eric patch

1. x86_setup_mtrr take address bit.
        2. generic ht, pcix, pcie beidge...
        3. scan bus and reset_bus
        4. ht read ctrl to decide if the ht chain
           is ready
        5. Intel e7520 and e7525 support
        6. new ich5r support
        7. intel sb 6300 support.

yhlu patch
	1. split x86_setup_mtrrs to fixed and var
	2. if (resource->flags & IORESOURCE_FIXED ) return; in device.c pick_largest_resource
	3. in_conherent.c K8_SCAN_PCI_BUS


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1982 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Yinghai Lu 2005-07-08 02:49:49 +00:00
parent 14cde9e96a
commit 13f1c2af8b
315 changed files with 30254 additions and 1952 deletions

View File

@ -576,6 +576,42 @@ define AUTOBOOT_CMDLINE
comment "Default command line when autobooting"
end
define USE_WATCHDOG_ON_BOOT
default 0
export always
comment "Use the watchdog on booting"
end
###############################################
# Plugin Device support options
###############################################
define CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT
default 1
export always
comment "Enable support for plugin Hypertransport busses"
end
define CONFIG_AGP_PLUGIN_SUPPORT
default 1
export always
comment "Enable support for plugin AGP busses"
end
define CONFIG_CARDBUS_PLUGIN_SUPPORT
default 1
export always
comment "Enable support cardbus plugin cards"
end
define CONFIG_PCIX_PLUGIN_SUPPORT
default 1
export always
comment "Enable support for plugin PCI-X busses"
end
define CONFIG_PCIEXP_PLUGIN_SUPPORT
default 1
export always
comment "Enable support for plugin PCI-E busses"
end
###############################################
# IRQ options
###############################################
@ -709,21 +745,6 @@ define HAVE_HARD_RESET
export used
comment "Have hard reset"
end
define HARD_RESET_BUS
default 1
export always
comment "Bus number of southbridge device doing reset"
end
define HARD_RESET_DEVICE
default 5
export always
comment "Device number of southbridge device doing reset"
end
define HARD_RESET_FUNCTION
default 0
export always
comment "Function number of southbridge device doing reset"
end
define MEMORY_HOLE
default none
export used

View File

@ -1,4 +1,5 @@
/* by yhlu 6.2005 */
/* be warned, this file will be used other cores and core0/node0 */
__asm__ volatile (
/*
FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.

View File

@ -192,6 +192,7 @@ static void init_ecc_memory(unsigned node_id)
/* If ecc support is not enabled don't touch memory */
dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
if (!(dcl & DCL_DimmEccEn)) {
printk_debug("ECC Disabled\n");
return;
}
@ -226,7 +227,9 @@ static void init_ecc_memory(unsigned node_id)
disable_lapic();
/* Walk through 2M chunks and zero them */
for(basek = begink; basek < endk; basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) {
for(basek = begink; basek < endk;
basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1)))
{
unsigned long limitk;
unsigned long size;
void *addr;
@ -255,12 +258,13 @@ static void init_ecc_memory(unsigned node_id)
}
size = (limitk - basek) << 10;
addr = map_2M_page(basek >> 11);
addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
if (addr == MAPPING_ERROR) {
printk_err("Cannot map page: %x\n", basek >> 11);
continue;
}
/* clear memory 2M (limitk - basek) */
addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
clear_memory(addr, size);
}
/* Restore the normal state */
@ -319,19 +323,16 @@ static inline void k8_errata(void)
}
wrmsr(NB_CFG_MSR, msr);
}
// AMD_D0_SUPPORT
/* Erratum 97 ... */
if (!is_cpu_pre_c0() && is_cpu_pre_d0()) {
/* D0 later don't need it */
/* Erratum 97 ... */
msr = rdmsr_amd(DC_CFG_MSR);
msr.lo |= 1 << 3;
wrmsr_amd(DC_CFG_MSR, msr);
}
//AMD_D0_SUPPORT
if(is_cpu_pre_d0()) {
/*D0 later don't need it */
/* Erratum 94 ... */
}
/* Erratum 94 ... */
if (is_cpu_pre_d0()) {
msr = rdmsr_amd(IC_CFG_MSR);
msr.lo |= 1 << 11;
wrmsr_amd(IC_CFG_MSR, msr);
@ -339,37 +340,51 @@ static inline void k8_errata(void)
/* Erratum 91 prefetch miss is handled in the kernel */
//AMD_D0_SUPPORT
/* Erratum 106 ... */
msr = rdmsr_amd(LS_CFG_MSR);
msr.lo |= 1 << 25;
wrmsr_amd(LS_CFG_MSR, msr);
/* Erratum 107 ... */
msr = rdmsr_amd(BU_CFG_MSR);
msr.hi |= 1 << (43 - 32);
wrmsr_amd(BU_CFG_MSR, msr);
if(is_cpu_d0()) {
/* Erratum 110 ...*/
msr = rdmsr_amd(CPU_ID_HYPER_EXT_FEATURES);
msr.hi |=1;
wrmsr_amd(CPU_ID_HYPER_EXT_FEATURES, msr);
}
}
//AMD_E0_SUPPORT
if(!is_cpu_pre_e0()) {
/* Erratum 110 ...*/
if (!is_cpu_pre_e0()) {
/* Erratum 110 ... */
msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
msr.hi |=1;
wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
}
/* Erratum 122 */
msr = rdmsr(HWCR_MSR);
msr.lo |= 1 << 6;
wrmsr(HWCR_MSR, msr);
}
void model_fxx_init(device_t dev)
{
unsigned long i;
msr_t msr;
#if CONFIG_LOGICAL_CPUS==1
#if CONFIG_LOGICAL_CPUS
struct node_core_id id;
unsigned siblings;
unsigned siblings;
id.coreid=0;
#else
unsigned nodeid;
#endif
/* Turn on caching if we haven't already */
x86_enable_cache();
x86_enable_cache();
amd_setup_mtrrs();
x86_mtrr_check();
@ -386,11 +401,12 @@ void model_fxx_init(device_t dev)
enable_cache();
#if CONFIG_LOGICAL_CPUS==1
//AMD_DUAL_CORE_SUPPORT
/* Enable the local cpu apics */
setup_lapic();
#if CONFIG_LOGICAL_CPUS == 1
siblings = cpuid_ecx(0x80000008) & 0xff;
// id = get_node_core_id((!is_cpu_pre_e0())? read_nb_cfg_54():0);
id = get_node_core_id(read_nb_cfg_54()); // pre e0 nb_cfg_54 can not be set
if(siblings>0) {
@ -407,24 +423,24 @@ void model_fxx_init(device_t dev)
wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
}
/* Is this a bad location? In particular can another node prefecth
* data from this node before we have initialized it?
*/
if(id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core0
if (id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core 0
#else
/* For now there is a 1-1 mapping between node_id and cpu_id */
nodeid = lapicid() & 0x7;
/* Is this a bad location? In particular can another node prefecth
* data from this node before we have initialized it?
*/
nodeid = lapicid() & 0xf;
init_ecc_memory(nodeid);
#endif
/* Enable the local cpu apics */
setup_lapic();
#if CONFIG_LOGICAL_CPUS==1
//AMD_DUAL_CORE_SUPPORT
/* Start up my cpu siblings */
// if(id.coreid==0) amd_sibling_init(dev); // Don't need core1 is already be put in the CPU BUS in bus_cpu_scan
#endif
}
static struct device_operations cpu_dev_ops = {

View File

@ -3,6 +3,7 @@
#define HWCR_MSR 0xC0010015
#define NB_CFG_MSR 0xC001001f
#define LS_CFG_MSR 0xC0011020
#define IC_CFG_MSR 0xC0011021
#define DC_CFG_MSR 0xC0011022
#define BU_CFG_MSR 0xC0011023

View File

@ -96,26 +96,32 @@ static void set_fixed_mtrr_resource(void *gp, struct device *dev, struct resourc
return;
}
printk_debug("Setting fixed MTRRs(%d-%d) Type: WB, RdMEM, WrMEM\n",
start_mtrr, last_mtrr);
start_mtrr, last_mtrr);
set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM);
}
extern void enable_fixed_mtrr(void);
void amd_setup_mtrrs(void)
{
unsigned long address_bits;
struct mem_state state;
unsigned long i;
msr_t msr;
/* Enable the access to AMD RdDram and WrDram extension bits */
disable_cache();
msr = rdmsr(SYSCFG_MSR);
msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
wrmsr(SYSCFG_MSR, msr);
enable_cache();
printk_debug("\n");
/* Initialized the fixed_mtrrs to uncached */
printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n",
0, NUM_FIXED_RANGES);
0, NUM_FIXED_RANGES);
set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE);
/* Except for the PCI MMIO hole just before 4GB there are no
@ -127,6 +133,7 @@ void amd_setup_mtrrs(void)
IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
set_fixed_mtrr_resource, &state);
printk_debug("DONE fixed MTRRs\n");
if (state.mmio_basek > state.tomk) {
state.mmio_basek = state.tomk;
}
@ -164,10 +171,17 @@ void amd_setup_mtrrs(void)
msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
wrmsr(SYSCFG_MSR, msr);
enable_fixed_mtrr();
enable_cache();
/* FIXME we should probably query the cpu for this
* but so far this is all any recent AMD cpu has supported.
*/
address_bits = 40;
/* Now that I have mapped what is memory and what is not
* Setup the mtrrs so we can cache the memory.
*/
x86_setup_mtrrs();
x86_setup_var_mtrrs(address_bits);
}

View File

@ -30,7 +30,7 @@ static void model_f0x_init(device_t dev)
{
/* Turn on caching if we haven't already */
x86_enable_cache();
x86_setup_mtrrs();
x86_setup_mtrrs(36);
x86_mtrr_check();
/* Update the microcode */

View File

@ -30,7 +30,7 @@ static void model_f1x_init(device_t dev)
{
/* Turn on caching if we haven't already */
x86_enable_cache();
x86_setup_mtrrs();
x86_setup_mtrrs(36);
x86_mtrr_check();
/* Update the microcode */

View File

@ -34,7 +34,7 @@ static void model_f2x_init(device_t cpu)
{
/* Turn on caching if we haven't already */
x86_enable_cache();
x86_setup_mtrrs();
x86_setup_mtrrs(36);
x86_mtrr_check();
/* Update the microcode */

View File

@ -31,7 +31,7 @@ static void model_f3x_init(device_t cpu)
{
/* Turn on caching if we haven't already */
x86_enable_cache();
x86_setup_mtrrs();
x86_setup_mtrrs(36);
x86_mtrr_check();
/* Update the microcode */

View File

@ -0,0 +1,12 @@
uses HAVE_MOVNTI
default HAVE_MOVNTI=1
dir /cpu/x86/tsc
dir /cpu/x86/mtrr
dir /cpu/x86/fpu
dir /cpu/x86/mmx
dir /cpu/x86/sse
dir /cpu/x86/lapic
dir /cpu/x86/cache
dir /cpu/intel/microcode
dir /cpu/intel/hyperthreading
driver model_f4x_init.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
#include <console/console.h>
#include <device/device.h>
#include <device/device.h>
#include <device/pci.h>
#include <string.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/hyperthreading.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/mtrr.h>
static uint32_t microcode_updates[] = {
/* WARNING - Intel has a new data structure that has variable length
* microcode update lengths. They are encoded in int 8 and 9. A
* dummy header of nulls must terminate the list.
*/
#include "microcode_MBDF410D.h"
/* Dummy terminator */
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
};
static void model_f4x_init(device_t cpu)
{
/* Turn on caching if we haven't already */
x86_enable_cache();
x86_setup_mtrrs(36);
x86_mtrr_check();
/* Update the microcode */
intel_update_microcode(microcode_updates);
/* Enable the local cpu apics */
setup_lapic();
/* Start up my cpu siblings */
intel_sibling_init(cpu);
};
static struct device_operations cpu_dev_ops = {
.init = model_f4x_init,
};
static struct cpu_device_id cpu_table[] = {
{ X86_VENDOR_INTEL, 0x0f41 }, /* Xeon */
{ 0, 0 },
};
static struct cpu_driver model_f4x __cpu_driver = {
.ops = &cpu_dev_ops,
.id_table = cpu_table,
};

View File

@ -1,3 +1,4 @@
config chip.h
object socket_mPGA604_800Mhz.o
dir /cpu/intel/model_f3x
dir /cpu/intel/model_f4x

View File

@ -37,8 +37,8 @@ static void disable_var_mtrr(unsigned reg)
wrmsr(MTRRphysMask_MSR(reg), zero);
}
static void set_var_mtrr(unsigned reg, unsigned base, unsigned size,
unsigned type)
static void set_var_mtrr(
unsigned reg, unsigned base, unsigned size, unsigned type)
{
/* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
@ -76,7 +76,7 @@ static void do_early_mtrr_init(const unsigned long *mtrr_msrs)
msr.lo = 0;
msr.hi = 0;
unsigned long msr_nr;
for (msr_addr = mtrr_msrs; (msr_nr = *msr_addr); msr_addr++) {
for(msr_addr = mtrr_msrs; (msr_nr = *msr_addr); msr_addr++) {
wrmsr(msr_nr, msr);
}

View File

@ -22,9 +22,14 @@
*
* Reference: Intel Architecture Software Developer's Manual, Volume 3: System Programming
*/
/*
2005.1 yhlu add NC support to spare mtrrs for 64G memory stored
2005.1 yhlu add NC support to spare mtrrs for 64G memory above installed
2005.6 Eric add address bit in x86_setup_mtrrs
2005.6 yhlu split x86_setup_var_mtrrs and x86_setup_fixed_mtrrs,
for AMD, it will not use x86_setup_fixed_mtrrs
*/
#include <stddef.h>
#include <console/console.h>
#include <device/device.h>
@ -32,19 +37,6 @@
#include <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#warning "FIXME I do not properly handle address more than 36 physical address bits"
//#define k8 0
#define k8 1
#if k8
# define ADDRESS_BITS 40
#else
# define ADDRESS_BITS 36
#endif
#define ADDRESS_BITS_HIGH (ADDRESS_BITS - 32)
#define ADDRESS_MASK_HIGH ((1u << ADDRESS_BITS_HIGH) - 1)
static unsigned int mtrr_msr[] = {
MTRRfix64K_00000_MSR, MTRRfix16K_80000_MSR, MTRRfix16K_A0000_MSR,
MTRRfix4K_C0000_MSR, MTRRfix4K_C8000_MSR, MTRRfix4K_D0000_MSR, MTRRfix4K_D8000_MSR,
@ -52,7 +44,7 @@ static unsigned int mtrr_msr[] = {
};
static void enable_fixed_mtrr(void)
void enable_fixed_mtrr(void)
{
msr_t msr;
@ -71,21 +63,26 @@ static void enable_var_mtrr(void)
}
/* setting variable mtrr, comes from linux kernel source */
static void set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
static void set_var_mtrr(
unsigned int reg, unsigned long basek, unsigned long sizek,
unsigned char type, unsigned address_bits)
{
msr_t base, mask;
unsigned address_mask_high;
address_mask_high = ((1u << (address_bits - 32u)) - 1u);
base.hi = basek >> 22;
base.lo = basek << 10;
//printk_debug("ADDRESS_MASK_HIGH=%#x\n", ADDRESS_MASK_HIGH);
printk_spew("ADDRESS_MASK_HIGH=%#x\n", address_mask_high);
if (sizek < 4*1024*1024) {
mask.hi = ADDRESS_MASK_HIGH;
mask.hi = address_mask_high;
mask.lo = ~((sizek << 10) -1);
}
else {
mask.hi = ADDRESS_MASK_HIGH & (~((sizek >> 22) -1));
mask.hi = address_mask_high & (~((sizek >> 22) -1));
mask.lo = 0;
}
@ -219,7 +216,7 @@ static unsigned fixed_mtrr_index(unsigned long addrk)
static unsigned int range_to_mtrr(unsigned int reg,
unsigned long range_startk, unsigned long range_sizek,
unsigned long next_range_startk, unsigned char type)
unsigned long next_range_startk, unsigned char type, unsigned address_bits)
{
if (!range_sizek || (reg >= BIOS_MTRRS)) {
return reg;
@ -235,11 +232,11 @@ static unsigned int range_to_mtrr(unsigned int reg,
}
sizek = 1 << align;
printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type %s\n",
reg, range_startk >>10, sizek >> 10,
(type==MTRR_TYPE_UNCACHEABLE) ? "NC" :
((type==MTRR_TYPE_WRBACK) ? "WB" : "Other")
reg, range_startk >>10, sizek >> 10,
(type==MTRR_TYPE_UNCACHEABLE)?"UC":
((type==MTRR_TYPE_WRBACK)?"WB":"Other")
);
set_var_mtrr(reg++, range_startk, sizek, type);
set_var_mtrr(reg++, range_startk, sizek, type, address_bits);
range_startk += sizek;
range_sizek -= sizek;
if (reg >= BIOS_MTRRS)
@ -279,6 +276,7 @@ struct var_mtrr_state {
unsigned long range_startk, range_sizek;
unsigned int reg;
unsigned long hole_startk, hole_sizek;
unsigned address_bits;
};
void set_var_mtrr_resource(void *gp, struct device *dev, struct resource *res)
@ -300,47 +298,68 @@ void set_var_mtrr_resource(void *gp, struct device *dev, struct resource *res)
}
/* Write the range mtrrs */
if (state->range_sizek != 0) {
if(state->hole_sizek == 0) {
// we need to put that on to hole.
unsigned long endk = basek + sizek;
if (state->hole_sizek == 0) {
/* We need to put that on to hole */
unsigned long endk = basek + sizek;
state->hole_startk = state->range_startk + state->range_sizek;
state->hole_sizek = basek - state->hole_startk;
state->range_sizek = endk - state->range_startk;
state->hole_sizek = basek - state->hole_startk;
state->range_sizek = endk - state->range_startk;
return;
}
state->reg = range_to_mtrr(state->reg, state->range_startk, state->range_sizek, basek, MTRR_TYPE_WRBACK);
state->reg = range_to_mtrr(state->reg, state->hole_startk, state->hole_sizek, basek, MTRR_TYPE_UNCACHEABLE);
state->reg = range_to_mtrr(state->reg, state->range_startk,
state->range_sizek, basek, MTRR_TYPE_WRBACK, state->address_bits);
state->reg = range_to_mtrr(state->reg, state->hole_startk,
state->hole_sizek, basek, MTRR_TYPE_UNCACHEABLE, state->address_bits);
state->range_startk = 0;
state->range_sizek = 0;
state->hole_startk = 0;
state->hole_sizek = 0;
}
/* Allocate an msr */
/* Allocate an msr */
printk_spew(" Allocate an msr - basek = %d, sizek = %d,\n", basek, sizek);
state->range_startk = basek;
state->range_sizek = sizek;
}
void x86_setup_mtrrs(void)
void x86_setup_fixed_mtrrs(void)
{
/* Try this the simple way of incrementally adding together
* mtrrs. If this doesn't work out we can get smart again
* and clear out the mtrrs.
*/
struct var_mtrr_state var_state;
printk_debug("\n");
/* Initialized the fixed_mtrrs to uncached */
printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n",
0, NUM_FIXED_RANGES);
set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE);
/* Now see which of the fixed mtrrs cover ram.
*/
search_global_resources(
IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
set_fixed_mtrr_resource, NULL);
printk_debug("DONE fixed MTRRs\n");
/* enable fixed MTRR */
printk_spew("call enable_fixed_mtrr()\n");
enable_fixed_mtrr();
}
void x86_setup_var_mtrrs(unsigned address_bits)
/* this routine needs to know how many address bits a given processor
* supports. CPUs get grumpy when you set too many bits in
* their mtrr registers :( I would generically call cpuid here
* and find out how many physically supported but some cpus are
* buggy, and report more bits then they actually support.
*/
{
/* Try this the simple way of incrementally adding together
* mtrrs. If this doesn't work out we can get smart again
* and clear out the mtrrs.
*/
struct var_mtrr_state var_state;
#if !k8
printk_debug("\n");
/* Initialized the fixed_mtrrs to uncached */
printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n",
0, NUM_FIXED_RANGES);
set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE);
/* Now see which of the fixed mtrrs cover ram.
*/
search_global_resources(
IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
set_fixed_mtrr_resource, NULL);
printk_debug("DONE fixed MTRRs\n");
#endif
/* Cache as many memory areas as possible */
/* FIXME is there an algorithm for computing the optimal set of mtrrs?
@ -351,28 +370,35 @@ void x86_setup_mtrrs(void)
var_state.hole_startk = 0;
var_state.hole_sizek = 0;
var_state.reg = 0;
var_state.address_bits = address_bits;
search_global_resources(
IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
set_var_mtrr_resource, &var_state);
/* Write the last range */
var_state.reg = range_to_mtrr(var_state.reg, var_state.range_startk, var_state.range_sizek, 0, MTRR_TYPE_WRBACK);
var_state.reg = range_to_mtrr(var_state.reg, var_state.hole_startk, var_state.hole_sizek, 0, MTRR_TYPE_UNCACHEABLE);
var_state.reg = range_to_mtrr(var_state.reg, var_state.range_startk,
var_state.range_sizek, 0, MTRR_TYPE_WRBACK, var_state.address_bits);
var_state.reg = range_to_mtrr(var_state.reg, var_state.hole_startk,
var_state.hole_sizek, 0, MTRR_TYPE_UNCACHEABLE, var_state.address_bits);
printk_debug("DONE variable MTRRs\n");
printk_debug("Clear out the extra MTRR's\n");
/* Clear out the extra MTRR's */
while(var_state.reg < MTRRS) {
set_var_mtrr(var_state.reg++, 0, 0, 0);
set_var_mtrr(var_state.reg++, 0, 0, 0, var_state.address_bits);
}
/* enable fixed MTRR */
printk_spew("call enable_fixed_mtrr()\n");
enable_fixed_mtrr();
printk_spew("call enable_var_mtrr()\n");
enable_var_mtrr();
printk_spew("Leave %s\n", __FUNCTION__);
post_code(0x6A);
}
void x86_setup_mtrrs(unsigned address_bits)
{
x86_setup_fixed_mtrrs();
x86_setup_var_mtrrs(address_bits);
}
int x86_mtrr_check(void)
{
/* Only Pentium Pro and later have MTRR */

View File

@ -3,8 +3,12 @@ object device.o
object root_device.o
object device_util.o
object pci_device.o
object pnp_device.o
object hypertransport.o
object pcix_device.o
object pciexp_device.o
object agp_device.o
object cardbus_device.o
object pnp_device.o
object pci_ops.o
object smbus_ops.o

54
src/devices/agp_device.c Normal file
View File

@ -0,0 +1,54 @@
/* (c) 2005 Linux Networx GPL see COPYING for details */
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/agp.h>
static void agp_tune_dev(device_t dev)
{
unsigned cap;
cap = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (!cap) {
return;
}
/* The OS is responsible for AGP tuning so do nothing here */
}
unsigned int agp_scan_bus(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max)
{
device_t child;
max = pci_scan_bus(bus, min_devfn, max_devfn, max);
for(child = bus->children; child; child = child->sibling) {
if ( (child->path.u.pci.devfn < min_devfn) ||
(child->path.u.pci.devfn > max_devfn))
{
continue;
}
agp_tune_dev(child);
}
return max;
}
unsigned int agp_scan_bridge(device_t dev, unsigned int max)
{
return do_pci_scan_bridge(dev, max, agp_scan_bus);
}
/** Default device operations for AGP bridges */
static struct pci_operations agp_bus_ops_pci = {
.set_subsystem = 0,
};
struct device_operations default_agp_ops_bus = {
.read_resources = pci_bus_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.init = 0,
.scan_bus = agp_scan_bridge,
.enable = 0,
.reset_bus = pci_bus_reset,
.ops_pci = &agp_bus_ops_pci,
};

View File

@ -58,7 +58,7 @@ device_t alloc_dev(struct bus *parent, struct device_path *path)
spin_lock(&dev_lock);
/* Find the last child of our parent */
for (child = parent->children; child && child->sibling; ) {
for(child = parent->children; child && child->sibling; ) {
child = child->sibling;
}
@ -70,7 +70,7 @@ device_t alloc_dev(struct bus *parent, struct device_path *path)
memcpy(&dev->path, path, sizeof(*path));
/* Initialize the back pointers in the link fields */
for (link = 0; link < MAX_LINKS; link++) {
for(link = 0; link < MAX_LINKS; link++) {
dev->link[link].dev = dev;
dev->link[link].link = link;
}
@ -119,10 +119,10 @@ static void read_resources(struct bus *bus)
struct device *curdev;
printk_spew("%s read_resources bus %d link: %d\n",
dev_path(bus->dev), bus->secondary, bus->link);
dev_path(bus->dev), bus->secondary, bus->link);
/* Walk through all of the devices and find which resources they need. */
for (curdev = bus->children; curdev; curdev = curdev->sibling) {
for(curdev = bus->children; curdev; curdev = curdev->sibling) {
unsigned links;
int i;
if (curdev->have_resources) {
@ -140,7 +140,7 @@ static void read_resources(struct bus *bus)
curdev->have_resources = 1;
/* Read in subtractive resources behind the current device */
links = 0;
for (i = 0; i < curdev->resources; i++) {
for(i = 0; i < curdev->resources; i++) {
struct resource *resource;
unsigned link;
resource = &curdev->resource[i];
@ -149,18 +149,17 @@ static void read_resources(struct bus *bus)
link = IOINDEX_SUBTRACTIVE_LINK(resource->index);
if (link > MAX_LINKS) {
printk_err("%s subtractive index on link: %d\n",
dev_path(curdev), link);
dev_path(curdev), link);
continue;
}
if (!(links & (1 << link))) {
links |= (1 << link);
read_resources(&curdev->link[resource->index]);
read_resources(&curdev->link[link]);
}
}
}
printk_spew("%s read_resources bus %d link: %d done\n",
dev_path(bus->dev), bus->secondary, bus->link);
dev_path(bus->dev), bus->secondary, bus->link);
}
struct pick_largest_state {
@ -181,6 +180,7 @@ static void pick_largest_resource(void *gp,
state->seen_last = 1;
return;
}
if (resource->flags & IORESOURCE_FIXED ) return; //skip it
if (last && (
(last->align < resource->align) ||
((last->align == resource->align) &&
@ -191,9 +191,10 @@ static void pick_largest_resource(void *gp,
return;
}
if (!state->result ||
(state->result->align < resource->align) ||
((state->result->align == resource->align) &&
(state->result->size < resource->size))) {
(state->result->align < resource->align) ||
((state->result->align == resource->align) &&
(state->result->size < resource->size)))
{
state->result_dev = dev;
state->result = resource;
}
@ -258,10 +259,10 @@ void compute_allocate_resource(
base = bridge->base;
printk_spew("%s compute_allocate_%s: base: %08Lx size: %08Lx align: %d gran: %d\n",
dev_path(bus->dev),
(bridge->flags & IORESOURCE_IO)? "io":
(bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
base, bridge->size, bridge->align, bridge->gran);
dev_path(bus->dev),
(bridge->flags & IORESOURCE_IO)? "io":
(bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
base, bridge->size, bridge->align, bridge->gran);
/* We want different minimum alignments for different kinds of
* resources. These minimums are not device type specific
@ -283,7 +284,7 @@ void compute_allocate_resource(
/* Walk through all the devices on the current bus and
* compute the addresses.
*/
while ((dev = largest_resource(bus, &resource, type_mask, type))) {
while((dev = largest_resource(bus, &resource, type_mask, type))) {
resource_t size;
/* Do NOT I repeat do not ignore resources which have zero size.
* If they need to be ignored dev->read_resources should not even
@ -301,9 +302,11 @@ void compute_allocate_resource(
if (align < min_align) {
align = min_align;
}
if (resource->flags & IORESOURCE_FIXED) {
continue;
}
/* Propogate the resource limit to the bridge register */
if (bridge->limit > resource->limit) {
bridge->limit = resource->limit;
@ -338,13 +341,14 @@ void compute_allocate_resource(
resource->flags &= ~IORESOURCE_STORED;
base += size;
printk_spew("%s %02x * [0x%08Lx - 0x%08Lx] %s\n",
dev_path(dev),
resource->index,
resource->base,
resource->base + resource->size - 1,
(resource->flags & IORESOURCE_IO)? "io":
(resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem");
printk_spew(
"%s %02x * [0x%08Lx - 0x%08Lx] %s\n",
dev_path(dev),
resource->index,
resource->base,
resource->base + resource->size - 1,
(resource->flags & IORESOURCE_IO)? "io":
(resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem");
}
}
/* A pci bridge resource does not need to be a power
@ -356,15 +360,16 @@ void compute_allocate_resource(
bridge->size = round(base, bridge->gran) - bridge->base;
printk_spew("%s compute_allocate_%s: base: %08Lx size: %08Lx align: %d gran: %d done\n",
dev_path(bus->dev),
(bridge->flags & IORESOURCE_IO)? "io":
(bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
base, bridge->size, bridge->align, bridge->gran);
dev_path(bus->dev),
(bridge->flags & IORESOURCE_IO)? "io":
(bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem",
base, bridge->size, bridge->align, bridge->gran);
}
#if CONFIG_CONSOLE_VGA == 1
device_t vga_pri = 0;
static void allocate_vga_resource(void)
{
@ -377,10 +382,11 @@ static void allocate_vga_resource(void)
bus = 0;
vga = 0;
vga_onboard = 0;
for (dev = all_devices; dev; dev = dev->next) {
for(dev = all_devices; dev; dev = dev->next) {
if (!dev->enabled) continue;
if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) {
((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER))
{
if (!vga) {
if (dev->on_mainboard) {
vga_onboard = dev;
@ -398,14 +404,15 @@ static void allocate_vga_resource(void)
}
if (vga) {
// vga is first add on card or the only onboard vga
/* vga is first add on card or the only onboard vga */
printk_debug("Allocating VGA resource %s\n", dev_path(vga));
/* All legacy VGA cards have MEM & I/O space registers */
vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
vga_pri = vga;
bus = vga->bus;
}
/* Now walk up the bridges setting the VGA enable */
while (bus) {
while(bus) {
printk_debug("Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
dev_path(bus->dev));
bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA;
@ -435,7 +442,7 @@ void assign_resources(struct bus *bus)
printk_spew("%s assign_resources, bus %d link: %d\n",
dev_path(bus->dev), bus->secondary, bus->link);
for (curdev = bus->children; curdev; curdev = curdev->sibling) {
for(curdev = bus->children; curdev; curdev = curdev->sibling) {
if (!curdev->enabled || !curdev->resources) {
continue;
}
@ -480,6 +487,70 @@ void enable_resources(struct device *dev)
dev->ops->enable_resources(dev);
}
/**
* @brief Reset all of the devices a bus
*
* Reset all of the devices on a bus and clear the bus's reset_needed flag.
*
* @param bus pointer to the bus structure
*
* @return 1 if the bus was successfully reset, 0 otherwise.
*
*/
int reset_bus(struct bus *bus)
{
device_t dev;
if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus)
{
bus->dev->ops->reset_bus(bus);
bus->reset_needed = 0;
return 1;
}
return 0;
}
/**
* @brief Scan for devices on a bus.
*
* If there are bridges on the bus, recursively scan the buses behind the bridges.
* If the setting up and tuning of the bus causes a reset to be required,
* reset the bus and scan it again.
*
* @param bus pointer to the bus device
* @param max current bus number
*
* @return The maximum bus number found, after scanning all subordinate busses
*/
unsigned int scan_bus(device_t bus, unsigned int max)
{
unsigned int new_max;
int do_scan_bus;
if ( !bus ||
!bus->enabled ||
!bus->ops ||
!bus->ops->scan_bus)
{
return max;
}
do_scan_bus = 1;
while(do_scan_bus) {
int link;
new_max = bus->ops->scan_bus(bus, max);
do_scan_bus = 0;
for(link = 0; link < bus->links; link++) {
if (bus->link[link].reset_needed) {
if (reset_bus(&bus->link[link])) {
do_scan_bus = 1;
} else {
bus->bus->reset_needed = 1;
}
}
}
}
return new_max;
}
/**
* @brief Determine the existence of devices and extend the device tree.
*
@ -515,7 +586,7 @@ void dev_enumerate(void)
printk_err("dev_root missing scan_bus operation");
return;
}
subordinate = root->ops->scan_bus(root, 0);
subordinate = scan_bus(root, 0);
printk_info("done\n");
}
@ -613,18 +684,19 @@ void dev_initialize(void)
struct device *dev;
printk_info("Initializing devices...\n");
for (dev = all_devices; dev; dev = dev->next) {
if (dev->enabled && !dev->initialized &&
dev->ops && dev->ops->init)
{
if(dev->path.type == DEVICE_PATH_I2C)
printk_debug("smbus: %s[%d]->", dev_path(dev->bus->dev), dev->bus->link );
printk_debug("%s init\n", dev_path(dev));
dev->initialized = 1;
dev->ops->init(dev);
}
}
for(dev = all_devices; dev; dev = dev->next) {
if (dev->enabled && !dev->initialized &&
dev->ops && dev->ops->init)
{
if (dev->path.type == DEVICE_PATH_I2C) {
printk_debug("smbus: %s[%d]->",
dev_path(dev->bus->dev), dev->bus->link);
}
printk_debug("%s init\n", dev_path(dev));
dev->initialized = 1;
dev->ops->init(dev);
}
}
printk_info("Devices initialized\n");
}

View File

@ -16,7 +16,7 @@
device_t find_dev_path(struct bus *parent, struct device_path *path)
{
device_t child;
for (child = parent->children; child; child = child->sibling) {
for(child = parent->children; child; child = child->sibling) {
if (path_eq(path, &child->path)) {
break;
}
@ -178,6 +178,14 @@ const char *dev_path(device_t dev)
return buffer;
}
const char *bus_path(struct bus *bus)
{
static char buffer[BUS_PATH_MAX];
sprintf(buffer, "%s,%d",
dev_path(bus->dev), bus->link);
return buffer;
}
int path_eq(struct device_path *path1, struct device_path *path2)
{
int equal = 0;
@ -389,13 +397,31 @@ resource_t resource_max(struct resource *resource)
return max;
}
/**
* @brief return the resource type of a resource
* @param resource the resource type to decode.
*/
const char *resource_type(struct resource *resource)
{
static char buffer[RESOURCE_TYPE_MAX];
sprintf(buffer, "%s%s%s%s",
((resource->flags & IORESOURCE_READONLY)? "ro": ""),
((resource->flags & IORESOURCE_PREFETCH)? "pref":""),
((resource->flags == 0)? "unused":
(resource->flags & IORESOURCE_IO)? "io":
(resource->flags & IORESOURCE_DRQ)? "drq":
(resource->flags & IORESOURCE_IRQ)? "irq":
(resource->flags & IORESOURCE_MEM)? "mem":"??????"),
((resource->flags & IORESOURCE_PCI64)?"64":""));
return buffer;
}
/**
* @brief print the resource that was just stored.
* @param dev the device the stored resorce lives on
* @param resource the resource that was just stored.
*/
void report_resource_stored(device_t dev, struct resource *resource,
const char *comment)
void report_resource_stored(device_t dev, struct resource *resource, const char *comment)
{
if (resource->flags & IORESOURCE_STORED) {
unsigned char buf[10];
@ -407,18 +433,12 @@ void report_resource_stored(device_t dev, struct resource *resource,
sprintf(buf, "bus %d ", dev->link[0].secondary);
}
printk_debug(
"%s %02x <- [0x%010Lx - 0x%010Lx] %s%s%s%s\n",
"%s %02x <- [0x%010Lx - 0x%010Lx] %s%s%s\n",
dev_path(dev),
resource->index,
base, end,
buf,
(resource->flags & IORESOURCE_PREFETCH) ? "pref" : "",
(resource->flags & IORESOURCE_IO)? "io":
(resource->flags & IORESOURCE_DRQ)? "drq":
(resource->flags & IORESOURCE_IRQ)? "irq":
(resource->flags & IORESOURCE_READONLY)? "rom":
(resource->flags & IORESOURCE_MEM)? "mem":
"????",
resource_type(resource),
comment);
}
}
@ -473,3 +493,29 @@ void search_global_resources(
}
}
}
void dev_set_enabled(device_t dev, int enable)
{
if (dev->enabled == enable) {
return;
}
dev->enabled = enable;
if (dev->ops && dev->ops->enable) {
dev->ops->enable(dev);
}
else if (dev->chip_ops && dev->chip_ops->enable_dev) {
dev->chip_ops->enable_dev(dev);
}
}
void disable_children(struct bus *bus)
{
device_t child;
for(child = bus->children; child; child = child->sibling) {
int link;
for(link = 0; link < child->links; link++) {
disable_children(&child->link[link]);
}
dev_set_enabled(child, 0);
}
}

View File

@ -9,7 +9,7 @@
#include <part/fallback_boot.h>
#define OPT_HT_LINK 0
#if OPT_HT_LINK == 1
#include "../northbridge/amd/amdk8/cpu_rev.c"
#endif
@ -19,17 +19,37 @@ static device_t ht_scan_get_devs(device_t *old_devices)
device_t first, last;
first = *old_devices;
last = first;
/* Extract the chain of devices to (first through last)
* for the next hypertransport device.
*/
while(last && last->sibling &&
(last->sibling->path.type == DEVICE_PATH_PCI) &&
(last->sibling->path.u.pci.devfn > last->path.u.pci.devfn)) {
(last->sibling->path.u.pci.devfn > last->path.u.pci.devfn))
{
last = last->sibling;
}
if (first) {
device_t child;
/* Unlink the chain from the list of old devices */
*old_devices = last->sibling;
last->sibling = 0;
/* Now add the device to the list of devices on the bus.
*/
/* Find the last child of our parent */
for(child = first->bus->children; child && child->sibling; ) {
child = child->sibling;
}
/* Place the chain on the list of children of their parent. */
if (child) {
child->sibling = first;
} else {
first->bus->children = first;
}
}
return first;
}
#if OPT_HT_LINK == 1
static unsigned ht_read_freq_cap(device_t dev, unsigned pos)
{
@ -43,30 +63,37 @@ static unsigned ht_read_freq_cap(device_t dev, unsigned pos)
if ((dev->vendor == PCI_VENDOR_ID_AMD) &&
(dev->device == PCI_DEVICE_ID_AMD_8131_PCIX)) {
freq_cap &= ~(1 << HT_FREQ_800Mhz);
} else
}
/* AMD 8151 Errata 23 */
if ((dev->vendor == PCI_VENDOR_ID_AMD) &&
(dev->device == PCI_DEVICE_ID_AMD_8151_SYSCTRL)) {
freq_cap &= ~(1 << HT_FREQ_800Mhz);
} else
}
/* AMD K8 Unsupported 1Ghz? */
if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == 0x1100)) {
#if K8_HT_FREQ_1G_SUPPORT == 1
if (is_cpu_pre_e0())
#endif
{
freq_cap &= ~(1 << HT_FREQ_1000Mhz);
}
}
return freq_cap;
}
#endif
struct prev_link {
struct ht_link {
struct device *dev;
unsigned pos;
unsigned char config_off, freq_off, freq_cap_off;
unsigned char ctrl_off, config_off, freq_off, freq_cap_off;
};
static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos)
static int ht_setup_link(struct ht_link *prev, device_t dev, unsigned pos)
{
static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
struct ht_link cur[1];
unsigned present_width_cap, upstream_width_cap;
unsigned present_freq_cap, upstream_freq_cap;
unsigned ln_present_width_in, ln_upstream_width_in;
@ -78,13 +105,30 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos)
/* Set the hypertransport link width and frequency */
reset_needed = 0;
linkb_to_host = (pci_read_config16(dev, pos + PCI_CAP_FLAGS) >> 10) & 1;
/* See which side of the device our previous write to
* set the unitid came from.
*/
cur->dev = dev;
cur->pos = pos;
linkb_to_host = (pci_read_config16(cur->dev, cur->pos + PCI_CAP_FLAGS) >> 10) & 1;
if (!linkb_to_host) {
cur->ctrl_off = PCI_HT_CAP_SLAVE_CTRL0;
cur->config_off = PCI_HT_CAP_SLAVE_WIDTH0;
cur->freq_off = PCI_HT_CAP_SLAVE_FREQ0;
cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
}
else {
cur->ctrl_off = PCI_HT_CAP_SLAVE_CTRL1;
cur->config_off = PCI_HT_CAP_SLAVE_WIDTH1;
cur->freq_off = PCI_HT_CAP_SLAVE_FREQ1;
cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
}
#if OPT_HT_LINK == 1
/* Read the capabilities */
present_freq_cap = ht_read_freq_cap(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ_CAP1: PCI_HT_CAP_SLAVE_FREQ_CAP0));
present_freq_cap = ht_read_freq_cap(cur->dev, cur->pos + cur->freq_cap_off);
upstream_freq_cap = ht_read_freq_cap(prev->dev, prev->pos + prev->freq_cap_off);
present_width_cap = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0));
upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off);
present_width_cap = pci_read_config8(cur->dev, cur->pos + cur->config_off);
upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off);
/* Calculate the highest useable frequency */
freq = log2(present_freq_cap & upstream_freq_cap);
@ -107,87 +151,130 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos)
present_width |= pow2_to_link_width[ln_upstream_width_out];
/* Set the current device */
old_freq = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0));
old_freq = pci_read_config8(cur->dev, cur->pos + cur->freq_off);
old_freq &= 0x0f;
if (freq != old_freq) {
pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0), freq);
unsigned new_freq;
pci_write_config8(cur->dev, cur->pos + cur->freq_off, freq);
reset_needed = 1;
printk_spew("HyperT FreqP old %x new %x\n",old_freq,freq);
new_freq = pci_read_config8(cur->dev, cur->pos + cur->freq_off);
new_freq &= 0x0f;
if (new_freq != freq) {
printk_err("%s Hypertransport frequency would not set wanted: %x got: %x\n",
dev_path(dev), freq, new_freq);
}
}
old_width = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1);
old_width = pci_read_config8(cur->dev, cur->pos + cur->config_off + 1);
if (present_width != old_width) {
pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1, present_width);
unsigned new_width;
pci_write_config8(cur->dev, cur->pos + cur->config_off + 1,
present_width);
reset_needed = 1;
printk_spew("HyperT widthP old %x new %x\n",old_width, present_width);
new_width = pci_read_config8(cur->dev, cur->pos + cur->config_off + 1);
if (new_width != present_width) {
printk_err("%s Hypertransport width would not set wanted: %x got: %x\n",
dev_path(dev), present_width, new_width);
}
}
/* Set the upstream device */
old_freq = pci_read_config8(prev->dev, prev->pos + prev->freq_off);
old_freq &= 0x0f;
if (freq != old_freq) {
unsigned new_freq;
pci_write_config8(prev->dev, prev->pos + prev->freq_off, freq);
reset_needed = 1;
printk_spew("HyperT freqU old %x new %x\n", old_freq, freq);
new_freq = pci_read_config8(prev->dev, prev->pos + prev->freq_off);
new_freq &= 0x0f;
if (new_freq != freq) {
printk_err("%s Hypertransport frequency would not set wanted: %x got: %x\n",
dev_path(prev->dev), freq, new_freq);
}
}
old_width = pci_read_config8(prev->dev, prev->pos + prev->config_off + 1);
if (upstream_width != old_width) {
unsigned new_width;
pci_write_config8(prev->dev, prev->pos + prev->config_off + 1, upstream_width);
reset_needed = 1;
printk_spew("HyperT widthU old %x new %x\n", old_width, upstream_width);
new_width = pci_read_config8(prev->dev, prev->pos + prev->config_off + 1);
if (new_width != upstream_width) {
printk_err("%s Hypertransport width would not set wanted: %x got: %x\n",
dev_path(prev->dev), upstream_width, new_width);
}
}
#endif
/* Remember the current link as the previous link */
prev->dev = dev;
prev->pos = pos;
if(linkb_to_host) {
prev->config_off = PCI_HT_CAP_SLAVE_WIDTH0;
prev->freq_off = PCI_HT_CAP_SLAVE_FREQ0;
prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
}
else {
prev->config_off = PCI_HT_CAP_SLAVE_WIDTH1;
prev->freq_off = PCI_HT_CAP_SLAVE_FREQ1;
prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
}
/* Remember the current link as the previous link,
* But look at the other offsets.
*/
prev->dev = cur->dev;
prev->pos = cur->pos;
if (cur->ctrl_off == PCI_HT_CAP_SLAVE_CTRL0) {
prev->ctrl_off = PCI_HT_CAP_SLAVE_CTRL1;
prev->config_off = PCI_HT_CAP_SLAVE_WIDTH1;
prev->freq_off = PCI_HT_CAP_SLAVE_FREQ1;
prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
} else {
prev->ctrl_off = PCI_HT_CAP_SLAVE_CTRL0;
prev->config_off = PCI_HT_CAP_SLAVE_WIDTH0;
prev->freq_off = PCI_HT_CAP_SLAVE_FREQ0;
prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
}
return reset_needed;
}
#endif
static unsigned ht_lookup_slave_capability(struct device *dev)
{
unsigned pos;
pos = 0;
switch(dev->hdr_type & 0x7f) {
case PCI_HEADER_TYPE_NORMAL:
case PCI_HEADER_TYPE_BRIDGE:
pos = PCI_CAPABILITY_LIST;
break;
}
if (pos > PCI_CAP_LIST_NEXT) {
pos = pci_read_config8(dev, pos);
}
while(pos != 0) { /* loop through the linked list */
uint8_t cap;
cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos);
if (cap == PCI_CAP_ID_HT) {
do {
pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos);
if (pos) {
unsigned flags;
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
printk_spew("flags: 0x%04x\n", (unsigned)flags);
printk_spew("flags: 0x%04x\n", flags);
if ((flags >> 13) == 0) {
/* Entry is a Slave secondary, success...*/
/* Entry is a Slave secondary, success... */
break;
}
}
pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
}
} while(pos);
return pos;
}
static void ht_collapse_early_enumeration(struct bus *bus)
{
unsigned int devfn;
struct ht_link prev;
unsigned ctrl;
/* Initialize the hypertransport enumeration state */
prev.dev = bus->dev;
prev.pos = bus->cap;
prev.ctrl_off = PCI_HT_CAP_HOST_CTRL;
prev.config_off = PCI_HT_CAP_HOST_WIDTH;
prev.freq_off = PCI_HT_CAP_HOST_FREQ;
prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;
/* Wait until the link initialization is complete */
do {
ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off);
/* Is this the end of the hypertransport chain */
if (ctrl & (1 << 6)) {
return;
}
/* Has the link failed? */
if (ctrl & (1 << 4)) {
return;
}
} while((ctrl & (1 << 5)) == 0);
/* Spin through the devices and collapse any early
* hypertransport enumeration.
@ -200,21 +287,10 @@ static void ht_collapse_early_enumeration(struct bus *bus)
dummy.path.type = DEVICE_PATH_PCI;
dummy.path.u.pci.devfn = devfn;
id = pci_read_config32(&dummy, PCI_VENDOR_ID);
if (id == 0xffffffff || id == 0x00000000 ||
id == 0x0000ffff || id == 0xffff0000) {
if ( (id == 0xffffffff) || (id == 0x00000000) ||
(id == 0x0000ffff) || (id == 0xffff0000)) {
continue;
}
#if 0
#if CK804_DEVN_BASE==0
//CK804 workaround:
// CK804 UnitID changes not use
if(id == 0x005e10de) {
break;
}
#endif
#endif
dummy.vendor = id & 0xffff;
dummy.device = (id >> 16) & 0xffff;
dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE);
@ -232,15 +308,13 @@ static void ht_collapse_early_enumeration(struct bus *bus)
}
}
unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
unsigned int hypertransport_scan_chain(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max)
{
unsigned next_unitid, last_unitid, previous_unitid;
device_t old_devices, dev, func, *chain_last;
unsigned next_unitid, last_unitid;
device_t old_devices, dev, func;
unsigned min_unitid = 1;
#if OPT_HT_LINK == 1
int reset_needed;
struct prev_link prev;
#endif
struct ht_link prev;
/* Restore the hypertransport chain to it's unitialized state */
ht_collapse_early_enumeration(bus);
@ -248,71 +322,48 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
/* See which static device nodes I have */
old_devices = bus->children;
bus->children = 0;
chain_last = &bus->children;
/* Initialize the hypertransport enumeration state */
#if OPT_HT_LINK == 1
reset_needed = 0;
prev.dev = bus->dev;
prev.pos = bus->cap;
prev.ctrl_off = PCI_HT_CAP_HOST_CTRL;
prev.config_off = PCI_HT_CAP_HOST_WIDTH;
prev.freq_off = PCI_HT_CAP_HOST_FREQ;
prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;
#endif
/* If present assign unitid to a hypertransport chain */
last_unitid = min_unitid -1;
next_unitid = min_unitid;
do {
uint32_t id, class;
uint8_t hdr_type;
unsigned pos;
uint8_t pos;
uint16_t flags;
unsigned count, static_count;
unsigned ctrl;
previous_unitid = last_unitid;
last_unitid = next_unitid;
/* Get setup the device_structure */
/* Wait until the link initialization is complete */
do {
ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off);
/* Is this the end of the hypertransport chain?
* Has the link failed?
* If so further scanning is pointless.
*/
if (ctrl & ((1 << 6) | (1 << 4))) {
goto end_of_chain;
}
} while((ctrl & (1 << 5)) == 0);
/* Get and setup the device_structure */
dev = ht_scan_get_devs(&old_devices);
if (!dev) {
struct device dummy;
dummy.bus = bus;
dummy.path.type = DEVICE_PATH_PCI;
dummy.path.u.pci.devfn = 0;
id = pci_read_config32(&dummy, PCI_VENDOR_ID);
/* If the chain is fully enumerated quit */
if (id == 0xffffffff || id == 0x00000000 ||
id == 0x0000ffff || id == 0xffff0000) {
break;
}
dev = alloc_dev(bus, &dummy.path);
}
else {
/* Add this device to the pci bus chain */
*chain_last = dev;
/* Run the magice enable sequence for the device */
if (dev->chip_ops && dev->chip_ops->enable_dev) {
dev->chip_ops->enable_dev(dev);
}
/* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID);
/* If the chain is fully enumerated quit */
if (id == 0xffffffff || id == 0x00000000 ||
id == 0x0000ffff || id == 0xffff0000) {
if (dev->enabled) {
printk_info("Disabling static device: %s\n",
dev_path(dev));
dev->enabled = 0;
}
break;
}
}
/* Update the device chain tail */
for(func = dev; func; func = func->sibling) {
chain_last = &func->sibling;
/* See if a device is present and setup the
* device structure.
*/
dev = pci_probe_dev(dev, bus, 0);
if (!dev || !dev->enabled) {
break;
}
/* Find the hypertransport link capability */
@ -323,20 +374,29 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
break;
}
/* Update the Unitid of the current device */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
/* If the devices has a unitid set and is at devfn 0 we are done.
* This can happen with shadow hypertransport devices,
* or if we have reached the bottom of a
* hypertransport device chain.
*/
if (flags & 0x1f) {
break;
}
flags &= ~0x1f; /* mask out base Unit ID */
#if CK804_DEVN_BASE==0
if(id == 0x005e10de) {
next_unitid = 0;
}
else {
if((dev->vendor == 0x10de) && (dev->device == 0x005e)) {
next_unitid = 0;
}
else {
#endif
flags |= next_unitid & 0x1f;
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
flags |= next_unitid & 0x1f;
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
#if CK804_DEVN_BASE==0
}
}
#endif
/* Update the Unitd id in the device structure */
@ -347,17 +407,6 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
- (dev->path.u.pci.devfn >> 3) + 1;
}
/* Read the rest of the pci configuration information */
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
class = pci_read_config32(dev, PCI_CLASS_REVISION);
/* Store the interesting information in the device structure */
dev->vendor = id & 0xffff;
dev->device = (id >> 16) & 0xffff;
dev->hdr_type = hdr_type;
/* class code, the upper 3 bytes of PCI_CLASS_REVISION */
dev->class = class >> 8;
/* Compute the number of unitids consumed */
count = (flags >> 5) & 0x1f; /* get unit count */
printk_spew("%s count: %04x static_count: %04x\n",
@ -369,36 +418,83 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
/* Update the Unitid of the next device */
next_unitid += count;
#if OPT_HT_LINK == 1
/* Setup the hypetransport link */
reset_needed |= ht_setup_link(&prev, dev, pos);
#endif
bus->reset_needed |= ht_setup_link(&prev, dev, pos);
printk_debug("%s [%04x/%04x] %s next_unitid: %04x\n",
dev_path(dev),
dev->vendor, dev->device,
(dev->enabled? "enabled": "disabled"), next_unitid);
#if CK804_DEVN_BASE==0
if(id == 0x005e10de) {
break; // CK804 can not change unitid, so it only can be alone in the link
}
if ((dev->vendor == 0x10de) && (dev->device == 0x005e)) {
break; // CK804 can not change unitid, so it only can be alone in the link
}
#endif
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
} while((last_unitid != next_unitid) && (next_unitid <= (max_devfn >> 3)));
end_of_chain:
#if OPT_HT_LINK == 1
#if HAVE_HARD_RESET == 1
if(reset_needed) {
if(bus->reset_needed) {
printk_info("HyperT reset needed\n");
hard_reset();
}
else {
printk_debug("HyperT reset not needed\n");
}
#endif
#endif
if (next_unitid > 0x1f) {
next_unitid = 0x1f;
}
return pci_scan_bus(bus, 0x00, (next_unitid << 3)|7, max);
/* Die if any leftover Static devices are are found.
* There's probably a problem in the Config.lb.
*/
if(old_devices) {
device_t left;
for(left = old_devices; left; left = left->sibling) {
printk_debug("%s\n", dev_path(left));
}
die("Left over static devices. Check your Config.lb\n");
}
/* Now that nothing is overlapping it is safe to scan the
* children.
*/
max = pci_scan_bus(bus, 0x00, (next_unitid << 3)|7, max);
return max;
}
/**
* @brief Scan a PCI bridge and the buses behind the bridge.
*
* Determine the existence of buses behind the bridge. Set up the bridge
* according to the result of the scan.
*
* This function is the default scan_bus() method for PCI bridge devices.
*
* @param dev pointer to the bridge device
* @param max the highest bus number assgined up to now
*
* @return The maximum bus number found, after scanning all subordinate busses
*/
unsigned int ht_scan_bridge(struct device *dev, unsigned int max)
{
return do_pci_scan_bridge(dev, max, hypertransport_scan_chain);
}
/** Default device operations for hypertransport bridges */
static struct pci_operations ht_bus_ops_pci = {
.set_subsystem = 0,
};
struct device_operations default_ht_ops_bus = {
.read_resources = pci_bus_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.init = 0,
.scan_bus = ht_scan_bridge,
.enable = 0,
.reset_bus = pci_bus_reset,
.ops_pci = &ht_bus_ops_pci,
};

View File

@ -21,8 +21,23 @@
#include <part/hard_reset.h>
#include <part/fallback_boot.h>
#include <delay.h>
#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
#include <device/hypertransport.h>
#endif
#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
#include <device/pcix.h>
#endif
#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
#include <device/pciexp.h>
#endif
#if CONFGI_AGP_PLUGIN_SUPPORT == 1
#include <device/agp.h>
#endif
#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
#include <device/cardbus.h>
#endif
static uint8_t pci_moving_config8(struct device *dev, unsigned reg)
uint8_t pci_moving_config8(struct device *dev, unsigned reg)
{
uint8_t value, ones, zeroes;
value = pci_read_config8(dev, reg);
@ -38,7 +53,7 @@ static uint8_t pci_moving_config8(struct device *dev, unsigned reg)
return ones ^ zeroes;
}
static uint16_t pci_moving_config16(struct device *dev, unsigned reg)
uint16_t pci_moving_config16(struct device *dev, unsigned reg)
{
uint16_t value, ones, zeroes;
value = pci_read_config16(dev, reg);
@ -54,7 +69,7 @@ static uint16_t pci_moving_config16(struct device *dev, unsigned reg)
return ones ^ zeroes;
}
static uint32_t pci_moving_config32(struct device *dev, unsigned reg)
uint32_t pci_moving_config32(struct device *dev, unsigned reg)
{
uint32_t value, ones, zeroes;
value = pci_read_config32(dev, reg);
@ -70,29 +85,53 @@ static uint32_t pci_moving_config32(struct device *dev, unsigned reg)
return ones ^ zeroes;
}
unsigned pci_find_capability(device_t dev, unsigned cap)
unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last)
{
unsigned pos;
unsigned status;
unsigned reps = 48;
pos = 0;
status = pci_read_config16(dev, PCI_STATUS);
if (!(status & PCI_STATUS_CAP_LIST)) {
return 0;
}
switch(dev->hdr_type & 0x7f) {
case PCI_HEADER_TYPE_NORMAL:
case PCI_HEADER_TYPE_BRIDGE:
pos = PCI_CAPABILITY_LIST;
break;
case PCI_HEADER_TYPE_CARDBUS:
pos = PCI_CB_CAPABILITY_LIST;
break;
default:
return 0;
}
if (pos > PCI_CAP_LIST_NEXT) {
pos = pci_read_config8(dev, pos);
}
while (pos != 0) { /* loop through the linked list */
pos = pci_read_config8(dev, pos);
while(reps-- && (pos >= 0x40)) { /* loop through the linked list */
int this_cap;
pos &= ~3;
this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
if (this_cap == cap) {
printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos);
if (this_cap == 0xff) {
break;
}
if (!last && (this_cap == cap)) {
return pos;
}
if (last == pos) {
last = 0;
}
pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
}
return 0;
}
unsigned pci_find_capability(device_t dev, unsigned cap)
{
return pci_find_next_capability(dev, cap, 0);
}
/** Given a device and register, read the size of the BAR for that register.
* @param dev Pointer to the device structure
* @param resource Pointer to the resource structure
@ -118,7 +157,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
/* If it is a 64bit resource look at the high half as well */
if (((attr & PCI_BASE_ADDRESS_SPACE_IO) == 0) &&
((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
{
/* Find the high bits that move */
moving |= ((resource_t)pci_moving_config32(dev, index + 4)) << 32;
@ -134,7 +173,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
if (moving) {
resource->size = 1;
resource->align = resource->gran = 0;
while (!(moving & resource->size)) {
while(!(moving & resource->size)) {
resource->size <<= 1;
resource->align += 1;
resource->gran += 1;
@ -154,17 +193,20 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
*/
if (moving == 0) {
if (value != 0) {
printk_debug("%s register %02x(%08x), read-only ignoring it\n",
dev_path(dev), index, value);
printk_debug(
"%s register %02x(%08x), read-only ignoring it\n",
dev_path(dev), index, value);
}
resource->flags = 0;
} else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
}
else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
/* An I/O mapped base address */
attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK;
resource->flags |= IORESOURCE_IO;
/* I don't want to deal with 32bit I/O resources */
resource->limit = 0xffff;
} else {
}
else {
/* A Memory mapped base address */
attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK;
resource->flags |= IORESOURCE_MEM;
@ -175,14 +217,17 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) {
/* 32bit limit */
resource->limit = 0xffffffffUL;
} else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
}
else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
/* 1MB limit */
resource->limit = 0x000fffffUL;
} else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
}
else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
/* 64bit limit */
resource->limit = 0xffffffffffffffffULL;
resource->flags |= IORESOURCE_PCI64;
} else {
}
else {
/* Invalid value */
resource->flags = 0;
}
@ -194,18 +239,15 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
#if 0
if (resource->flags) {
printk_debug("%s %02x ->",
dev_path(dev), resource->index);
dev_path(dev), resource->index);
printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
value, zeroes, ones, attr);
value, zeroes, ones, attr);
printk_debug(
"%s %02x -> size: 0x%08Lx max: 0x%08Lx %s%s\n ",
"%s %02x -> size: 0x%08Lx max: 0x%08Lx %s\n ",
dev_path(dev),
resource->index,
resource->size, resource->limit,
(resource->flags == 0) ? "unused":
(resource->flags & IORESOURCE_IO)? "io":
(resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem",
(resource->flags & IORESOURCE_PCI64)?"64":"");
resource_type(resource));
}
#endif
@ -272,32 +314,32 @@ static void pci_get_rom_resource(struct device *dev, unsigned long index)
resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY |
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}
compact_resources(dev);
}
/** Read the base address registers for a given device.
* @param dev Pointer to the dev structure
* @param howmany How many registers to read (6 for device, 2 for bridge)
*/
static void pci_read_bases(struct device *dev, unsigned int howmany, unsigned long rom)
static void pci_read_bases(struct device *dev, unsigned int howmany)
{
unsigned long index;
for (index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
struct resource *resource;
resource = pci_get_resource(dev, index);
index += (resource->flags & IORESOURCE_PCI64)?8:4;
}
if (rom)
pci_get_rom_resource(dev, rom);
compact_resources(dev);
}
static void pci_set_resource(struct device *dev, struct resource *resource);
static void pci_record_bridge_resource( struct device *dev, resource_t moving,
unsigned index, unsigned long mask,
unsigned long type)
static void pci_record_bridge_resource(
struct device *dev, resource_t moving,
unsigned index, unsigned long mask, unsigned long type)
{
/* Initiliaze the constraints on the current bus */
struct resource *resource;
@ -346,8 +388,10 @@ static void pci_bridge_read_bases(struct device *dev)
moving = moving_base & moving_limit;
/* Initialize the io space constraints on the current bus */
pci_record_bridge_resource(dev, moving, PCI_IO_BASE,
IORESOURCE_IO, IORESOURCE_IO);
pci_record_bridge_resource(
dev, moving, PCI_IO_BASE,
IORESOURCE_IO, IORESOURCE_IO);
/* See if the bridge prefmem resources are implemented */
moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
@ -358,9 +402,11 @@ static void pci_bridge_read_bases(struct device *dev)
moving = moving_base & moving_limit;
/* Initiliaze the prefetchable memory constraints on the current bus */
pci_record_bridge_resource(dev, moving, PCI_PREF_MEMORY_BASE,
IORESOURCE_MEM | IORESOURCE_PREFETCH,
IORESOURCE_MEM | IORESOURCE_PREFETCH);
pci_record_bridge_resource(
dev, moving, PCI_PREF_MEMORY_BASE,
IORESOURCE_MEM | IORESOURCE_PREFETCH,
IORESOURCE_MEM | IORESOURCE_PREFETCH);
/* See if the bridge mem resources are implemented */
moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
@ -369,26 +415,25 @@ static void pci_bridge_read_bases(struct device *dev)
moving = moving_base & moving_limit;
/* Initialize the memory resources on the current bus */
pci_record_bridge_resource(dev, moving, PCI_MEMORY_BASE,
IORESOURCE_MEM | IORESOURCE_PREFETCH,
IORESOURCE_MEM);
pci_record_bridge_resource(
dev, moving, PCI_MEMORY_BASE,
IORESOURCE_MEM | IORESOURCE_PREFETCH,
IORESOURCE_MEM);
compact_resources(dev);
}
void pci_dev_read_resources(struct device *dev)
{
uint32_t addr;
pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
pci_read_bases(dev, 6);
pci_get_rom_resource(dev, PCI_ROM_ADDRESS);
}
void pci_bus_read_resources(struct device *dev)
{
uint32_t addr;
pci_bridge_read_bases(dev);
pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
pci_read_bases(dev, 2);
pci_get_rom_resource(dev, PCI_ROM_ADDRESS1);
}
static void pci_set_resource(struct device *dev, struct resource *resource)
@ -397,8 +442,10 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
/* Make certain the resource has actually been set */
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
printk_err("ERROR: %s %02x not allocated\n",
dev_path(dev), resource->index);
printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
dev_path(dev), resource->index,
resource_type(resource),
resource->size);
return;
}
@ -497,10 +544,10 @@ void pci_dev_set_resources(struct device *dev)
last = &dev->resource[dev->resources];
for (resource = &dev->resource[0]; resource < last; resource++) {
for(resource = &dev->resource[0]; resource < last; resource++) {
pci_set_resource(dev, resource);
}
for (link = 0; link < dev->links; link++) {
for(link = 0; link < dev->links; link++) {
struct bus *bus;
bus = &dev->link[link];
if (bus->children) {
@ -551,14 +598,10 @@ void pci_dev_enable_resources(struct device *dev)
void pci_bus_enable_resources(struct device *dev)
{
uint16_t ctrl;
#if CONFIG_CONSOLE_VGA == 1
/* enable IO in command register if there is VGA card
* connected with (even it does not claim IO resource) */
if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
dev->command |= PCI_COMMAND_IO;
#endif
ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
ctrl |= dev->link[0].bridge_ctrl;
ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
@ -570,15 +613,27 @@ void pci_bus_enable_resources(struct device *dev)
enable_childrens_resources(dev);
}
void pci_bus_reset(struct bus *bus)
{
unsigned ctl;
ctl = pci_read_config16(bus->dev, PCI_BRIDGE_CONTROL);
ctl |= PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
mdelay(10);
ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
delay(1);
}
void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
#if CONFIG_PCI_ROM_RUN == 1
void pci_dev_init(struct device *dev)
{
#if CONFIG_PCI_ROM_RUN == 1
struct rom_header *rom, *ram;
rom = pci_rom_probe(dev);
@ -589,8 +644,8 @@ void pci_dev_init(struct device *dev)
return;
run_bios(dev, ram);
}
#endif
}
/** Default device operation for PCI devices */
static struct pci_operations pci_dev_ops_pci = {
@ -601,11 +656,7 @@ struct device_operations default_pci_ops_dev = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
#if CONFIG_PCI_ROM_RUN == 1
.init = pci_dev_init,
#else
.init = 0,
#endif
.scan_bus = 0,
.enable = 0,
.ops_pci = &pci_dev_ops_pci,
@ -623,9 +674,78 @@ struct device_operations default_pci_ops_bus = {
.init = 0,
.scan_bus = pci_scan_bridge,
.enable = 0,
.reset_bus = pci_bus_reset,
.ops_pci = &pci_bus_ops_pci,
};
/**
* @brief Detect the type of downstream bridge
*
* This function is a heuristic to detect which type
* of bus is downstream of a pci to pci bridge. This
* functions by looking for various capability blocks
* to figure out the type of downstream bridge. PCI-X
* PCI-E, and Hypertransport all seem to have appropriate
* capabilities.
*
* When only a PCI-Express capability is found the type
* is examined to see which type of bridge we have.
*
* @param dev
*
* @return appropriate bridge operations
*/
static struct device_operations *get_pci_bridge_ops(device_t dev)
{
unsigned pos;
#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (pos) {
printk_debug("%s subbordinate bus PCI-X\n", dev_path(dev));
return &default_pcix_ops_bus;
}
#endif
#if CONFIG_AGP_PLUGIN_SUPPORT == 1
/* How do I detect an PCI to AGP bridge? */
#endif
#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
pos = 0;
while((pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos))) {
unsigned flags;
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
if ((flags >> 13) == 1) {
/* Host or Secondary Interface */
printk_debug("%s subbordinate bus Hypertransport\n",
dev_path(dev));
return &default_ht_ops_bus;
}
}
#endif
#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
pos = pci_find_capability(dev, PCI_CAP_ID_PCIE);
if (pos) {
unsigned flags;
flags = pci_read_config16(dev, pos + PCI_EXP_FLAGS);
switch((flags & PCI_EXP_FLAGS_TYPE) >> 4) {
case PCI_EXP_TYPE_ROOT_PORT:
case PCI_EXP_TYPE_UPSTREAM:
case PCI_EXP_TYPE_DOWNSTREAM:
printk_debug("%s subbordinate bus PCI Express\n",
dev_path(dev));
return &default_pciexp_ops_bus;
case PCI_EXP_TYPE_PCI_BRIDGE:
printk_debug("%s subbordinate PCI\n",
dev_path(dev));
return &default_pci_ops_bus;
default:
break;
}
}
#endif
return &default_pci_ops_bus;
}
/**
* @brief Set up PCI device operation
*
@ -644,12 +764,12 @@ static void set_pci_ops(struct device *dev)
/* Look through the list of setup drivers and find one for
* this pci device
*/
for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
for(driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
if ((driver->vendor == dev->vendor) &&
(driver->device == dev->device))
(driver->device == dev->device))
{
dev->ops = driver->ops;
printk_debug("%s [%04x/%04x] %sops\n",
printk_spew("%s [%04x/%04x] %sops\n",
dev_path(dev),
driver->vendor, driver->device,
(driver->ops->scan_bus?"bus ":""));
@ -667,8 +787,13 @@ static void set_pci_ops(struct device *dev)
case PCI_HEADER_TYPE_BRIDGE:
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
goto bad;
dev->ops = &default_pci_ops_bus;
dev->ops = get_pci_bridge_ops(dev);
break;
#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
case PCI_HEADER_TYPE_CARDBUS:
dev->ops = &default_cardbus_ops_bus;
break;
#endif
default:
bad:
if (dev->enabled) {
@ -682,6 +807,8 @@ static void set_pci_ops(struct device *dev)
return;
}
/**
* @brief See if we have already allocated a device structure for a given devfn.
*
@ -702,7 +829,7 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
for(; *list; list = &(*list)->sibling) {
if ((*list)->path.type != DEVICE_PATH_PCI) {
printk_err("child %s not a pci device\n",
dev_path(*list));
dev_path(*list));
continue;
}
if ((*list)->path.u.pci.devfn == devfn) {
@ -713,15 +840,15 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
break;
}
}
/* Just like alloc_dev add the device to the list of device on the bus.
* When the list of devices was formed we removed all of the parents
* children, and now we are interleaving static and dynamic devices in
/* Just like alloc_dev add the device to the list of device on the bus.
* When the list of devices was formed we removed all of the parents
* children, and now we are interleaving static and dynamic devices in
* order on the bus.
*/
if (dev) {
device_t child;
/* Find the last child of our parent */
for (child = dev->bus->children; child && child->sibling; ) {
for(child = dev->bus->children; child && child->sibling; ) {
child = child->sibling;
}
/* Place the device on the list of children of it's parent. */
@ -735,12 +862,131 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
return dev;
}
/**
* @brief Scan a PCI bus.
*
* Determine the existence of a given PCI device.
*
* @param bus pointer to the bus structure
* @param devfn to look at
*
* @return The device structure for hte device (if found)
* or the NULL if no device is found.
*/
device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
{
uint32_t id, class;
uint8_t hdr_type;
/* Detect if a device is present */
if (!dev) {
struct device dummy;
dummy.bus = bus;
dummy.path.type = DEVICE_PATH_PCI;
dummy.path.u.pci.devfn = devfn;
id = pci_read_config32(&dummy, PCI_VENDOR_ID);
/* Have we found somthing?
* Some broken boards return 0 if a slot is empty.
*/
if ( (id == 0xffffffff) || (id == 0x00000000) ||
(id == 0x0000ffff) || (id == 0xffff0000))
{
printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
return NULL;
}
dev = alloc_dev(bus, &dummy.path);
}
else {
/* Enable/disable the device. Once we have
* found the device specific operations this
* operations we will disable the device with
* those as well.
*
* This is geared toward devices that have subfunctions
* that do not show up by default.
*
* If a device is a stuff option on the motherboard
* it may be absent and enable_dev must cope.
*
*/
/* Run the magice enable sequence for the device */
if (dev->chip_ops && dev->chip_ops->enable_dev) {
dev->chip_ops->enable_dev(dev);
}
/* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID);
/* If the device does not have a pci id disable it.
* Possibly this is because we have already disabled
* the device. But this also handles optional devices
* that may not always show up.
*/
/* If the chain is fully enumerated quit */
if ( (id == 0xffffffff) || (id == 0x00000000) ||
(id == 0x0000ffff) || (id == 0xffff0000))
{
if (dev->enabled) {
printk_info("Disabling static device: %s\n",
dev_path(dev));
dev->enabled = 0;
}
return dev;
}
}
/* Read the rest of the pci configuration information */
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
class = pci_read_config32(dev, PCI_CLASS_REVISION);
/* Store the interesting information in the device structure */
dev->vendor = id & 0xffff;
dev->device = (id >> 16) & 0xffff;
dev->hdr_type = hdr_type;
/* class code, the upper 3 bytes of PCI_CLASS_REVISION */
dev->class = class >> 8;
/* Architectural/System devices always need to
* be bus masters.
*/
if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
dev->command |= PCI_COMMAND_MASTER;
}
/* Look at the vendor and device id, or at least the
* header type and class and figure out which set of
* configuration methods to use. Unless we already
* have some pci ops.
*/
set_pci_ops(dev);
/* Now run the magic enable/disable sequence for the device */
if (dev->ops && dev->ops->enable) {
dev->ops->enable(dev);
}
/* Display the device and error if we don't have some pci operations
* for it.
*/
printk_debug("%s [%04x/%04x] %s%s\n",
dev_path(dev),
dev->vendor, dev->device,
dev->enabled?"enabled": "disabled",
dev->ops?"" : " No operations"
);
return dev;
}
/**
* @brief Scan a PCI bus.
*
* Determine the existence of devices and bridges on a PCI bus. If there are
* bridges on the bus, recursively scan the buses behind the bridges.
*
* This function is the default scan_bus() method for the root device
* 'dev_root'.
*
* @param bus pointer to the bus structure
* @param min_devfn minimum devfn to look at in the scan usually 0x00
* @param max_devfn maximum devfn to look at in the scan usually 0xff
@ -748,11 +994,11 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
*
* @return The maximum bus number found, after scanning all subordinate busses
*/
unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn,
unsigned int max)
unsigned int pci_scan_bus(struct bus *bus,
unsigned min_devfn, unsigned max_devfn,
unsigned int max)
{
unsigned int devfn;
device_t dev;
device_t old_devices;
device_t child;
@ -762,141 +1008,49 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devf
bus->children = 0;
post_code(0x24);
/* probe all devices/functions on this bus with some optimization for
* non-existence and single funcion devices
*/
for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
uint32_t id, class;
uint8_t hdr_type;
device_t dev;
/* First thing setup the device structure */
dev = pci_scan_get_dev(&old_devices, devfn);
/* Detect if a device is present */
if (!dev) {
struct device dummy;
dummy.bus = bus;
dummy.path.type = DEVICE_PATH_PCI;
dummy.path.u.pci.devfn = devfn;
id = pci_read_config32(&dummy, PCI_VENDOR_ID);
/* some broken boards return 0 if a slot is empty: */
if ((id == 0xffffffff) || (id == 0x00000000) ||
(id == 0x0000ffff) || (id == 0xffff0000))
{
printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
if (PCI_FUNC(devfn) == 0x00) {
/* if this is a function 0 device and
* it is not present,
* skip to next device
*/
devfn += 0x07;
}
/* This function in a multi function device is
* not present, skip to the next function.
*/
continue;
}
dev = alloc_dev(bus, &dummy.path);
}
else {
/* Enable/disable the device. Once we have
* found the device specific operations this
* operations we will disable the device with
* those as well.
*
* This is geared toward devices that have subfunctions
* that do not show up by default.
*
* If a device is a stuff option on the motherboard
* it may be absent and enable_dev must cope.
*
*/
if (dev->chip_ops && dev->chip_ops->enable_dev)
{
dev->chip_ops->enable_dev(dev);
}
/* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID);
/* If the device does not have a pci id disable it.
* Possibly this is because we have already disabled
* the device. But this also handles optional devices
* that may not always show up.
*/
if (id == 0xffffffff || id == 0x00000000 ||
id == 0x0000ffff || id == 0xffff0000)
{
if (dev->enabled) {
printk_info("Disabling static device: %s\n",
dev_path(dev));
dev->enabled = 0;
}
continue;
}
}
/* Read the rest of the pci configuration information */
hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
class = pci_read_config32(dev, PCI_CLASS_REVISION);
/* Store the interesting information in the device structure */
dev->vendor = id & 0xffff;
dev->device = (id >> 16) & 0xffff;
dev->hdr_type = hdr_type;
/* class code, the upper 3 bytes of PCI_CLASS_REVISION */
dev->class = class >> 8;
/* Architectural/System devices always need to
* be bus masters.
/* See if a device is present and setup the device
* structure.
*/
if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
dev->command |= PCI_COMMAND_MASTER;
}
dev = pci_probe_dev(dev, bus, devfn);
/* Look at the vendor and device id, or at least the
* header type and class and figure out which set of
* configuration methods to use. Unless we already
* have some pci ops.
/* if this is not a multi function device,
* or the device is not present don't waste
* time probing another function.
* Skip to next device.
*/
set_pci_ops(dev);
/* Error if we don't have some pci operations for it */
if (!dev->ops) {
printk_err("%s No device operations\n",
dev_path(dev));
continue;
}
/* Now run the magic enable/disable sequence for the device */
if (dev->ops && dev->ops->enable) {
dev->ops->enable(dev);
}
printk_debug("%s [%04x/%04x] %s\n",
dev_path(dev),
dev->vendor, dev->device,
dev->enabled?"enabled": "disabled");
if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) {
/* if this is not a multi function device,
* don't waste time probing another function.
* Skip to next device.
*/
if ((PCI_FUNC(devfn) == 0x00) &&
(!dev || (dev->enabled && ((dev->hdr_type & 0x80) != 0x80))))
{
devfn += 0x07;
}
}
post_code(0x25);
/* Die if any leftover Static devices are are found.
* There's probably a problem in the Config.lb.
*/
if(old_devices) {
device_t left;
for(left = old_devices; left; left = left->sibling) {
printk_debug("%s\n", dev_path(left));
}
die("Left over static devices. Check your Config.lb\n");
}
/* For all children that implement scan_bus (i.e. bridges)
* scan the bus behind that child.
*/
for (child = bus->children; child; child = child->sibling) {
if (!child->enabled ||
!child->ops ||
!child->ops->scan_bus)
{
continue;
}
max = child->ops->scan_bus(child, max);
for(child = bus->children; child; child = child->sibling) {
max = scan_bus(child, max);
}
/*
@ -911,6 +1065,7 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devf
return max;
}
/**
* @brief Scan a PCI bridge and the buses behind the bridge.
*
@ -924,7 +1079,9 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devf
*
* @return The maximum bus number found, after scanning all subordinate busses
*/
unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
unsigned int (*do_scan_bus)(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max))
{
struct bus *bus;
uint32_t buses;
@ -960,14 +1117,14 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
*/
buses &= 0xff000000;
buses |= (((unsigned int) (dev->bus->secondary) << 0) |
((unsigned int) (bus->secondary) << 8) |
((unsigned int) (bus->subordinate) << 16));
((unsigned int) (bus->secondary) << 8) |
((unsigned int) (bus->subordinate) << 16));
pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
/* Now we can scan all subordinate buses
* i.e. the bus behind the bridge.
*/
max = pci_scan_bus(bus, 0x00, 0xff, max);
max = do_scan_bus(bus, 0x00, 0xff, max);
/* We know the number of buses behind this bridge. Set the subordinate
* bus number to its real value.
@ -977,11 +1134,29 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
((unsigned int) (bus->subordinate) << 16);
pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
pci_write_config16(dev, PCI_COMMAND, cr);
printk_spew("%s returns max %d\n", __func__, max);
return max;
}
/**
* @brief Scan a PCI bridge and the buses behind the bridge.
*
* Determine the existence of buses behind the bridge. Set up the bridge
* according to the result of the scan.
*
* This function is the default scan_bus() method for PCI bridge devices.
*
* @param dev pointer to the bridge device
* @param max the highest bus number assgined up to now
*
* @return The maximum bus number found, after scanning all subordinate busses
*/
unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
{
return do_pci_scan_bridge(dev, max, pci_scan_bus);
}
/*
Tell the EISA int controller this int must be level triggered
THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
@ -1026,7 +1201,8 @@ static void pci_level_irq(unsigned char intNum)
-kevinh@ispiri.com
*/
void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4])
void pci_assign_irqs(unsigned bus, unsigned slot,
const unsigned char pIntAtoD[4])
{
unsigned functNum;
device_t pdev;

View File

@ -0,0 +1,60 @@
/* (c) 2005 Linux Networx GPL see COPYING for details */
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pciexp.h>
static void pciexp_tune_dev(device_t dev)
{
unsigned cap;
cap = pci_find_capability(dev, PCI_CAP_ID_PCIE);
if (!cap) {
/* error... */
return;
}
printk_debug("PCIEXP: tunning %s\n", dev_path(dev));
#warning "IMPLEMENT PCI EXPRESS TUNING"
}
unsigned int pciexp_scan_bus(struct bus *bus,
unsigned min_devfn, unsigned max_devfn,
unsigned int max)
{
device_t child;
max = pci_scan_bus(bus, min_devfn, max_devfn, max);
for(child = bus->children; child; child = child->sibling) {
if ( (child->path.u.pci.devfn < min_devfn) ||
(child->path.u.pci.devfn > max_devfn))
{
continue;
}
pciexp_tune_dev(child);
}
return max;
}
unsigned int pciexp_scan_bridge(device_t dev, unsigned int max)
{
return do_pci_scan_bridge(dev, max, pciexp_scan_bus);
}
/** Default device operations for PCI Express bridges */
static struct pci_operations pciexp_bus_ops_pci = {
.set_subsystem = 0,
};
struct device_operations default_pciexp_ops_bus = {
.read_resources = pci_bus_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.init = 0,
.scan_bus = pciexp_scan_bridge,
.enable = 0,
.reset_bus = pci_bus_reset,
.ops_pci = &pciexp_bus_ops_pci,
};

140
src/devices/pcix_device.c Normal file
View File

@ -0,0 +1,140 @@
/* (c) 2005 Linux Networx GPL see COPYING for details */
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pcix.h>
static void pcix_tune_dev(device_t dev)
{
unsigned cap;
unsigned status, orig_cmd, cmd;
unsigned max_read, max_tran;
if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) {
return;
}
cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!cap) {
return;
}
printk_debug("%s PCI-X tuning\n", dev_path(dev));
status = pci_read_config32(dev, cap + PCI_X_STATUS);
orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD);
max_read = (status & PCI_X_STATUS_MAX_READ) >> 21;
max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23;
if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) {
cmd &= ~PCI_X_CMD_MAX_READ;
cmd |= max_read << 2;
}
if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) {
cmd &= ~PCI_X_CMD_MAX_SPLIT;
cmd |= max_tran << 4;
}
/* Don't attempt to handle PCI-X errors */
cmd &= ~PCI_X_CMD_DPERR_E;
/* Enable Relaxed Ordering */
cmd |= PCI_X_CMD_ERO;
if (orig_cmd != cmd) {
pci_write_config16(dev, cap + PCI_X_CMD, cmd);
}
}
unsigned int pcix_scan_bus(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max)
{
device_t child;
max = pci_scan_bus(bus, min_devfn, max_devfn, max);
for(child = bus->children; child; child = child->sibling) {
if ( (child->path.u.pci.devfn < min_devfn) ||
(child->path.u.pci.devfn > max_devfn))
{
continue;
}
pcix_tune_dev(child);
}
return max;
}
const char *pcix_speed(unsigned sstatus)
{
static const char conventional[] = "Conventional PCI";
static const char pcix_66mhz[] = "66MHz PCI-X";
static const char pcix_100mhz[] = "100MHz PCI-X";
static const char pcix_133mhz[] = "133MHz PCI-X";
static const char pcix_266mhz[] = "266MHz PCI-X";
static const char pcix_533mhz[] = "533MHZ PCI-X";
static const char unknown[] = "Unknown";
const char *result;
result = unknown;
switch(PCI_X_SSTATUS_MFREQ(sstatus)) {
case PCI_X_SSTATUS_CONVENTIONAL_PCI:
result = conventional;
break;
case PCI_X_SSTATUS_MODE1_66MHZ:
result = pcix_66mhz;
break;
case PCI_X_SSTATUS_MODE1_100MHZ:
result = pcix_100mhz;
break;
case PCI_X_SSTATUS_MODE1_133MHZ:
result = pcix_133mhz;
break;
case PCI_X_SSTATUS_MODE2_266MHZ_REF_66MHZ:
case PCI_X_SSTATUS_MODE2_266MHZ_REF_100MHZ:
case PCI_X_SSTATUS_MODE2_266MHZ_REF_133MHZ:
result = pcix_266mhz;
break;
case PCI_X_SSTATUS_MODE2_533MHZ_REF_66MHZ:
case PCI_X_SSTATUS_MODE2_533MHZ_REF_100MHZ:
case PCI_X_SSTATUS_MODE2_533MHZ_REF_133MHZ:
result = pcix_533mhz;
break;
}
return result;
}
unsigned int pcix_scan_bridge(device_t dev, unsigned int max)
{
unsigned pos;
unsigned sstatus;
/* Find the PCI-X capability */
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
sstatus = pci_read_config16(dev, pos + PCI_X_SEC_STATUS);
if (PCI_X_SSTATUS_MFREQ(sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
max = do_pci_scan_bridge(dev, max, pci_scan_bus);
} else {
max = do_pci_scan_bridge(dev, max, pcix_scan_bus);
}
/* Print the PCI-X bus speed */
printk_debug("PCI: %02x: %s\n", dev->link[0].secondary, pcix_speed(sstatus));
return max;
}
/** Default device operations for PCI-X bridges */
static struct pci_operations pcix_bus_ops_pci = {
.set_subsystem = 0,
};
struct device_operations default_pcix_ops_bus = {
.read_resources = pci_bus_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.init = 0,
.scan_bus = pcix_scan_bridge,
.enable = 0,
.reset_bus = pci_bus_reset,
.ops_pci = &pcix_bus_ops_pci,
};

View File

@ -68,8 +68,10 @@ void pnp_read_resources(device_t dev)
static void pnp_set_resource(device_t dev, struct resource *resource)
{
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
printk_err("ERROR: %s %02x not allocated\n",
dev_path(dev), resource->index);
printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
dev_path(dev), resource->index,
resource_type(resource),
resource->size);
return;
}

View File

@ -1,6 +1,7 @@
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <part/hard_reset.h>
/**
* Read the resources for the root device,
@ -35,8 +36,9 @@ void root_dev_read_resources(device_t root)
}
/**
* @brief Write the resources for the root device
* @brief Write the resources for every device
*
* Write the resources for the root device,
* and every device under it which are all of the devices.
* @param root Pointer to the device structure for the system root device
*/
@ -45,10 +47,10 @@ void root_dev_set_resources(device_t root)
struct bus *bus;
bus = &root->link[0];
compute_allocate_resource(bus, &root->resource[0],
IORESOURCE_IO, IORESOURCE_IO);
compute_allocate_resource(bus, &root->resource[1],
IORESOURCE_MEM, IORESOURCE_MEM);
compute_allocate_resource(bus,
&root->resource[0], IORESOURCE_IO, IORESOURCE_IO);
compute_allocate_resource(bus,
&root->resource[1], IORESOURCE_MEM, IORESOURCE_MEM);
assign_resources(bus);
}
@ -57,9 +59,9 @@ void root_dev_set_resources(device_t root)
*
* The enumeration of certain buses is purely static. The existence of
* devices on those buses can be completely determined at compile time
* and is specified in the config file. Typical exapmles are the 'PNP'
* devices on a legacy ISA/LPC bus. There is no need of probing of any
* kind, the only thing we have to do is to walk through the bus and
* and is specified in the config file. Typical examples are the 'PNP'
* devices on a legacy ISA/LPC bus. There is no need of probing of any kind,
* the only thing we have to do is to walk through the bus and
* enable or disable devices as indicated in the config file.
*
* On the other hand, some devices are virtual and their existence is
@ -70,47 +72,50 @@ void root_dev_set_resources(device_t root)
* This function is the default scan_bus() method for the root device and
* LPC bridges.
*
* @param root Pointer to the root device which the static buses are attached
* @param bus Pointer to the device structure which the static buses are attached
* @param max Maximum bus number currently used before scanning.
* @return Largest bus number used after scanning.
* @return Largest bus number used.
*/
static int smbus_max = 0;
unsigned int scan_static_bus(device_t root, unsigned int max)
unsigned int scan_static_bus(device_t bus, unsigned int max)
{
device_t child;
unsigned link;
printk_spew("%s for %s\n", __func__, dev_path(root));
printk_spew("%s for %s\n", __func__, dev_path(bus));
for (link = 0; link < root->links; link++) {
/* for smbus bus enumerate */
child = root->link[link].children;
if(child && child->path.type == DEVICE_PATH_I2C) {
root->link[link].secondary = ++smbus_max;
}
for (child = root->link[link].children; child; child = child->sibling) {
for(link = 0; link < bus->links; link++) {
/* for smbus bus enumerate */
child = bus->link[link].children;
if(child && child->path.type == DEVICE_PATH_I2C) {
bus->link[link].secondary = ++smbus_max;
}
for(child = bus->link[link].children; child; child = child->sibling) {
if (child->chip_ops && child->chip_ops->enable_dev) {
child->chip_ops->enable_dev(child);
}
if (child->ops && child->ops->enable) {
child->ops->enable(child);
}
if (child->path.type == DEVICE_PATH_I2C)
printk_debug("smbus: %s[%d]->", dev_path(child->bus->dev), child->bus->link );
printk_debug("%s %s\n", dev_path(child),
child->enabled?"enabled": "disabled");
if (child->path.type == DEVICE_PATH_I2C) {
printk_debug("smbus: %s[%d]->",
dev_path(child->bus->dev), child->bus->link );
}
printk_debug("%s %s\n",
dev_path(child),
child->enabled?"enabled": "disabled");
}
}
for (link = 0; link < root->links; link++) {
for (child = root->link[link].children; child; child = child->sibling) {
for(link = 0; link < bus->links; link++) {
for(child = bus->link[link].children; child; child = child->sibling) {
if (!child->ops || !child->ops->scan_bus)
continue;
printk_spew("%s scanning...\n", dev_path(child));
max = child->ops->scan_bus(child, max);
max = scan_bus(child, max);
}
}
printk_spew("%s for %s done\n", __func__, dev_path(root));
printk_spew("%s for %s done\n", __func__, dev_path(bus));
return max;
}
@ -120,7 +125,7 @@ unsigned int scan_static_bus(device_t root, unsigned int max)
*
* @param dev the device whos children's resources are to be enabled
*
* This function is call by the global enable_resources() indirectly via the
* This function is called by the global enable_resource() indirectly via the
* device_operation::enable_resources() method of devices.
*
* Indirect mutual recursion:
@ -131,9 +136,9 @@ unsigned int scan_static_bus(device_t root, unsigned int max)
void enable_childrens_resources(device_t dev)
{
unsigned link;
for (link = 0; link < dev->links; link++) {
for(link = 0; link < dev->links; link++) {
device_t child;
for (child = dev->link[link].children; child; child = child->sibling) {
for(child = dev->link[link].children; child; child = child->sibling) {
enable_resources(child);
}
}
@ -161,6 +166,12 @@ void root_dev_init(device_t root)
{
}
void root_dev_reset(struct bus *bus)
{
printk_info("Reseting board...\n");
hard_reset();
}
/**
* @brief Default device operation for root device
*
@ -174,6 +185,7 @@ struct device_operations default_dev_ops_root = {
.enable_resources = root_dev_enable_resources,
.init = root_dev_init,
.scan_bus = root_dev_scan_bus,
.reset_bus = root_dev_reset,
};
/**

View File

@ -268,6 +268,9 @@ static void debug_init(device_t dev)
case 7:
print_tsc();
break;
case 8:
hard_reset();
break;
}
}

View File

@ -34,7 +34,9 @@
#if !defined(__ROMCC__) && !defined (ASSEMBLY)
void x86_setup_mtrrs(void);
void x86_setup_var_mtrrs(unsigned address_bits);
void x86_setup_mtrrs(unsigned address_bits);
int x86_mtrr_check(void);
#endif /* __ROMCC__ */

12
src/include/device/agp.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef DEVICE_AGP_H
#define DEVICE_AGP_H
/* (c) 2005 Linux Networx GPL see COPYING for details */
unsigned int agp_scan_bus(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max);
unsigned int agp_scan_bridge(device_t dev, unsigned int max);
extern struct device_operations default_agp_ops_bus;
#endif /* DEVICE_AGP_H */

View File

@ -0,0 +1,12 @@
#ifndef DEVICE_CARDBUS_H
#define DEVICE_CARDBUS_H
/* (c) 2005 Linux Networx GPL see COPYING for details */
void cardbus_read_resources(device_t dev);
unsigned int cardbus_scan_bus(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max);
unsigned int cardbus_scan_bridge(device_t dev, unsigned int max);
extern struct device_operations default_cardbus_ops_bus;
#endif /* DEVICE_CARDBUS_H */

View File

@ -26,6 +26,8 @@ struct chip_operations {
#define CHIP_NAME(X)
#endif
struct bus;
struct device_operations {
void (*read_resources)(device_t dev);
void (*set_resources)(device_t dev);
@ -34,6 +36,7 @@ struct device_operations {
unsigned int (*scan_bus)(device_t bus, unsigned int max);
void (*enable)(device_t dev);
void (*set_link)(device_t dev, unsigned int link);
void (*reset_bus)(struct bus *bus);
const struct pci_operations *ops_pci;
const struct smbus_bus_operations *ops_smbus_bus;
const struct pci_bus_operations *ops_pci_bus;
@ -48,6 +51,8 @@ struct bus {
unsigned char secondary; /* secondary bus number */
unsigned char subordinate; /* max subordinate bus number */
unsigned char cap; /* PCi capability offset */
unsigned reset_needed : 1;
unsigned disable_relaxed_ordering : 1;
};
#define MAX_RESOURCES 12
@ -81,7 +86,8 @@ struct device {
unsigned int resources;
/* link are (down sream) buses attached to the device, usually a leaf
* device with no child have 0 bus attached and a bridge has 1 bus */
* device with no children have 0 buses attached and a bridge has 1 bus
*/
struct bus link[MAX_LINKS];
/* number of buses attached to the device */
unsigned int links;
@ -101,8 +107,11 @@ extern void dev_enumerate(void);
extern void dev_configure(void);
extern void dev_enable(void);
extern void dev_initialize(void);
extern void dev_optimize(void);
/* Generic device helper functions */
extern int reset_bus(struct bus *bus);
extern unsigned int scan_bus(struct device *bus, unsigned int max);
extern void compute_allocate_resource(struct bus *bus, struct resource *bridge,
unsigned long type_mask, unsigned long type);
extern void assign_resources(struct bus *bus);
@ -110,6 +119,9 @@ extern void enable_resources(struct device *dev);
extern void enumerate_static_device(void);
extern void enumerate_static_devices(void);
extern const char *dev_path(device_t dev);
const char *bus_path(struct bus *bus);
extern void dev_set_enabled(device_t dev, int enable);
extern void disable_children(struct bus *bus);
/* Helper functions */
device_t find_dev_path(struct bus *parent, struct device_path *path);
@ -134,5 +146,4 @@ extern void enable_childrens_resources(device_t dev);
extern void root_dev_enable_resources(device_t dev);
extern unsigned int root_dev_scan_bus(device_t root, unsigned int max);
extern void root_dev_init(device_t dev);
#endif /* DEVICE_H */

View File

@ -3,7 +3,10 @@
#include <device/hypertransport_def.h>
unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max);
unsigned int hypertransport_scan_chain(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max);
unsigned int ht_scan_bridge(struct device *dev, unsigned int max);
extern struct device_operations default_ht_ops_bus;
#define HT_IO_HOST_ALIGN 4096
#define HT_MEM_HOST_ALIGN (1024*1024)

View File

@ -72,6 +72,7 @@ struct device_path {
#define DEVICE_PATH_MAX 30
#define BUS_PATH_MAX (DEVICE_PATH_MAX+10)
extern int path_eq(struct device_path *path1, struct device_path *path2);

View File

@ -50,16 +50,26 @@ extern struct pci_driver pci_drivers[];
extern struct pci_driver epci_drivers[];
struct device_operations default_pci_ops_dev;
struct device_operations default_pci_ops_bus;
extern struct device_operations default_pci_ops_dev;
extern struct device_operations default_pci_ops_bus;
void pci_dev_read_resources(device_t dev);
void pci_bus_read_resources(device_t dev);
void pci_dev_set_resources(device_t dev);
void pci_dev_enable_resources(device_t dev);
void pci_bus_enable_resources(device_t dev);
void pci_bus_reset(struct bus *bus);
device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn);
unsigned int do_pci_scan_bridge(device_t bus, unsigned int max,
unsigned int (*do_scan_bus)(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max));
unsigned int pci_scan_bridge(device_t bus, unsigned int max);
unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn, unsigned int max);
uint8_t pci_moving_config8(struct device *dev, unsigned reg);
uint16_t pci_moving_config16(struct device *dev, unsigned reg);
uint32_t pci_moving_config32(struct device *dev, unsigned reg);
unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last);
unsigned pci_find_capability(device_t dev, unsigned cap);
struct resource *pci_get_resource(struct device *dev, unsigned long index);
void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device);

View File

@ -181,15 +181,20 @@
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
#define PCI_CAP_ID_PCIX 0x07 /* PCIX */
#define PCI_CAP_ID_HT 0x08 /* Hypertransport */
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
#define PCI_CAP_ID_PCIE 0x10 /* PCI Express */
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
/* Hypertransport Registers */
#define PCI_HT_CAP_SIZEOF 4
#define PCI_HT_CAP_HOST_CTRL 4 /* Host link control */
#define PCI_HT_CAP_HOST_WIDTH 6 /* width value & capability */
#define PCI_HT_CAP_HOST_FREQ 0x09 /* Host frequency */
#define PCI_HT_CAP_HOST_FREQ_CAP 0x0a /* Host Frequency capability */
#define PCI_HT_CAP_SLAVE_CTRL0 4 /* link control */
#define PCI_HT_CAP_SLAVE_CTRL1 8 /* link control to */
#define PCI_HT_CAP_SLAVE_WIDTH0 6 /* width value & capability */
#define PCI_HT_CAP_SLAVE_WIDTH1 0x0a /* width value & capability to */
#define PCI_HT_CAP_SLAVE_FREQ0 0x0d /* Slave frequency from */
@ -199,6 +204,7 @@
/* Power Management Registers */
#define PCI_PM_PMC 2 /* PM Capabilities Register */
#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
#define PCI_PM_CAP_AUX_POWER 0x0010 /* Auxilliary power support */
@ -260,6 +266,191 @@
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
#define PCI_MSI_MASK_BIT 16 /* Mask bits register */
/* CompactPCI Hotswap Register */
#define PCI_CHSWP_CSR 2 /* Control and Status Register */
#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */
#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */
#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */
#define PCI_CHSWP_LOO 0x08 /* LED On / Off */
#define PCI_CHSWP_PI 0x30 /* Programming Interface */
#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */
#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */
/* PCI-X registers */
#define PCI_X_CMD 2 /* Modes & Features */
#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */
#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */
#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */
#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */
#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */
#define PCI_X_STATUS 4 /* PCI-X capabilities */
#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */
#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */
#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */
#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */
#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */
#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */
#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */
#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */
#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */
#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */
#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */
#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */
#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */
/* PCI-X bridge registers */
#define PCI_X_SEC_STATUS 2 /* Secondary status */
#define PCI_X_SSTATUS_64BIT 0x0001 /* The bus behind the bridge is 64bits wide */
#define PCI_X_SSTATUS_133MHZ 0x0002 /* The bus behind the bridge is 133Mhz Capable */
#define PCI_X_SSTATUS_SPL_DISC 0x0004 /* Split Completion Discarded */
#define PCI_X_SSTATUS_UNX_SPL 0x0008 /* Unexpected Split Completion */
#define PCI_X_SSTATUS_SPL_OVR 0x0010 /* Split Completion Overrun */
#define PCI_X_SSTATUS_SPL_DLY 0x0020 /* Split Completion Delayed */
#define PCI_X_SSTATUS_MFREQ(x) (((x) & 0x03c0) >> 6) /* PCI-X mode and frequency */
#define PCI_X_SSTATUS_CONVENTIONAL_PCI 0x0
#define PCI_X_SSTATUS_MODE1_66MHZ 0x1
#define PCI_X_SSTATUS_MODE1_100MHZ 0x2
#define PCI_X_SSTATUS_MODE1_133MHZ 0x3
#define PCI_X_SSTATUS_MODE2_266MHZ_REF_66MHZ 0x9
#define PCI_X_SSTATUS_MODE2_266MHZ_REF_100MHZ 0xa
#define PCI_X_SSTATUS_MODE2_266MHZ_REF_133MHZ 0xb
#define PCI_X_SSTATUS_MODE2_533MHZ_REF_66MHZ 0xd
#define PCI_X_SSTATUS_MODE2_533MHZ_REF_100MHZ 0xe
#define PCI_X_SSTATUS_MODE2_533MHZ_REF_133MHZ 0xf
#define PCI_X_SSTATUS_VERSION(x) (((x) >> 12) & 3) /* Version */
#define PCI_X_SSTATUS_266MHZ 0x4000 /* The bus behind the bridge is 266Mhz Capable */
#define PCI_X_SSTAUTS_533MHZ 0x8000 /* The bus behind the bridge is 533Mhz Capable */
/* PCI Express capability registers */
#define PCI_EXP_FLAGS 2 /* Capabilities register */
#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */
#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
#define PCI_EXP_DEVCTL 8 /* Device Control */
#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
#define PCI_EXP_DEVSTA 10 /* Device Status */
#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
#define PCI_EXP_LNKCAP 12 /* Link Capabilities */
#define PCI_EXP_LNKCTL 16 /* Link Control */
#define PCI_EXP_LNKSTA 18 /* Link Status */
#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
#define PCI_EXP_SLTCTL 24 /* Slot Control */
#define PCI_EXP_SLTSTA 26 /* Slot Status */
#define PCI_EXP_RTCTL 28 /* Root Control */
#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */
#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */
#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */
#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */
#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
#define PCI_EXP_RTCAP 30 /* Root Capabilities */
#define PCI_EXP_RTSTA 32 /* Root Status */
/* Extended Capabilities (PCI-X 2.0 and Express) */
#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
#define PCI_EXT_CAP_ID_ERR 1
#define PCI_EXT_CAP_ID_VC 2
#define PCI_EXT_CAP_ID_DSN 3
#define PCI_EXT_CAP_ID_PWR 4
/* Advanced Error Reporting */
#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */
#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */
#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */
#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */
#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */
#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */
#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */
#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */
#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */
#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */
#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */
#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */
/* Same bits as above */
#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */
/* Same bits as above */
#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */
#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */
#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */
#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
/* Same bits as above */
#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */
#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */
#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */
#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */
#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */
#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */
#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */
#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */
#define PCI_ERR_ROOT_STATUS 48
#define PCI_ERR_ROOT_COR_SRC 52
#define PCI_ERR_ROOT_SRC 54
/* Virtual Channel */
#define PCI_VC_PORT_REG1 4
#define PCI_VC_PORT_REG2 8
#define PCI_VC_PORT_CTRL 12
#define PCI_VC_PORT_STATUS 14
#define PCI_VC_RES_CAP 16
#define PCI_VC_RES_CTRL 20
#define PCI_VC_RES_STATUS 26
/* Power Budgeting */
#define PCI_PWR_DSR 4 /* Data Select Register */
#define PCI_PWR_DATA 8 /* Data Register */
#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */
#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */
#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */
#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */
#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */
#define PCI_PWR_CAP 12 /* Capability */
#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
/*
* The PCI interface treats multi-function devices as independent

View File

@ -137,12 +137,14 @@
#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34
#define PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE 0xae33
#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35
#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40
#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43
#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011
#define PCI_DEVICE_ID_COMPAQ_CISS 0xb060
#define PCI_DEVICE_ID_COMPAQ_CISSB 0xb178
#define PCI_DEVICE_ID_COMPAQ_CISSC 0x46
#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130
#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150
@ -165,6 +167,7 @@
#define PCI_DEVICE_ID_LSI_53C1010_33 0x0020
#define PCI_DEVICE_ID_LSI_53C1010_66 0x0021
#define PCI_DEVICE_ID_LSI_53C1030 0x0030
#define PCI_DEVICE_ID_LSI_1030_53C1035 0x0032
#define PCI_DEVICE_ID_LSI_53C1035 0x0040
#define PCI_DEVICE_ID_NCR_53C875J 0x008f
#define PCI_DEVICE_ID_LSI_FC909 0x0621
@ -172,9 +175,21 @@
#define PCI_DEVICE_ID_LSI_FC929_LAN 0x0623
#define PCI_DEVICE_ID_LSI_FC919 0x0624
#define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625
#define PCI_DEVICE_ID_LSI_FC929X 0x0626
#define PCI_DEVICE_ID_LSI_FC939X 0x0642
#define PCI_DEVICE_ID_LSI_FC949X 0x0640
#define PCI_DEVICE_ID_LSI_FC919X 0x0628
#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701
#define PCI_DEVICE_ID_LSI_61C102 0x0901
#define PCI_DEVICE_ID_LSI_63C815 0x1000
#define PCI_DEVICE_ID_LSI_SAS1064 0x0050
#define PCI_DEVICE_ID_LSI_SAS1066 0x005E
#define PCI_DEVICE_ID_LSI_SAS1068 0x0054
#define PCI_DEVICE_ID_LSI_SAS1064A 0x005C
#define PCI_DEVICE_ID_LSI_SAS1064E 0x0056
#define PCI_DEVICE_ID_LSI_SAS1066E 0x005A
#define PCI_DEVICE_ID_LSI_SAS1068E 0x0058
#define PCI_DEVICE_ID_LSI_SAS1078 0x0060
#define PCI_VENDOR_ID_ATI 0x1002
/* Mach64 */
@ -901,6 +916,33 @@
#define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029
#define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C
#define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D
#define PCI_DEVICE_ID_NVIDIA_CK804_LPC 0x0050
#define PCI_DEVICE_ID_NVIDIA_CK804_PRO 0x0051
#define PCI_DEVICE_ID_NVIDIA_CK804_ISA 0x0051
#define PCI_DEVICE_ID_NVIDIA_CK804_SMB 0x0052
#define PCI_DEVICE_ID_NVIDIA_CK804_SM 0x0052
#define PCI_DEVICE_ID_NVIDIA_CK804_ACPI 0x0052
#define PCI_DEVICE_ID_NVIDIA_CK804_IDE 0x0053
#define PCI_DEVICE_ID_NVIDIA_CK804_SATA0 0x0054
#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1 0x0055
#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1 0x0055
#define PCI_DEVICE_ID_NVIDIA_CK804_ENET 0x0056
#define PCI_DEVICE_ID_NVIDIA_CK804_NIC 0x0056
#define PCI_DEVICE_ID_NVIDIA_CK804_ENET2 0x0057
#define PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE 0x0057
#define PCI_DEVICE_ID_NVIDIA_CK804_MODEM 0x0058
#define PCI_DEVICE_ID_NVIDIA_CK804_MCI 0x0058
#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059
#define PCI_DEVICE_ID_NVIDIA_CK804_ACI 0x0059
#define PCI_DEVICE_ID_NVIDIA_CK804_USB 0x005A
#define PCI_DEVICE_ID_NVIDIA_CK804_USB2 0x005B
#define PCI_DEVICE_ID_NVIDIA_CK804_PCI 0x005C
#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005D
#define PCI_DEVICE_ID_NVIDIA_CK804_PCI_E 0x005D
#define PCI_DEVICE_ID_NVIDIA_CK804_MEM 0x005E
#define PCI_DEVICE_ID_NVIDIA_CK804_HT 0x005E
#define PCI_DEVICE_ID_NVIDIA_CK804_TRIM 0x005f
#define PCI_DEVICE_ID_NVIDIA_CK804_SLAVE 0x00d3
#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101
@ -919,23 +961,6 @@
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202
#define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC 0x0203
#define PCI_DEVICE_ID_NVIDIA_CK804_HT 0x005e
#define PCI_DEVICE_ID_NVIDIA_CK804_LPC 0x0050
#define PCI_DEVICE_ID_NVIDIA_CK804_PRO 0x0051
#define PCI_DEVICE_ID_NVIDIA_CK804_SLAVE 0x00d3
#define PCI_DEVICE_ID_NVIDIA_CK804_SM 0x0052
#define PCI_DEVICE_ID_NVIDIA_CK804_ACPI 0x0052
#define PCI_DEVICE_ID_NVIDIA_CK804_USB 0x005a
#define PCI_DEVICE_ID_NVIDIA_CK804_USB2 0x005b
#define PCI_DEVICE_ID_NVIDIA_CK804_NIC 0x0056
#define PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE 0x0057
#define PCI_DEVICE_ID_NVIDIA_CK804_ACI 0x0059
#define PCI_DEVICE_ID_NVIDIA_CK804_MCI 0x0058
#define PCI_DEVICE_ID_NVIDIA_CK804_IDE 0x0053
#define PCI_DEVICE_ID_NVIDIA_CK804_SATA0 0x0054
#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1 0x0055
#define PCI_DEVICE_ID_NVIDIA_CK804_PCI 0x005c
#define PCI_DEVICE_ID_NVIDIA_CK804_PCI_E 0x005d
#define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849
@ -1812,7 +1837,9 @@
#define PCI_DEVICE_ID_INTEL_6300ESB_USB2 0x25aa
#define PCI_DEVICE_ID_INTEL_6300ESB_USB3 0x25ad
#define PCI_DEVICE_ID_INTEL_6300ESB_SATA 0x25a3
#define PCI_DEVICE_ID_INTEL_6300ESB_SATA_R 0x25b0
#define PCI_DEVICE_ID_INTEL_6300ESB_PIC1 0x25ac
#define PCI_DEVICE_ID_INTEL_6300ESB_BRIDGE1C 0x25ae
#define PCI_DEVICE_ID_INTEL_80310 0x530d
#define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120
#define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121

View File

@ -0,0 +1,11 @@
#ifndef DEVICE_PCIEXP_H
#define DEVICE_PCIEXP_H
/* (c) 2005 Linux Networx GPL see COPYING for details */
unsigned int pciexp_scan_bus(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max);
unsigned int pciexp_scan_bridge(device_t dev, unsigned int max);
extern struct device_operations default_pciexp_ops_bus;
#endif /* DEVICE_PCIEXP_H */

12
src/include/device/pcix.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef DEVICE_PCIX_H
#define DEVICE_PCIX_H
/* (c) 2005 Linux Networx GPL see COPYING for details */
unsigned int pcix_scan_bus(struct bus *bus,
unsigned min_devfn, unsigned max_devfn, unsigned int max);
unsigned int pcix_scan_bridge(device_t dev, unsigned int max);
const char *pcix_speed(unsigned sstatus);
extern struct device_operations default_pcix_ops_bus;
#endif /* DEVICE_PCIX_H */

View File

@ -98,4 +98,7 @@ extern void search_global_resources(
unsigned long type_mask, unsigned long type,
resource_search_t search, void *gp);
#define RESOURCE_TYPE_MAX 20
extern const char *resource_type(struct resource *resource);
#endif /* RESOURCE_H */

View File

@ -4,11 +4,13 @@
#ifndef ASSEMBLY
#if HAVE_FALLBACK_BOOT == 1
void boot_successful(void);
void set_boot_successful(void);
#else
#define boot_successful()
#define set_boot_successful()
#endif
void boot_successful(void);
#endif /* ASSEMBLY */
#define RTC_BOOT_BYTE 48

View File

@ -0,0 +1,10 @@
#ifndef PART_WATCHDOG_H
#define PART_WATCHDOG_H
#if USE_WATCHDOG_ON_BOOT == 1
void watchdog_off(void);
#else
#define watchdog_off()
#endif
#endif /* PART_WATCHDOG_H */

View File

@ -9,9 +9,7 @@ object memcmp.o
object memmove.o
object malloc.o
object delay.o
if HAVE_FALLBACK_BOOT
object fallback_boot.o
end
object fallback_boot.o
object compute_ip_checksum.o
object version.o
# Force version.o to recompile every time

View File

@ -4,16 +4,19 @@
#include <console/console.h>
#endif
/* Assume 8 bits per byte */
#define CHAR_BIT 8
unsigned long log2(unsigned long x)
{
// assume 8 bits per byte.
unsigned long i = 1 << (sizeof(x)*8 - 1);
unsigned long pow = sizeof(x) * 8 - 1;
unsigned long i = 1ULL << (sizeof(x)* CHAR_BIT - 1ULL);
unsigned long pow = sizeof(x) * CHAR_BIT - 1ULL;
if (! x) {
#ifdef DEBUG_LOG2
printk_warning("%s called with invalid parameter of 0\n",
__FUNCTION__);
__func__);
#endif
return -1;
}

View File

@ -1,9 +1,12 @@
#include <console/console.h>
#include <part/fallback_boot.h>
#include <part/watchdog.h>
#include <pc80/mc146818rtc.h>
#include <arch/io.h>
void boot_successful(void)
#if HAVE_FALLBACK_BOOT == 1
void set_boot_successful(void)
{
/* Remember I succesfully booted by setting
* the initial boot direction
@ -23,3 +26,13 @@ void boot_successful(void)
byte &= 0x0f;
outb(byte, RTC_PORT(1));
}
#endif
void boot_successful(void)
{
/* Remember this was a successful boot */
set_boot_successful();
/* turn off the boot watchdog */
watchdog_off();
}

View File

@ -45,6 +45,7 @@ arch i386 end
driver mainboard.o
if HAVE_MP_TABLE object mptable.o end
if HAVE_PIRQ_TABLE object irq_tables.o end
object reset.o
## ATI Rage XL framebuffering graphics driver
dir /drivers/ati/ragexl
@ -129,7 +130,7 @@ mainboardinit cpu/x86/mmx/disable_mmx.inc
dir /pc80
config chip.h
# config for arima/hdama
# config for Iwill/DK8S2
chip northbridge/amd/amdk8/root_complex
device pci_domain 0 on
chip northbridge/amd/amdk8
@ -189,7 +190,7 @@ chip northbridge/amd/amdk8/root_complex
end
device pci 1.1 on end
device pci 1.2 on end
device pci 1.3 on end
device pci 1.3 on end
device pci 1.5 off end
device pci 1.6 off end
end
@ -208,7 +209,7 @@ chip northbridge/amd/amdk8/root_complex
device pci 19.2 on end
device pci 19.3 on end
end
end
end
device apic_cluster 0 on
chip cpu/amd/socket_940
device apic 0 on end

View File

@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -75,13 +72,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=1
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 0);
}

View File

@ -45,6 +45,7 @@ arch i386 end
driver mainboard.o
if HAVE_MP_TABLE object mptable.o end
if HAVE_PIRQ_TABLE object irq_tables.o end
object reset.o
##
## Romcc output

View File

@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -75,13 +72,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=1
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 0);
}

View File

@ -41,6 +41,7 @@ arch i386 end
driver mainboard.o
if HAVE_MP_TABLE object mptable.o end
if HAVE_PIRQ_TABLE object irq_tables.o end
object reset.o
##
## Romcc output

View File

@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -74,13 +71,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=1
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 2);
}

View File

@ -41,6 +41,7 @@ arch i386 end
driver mainboard.o
if HAVE_MP_TABLE object mptable.o end
if HAVE_PIRQ_TABLE object irq_tables.o end
object reset.o
##
## Romcc output

View File

@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -73,13 +70,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=1
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 2);
}

View File

@ -42,6 +42,7 @@ 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 acpi_tables.o end
object reset.o
##
## Romcc output

View File

@ -4,9 +4,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -75,13 +72,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=1
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 0);
}

View File

@ -29,7 +29,7 @@ default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
## 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_SIZE=131072
default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
##
@ -45,13 +45,13 @@ arch i386 end
driver mainboard.o
if HAVE_MP_TABLE object mptable.o end
if HAVE_PIRQ_TABLE object irq_tables.o end
#object reset.o
object reset.o
##
## Romcc output
##
makerule ./failover.E
depends "$(MAINBOARD)/failover.c ./romcc"
depends "$(MAINBOARD)/failover.c ./romcc"
action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
end
@ -60,11 +60,11 @@ makerule ./failover.inc
action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
end
makerule ./auto.E
depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
makerule ./auto.E
depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
action "./romcc -E -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
end
makerule ./auto.inc
makerule ./auto.inc
depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
action "./romcc -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
end
@ -129,61 +129,122 @@ config chip.h
# config for arima/hdama
chip northbridge/amd/amdk8/root_complex
device apic_cluster 0 on
chip cpu/amd/socket_940
device apic 0 on end
end
chip cpu/amd/socket_940
device apic 1 on end
end
end
device pci_domain 0 on
chip northbridge/amd/amdk8
device pci 18.0 on # northbridge
# devices on link 0, link 0 == LDT 0
chip southbridge/amd/amd8131
# the on/off keyword is mandatory
device pci 0.0 on end # PCIX bridge
device pci 0.0 on # PCIX bridge
## On board NIC A
#chip drivers/generic/generic
# device pci 3.0 on
# irq 0 = 0x13
# end
#end
## On board NIC B
#chip drivers/generic/generic
# device pci 4.0 on
# irq 0 = 0x13
# end
#end
## PCI Slot 3
#chip drivers/generic/generic
# device pci 1.0 on
# irq 0 = 0x11
# irq 1 = 0x12
# irq 2 = 0x13
# irq 3 = 0x10
# end
#end
## PCI Slot 4
#chip drivers/generic/generic
# device pci 2.0 on
# irq 0 = 0x12
# irq 1 = 0x13
# irq 2 = 0x10
# irq 3 = 0x11
# end
#end
end
device pci 0.1 on end # IOAPIC
device pci 1.0 on end # PCIX bridge
device pci 1.1 on end # IOAPIC
device pci 1.0 on # PCIX bridge
## PCI Slot 1
#chip drivers/generic/generic
# device pci 1.0 on
# irq 0 = 0x11
# irq 1 = 0x12
# irq 2 = 0x13
# irq 3 = 0x10
# end
#end
## PCI Slot 2
#chip drivers/generic/generic
# device pci 2.0 on
# irq 0 = 0x12
# irq 1 = 0x13
# irq 2 = 0x10
# irq 3 = 0x11
# end
#end
end
device pci 1.1 on end # IOAPIC
end
chip southbridge/amd/amd8111
# this "device pci 0.0" is the parent of the next one
# PCI bridge
device pci 0.0 on
device pci 0.0 on end # USB0
device pci 0.1 on end # USB1
device pci 0.2 off end # USB 2.0
device pci 1.0 off end # LAN
device pci 0.0 on end # USB0
device pci 0.1 on end # USB1
device pci 0.2 off end # USB 2.0
device pci 1.0 off end # LAN
chip drivers/pci/onboard
device pci 6.0 on end # ATI Rage XL
register "rom_address" = "0xfff80000"
end
## PCI Slot 5 (correct?)
#chip drivers/generic/generic
# device pci 5.0 on
# irq 0 = 0x11
# irq 1 = 0x12
# irq 2 = 0x13
# irq 3 = 0x10
# end
#end
## PCI Slot 6 (correct?)
#chip drivers/generic/generic
# device pci 4.0 on
# irq 0 = 0x10
# irq 1 = 0x11
# irq 2 = 0x12
# irq 3 = 0x13
# end
#end
end
# LPC bridge
device pci 1.0 on
chip superio/NSC/pc87360
device pnp 2e.0 off # Floppy
device pnp 2e.0 off # Floppy
io 0x60 = 0x3f0
irq 0x70 = 6
drq 0x74 = 2
end
device pnp 2e.1 off # Parallel Port
device pnp 2e.1 off # Parallel Port
io 0x60 = 0x378
irq 0x70 = 7
end
device pnp 2e.2 off # Com 2
device pnp 2e.2 off # Com 2
io 0x60 = 0x2f8
irq 0x70 = 3
end
device pnp 2e.3 on # Com 1
device pnp 2e.3 on # Com 1
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.4 off end # SWC
device pnp 2e.5 off end # Mouse
device pnp 2e.6 on # Keyboard
device pnp 2e.6 on # Keyboard
io 0x60 = 0x60
io 0x62 = 0x64
irq 0x70 = 1
@ -239,7 +300,7 @@ chip northbridge/amd/amdk8/root_complex
register "ide0_enable" = "1"
register "ide1_enable" = "1"
end
end # device pci 18.0
end # device pci 18.0
device pci 18.0 on end # LDT1
device pci 18.0 on end # LDT2
@ -255,6 +316,14 @@ chip northbridge/amd/amdk8/root_complex
device pci 19.2 on end
device pci 19.3 on end
end
end
device apic_cluster 0 on
chip cpu/amd/socket_940
device apic 0 on end
end
chip cpu/amd/socket_940
device apic 1 on end
end
end
end

View File

@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -79,13 +76,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=1
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -11,6 +11,7 @@
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
#include "northbridge/amd/amdk8/cpu_rev.c"
#include "northbridge/amd/amdk8/incoherent_ht.c"
#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
@ -18,28 +19,59 @@
#include "lib/delay.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "northbridge/amd/amdk8/reset_test.c"
#include "northbridge/amd/amdk8/debug.c"
#include "northbridge/amd/amdk8/cpu_rev.c"
#include "superio/NSC/pc87360/pc87360_early_serial.c"
#include "cpu/amd/mtrr/amd_earlymtrr.c"
#include "cpu/x86/bist.h"
#define SERIAL_DEV PNP_DEV(0x2e, PC87360_SP1)
/* Look up a which bus a given node/link combination is on.
* return 0 when we can't find the answer.
*/
static unsigned node_link_to_bus(unsigned node, unsigned link)
{
unsigned reg;
for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
unsigned config_map;
config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg);
if ((config_map & 3) != 3) {
continue;
}
if ((((config_map >> 4) & 7) == node) &&
(((config_map >> 8) & 3) == link))
{
return (config_map >> 16) & 0xff;
}
}
return 0;
}
static void hard_reset(void)
{
set_bios_reset();
device_t dev;
/* Find the device */
dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3);
/* enable cf9 */
pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1);
pci_write_config8(dev, 0x41, 0xf1);
/* reset */
set_bios_reset();
outb(0x0e, 0x0cf9);
}
static void soft_reset(void)
{
device_t dev;
/* Find the device */
dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0);
/* Reset */
set_bios_reset();
pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1);
pci_write_config8(dev, 0x47, 1);
}
/*
@ -128,6 +160,7 @@ static inline int spd_read_byte(unsigned device, unsigned address)
#include "northbridge/amd/amdk8/coherent_ht.c"
#include "sdram/generic_sdram.c"
#include "northbridge/amd/amdk8/resourcemap.c"
#include "debug.c"
#define FIRST_CPU 1
#define SECOND_CPU 1
@ -160,13 +193,14 @@ static void main(unsigned long bist)
};
int needs_reset;
unsigned nodeid;
if (bist == 0) {
unsigned nodeid;
/* Skip this if there was a built in self test failure */
amd_early_mtrr_init();
enable_lapic();
init_timer();
nodeid = lapicid() & 0xf;
/* Has this cpu already booted? */
if (cpu_init_detected(nodeid)) {
asm volatile ("jmp __cpu_reset");
@ -191,13 +225,12 @@ static void main(unsigned long bist)
print_info("ht reset -\r\n");
soft_reset();
}
#if 0
print_pci_devices();
#endif
enable_smbus();
#if 0
dump_spd_registers(&cpu[0]);
dump_spd_registers(sizeof(cpu)/sizeof(cpu[0]), cpu);
#endif
memreset_setup();
@ -205,6 +238,8 @@ static void main(unsigned long bist)
#if 0
dump_pci_devices();
#endif
#if 0
dump_pci_device(PCI_DEV(0, 0x18, 2));
#endif

View File

@ -0,0 +1,143 @@
static void print_debug_pci_dev(unsigned dev)
{
print_debug("PCI: ");
print_debug_hex8((dev >> 16) & 0xff);
print_debug_char(':');
print_debug_hex8((dev >> 11) & 0x1f);
print_debug_char('.');
print_debug_hex8((dev >> 8) & 7);
}
static void print_pci_devices(void)
{
device_t dev;
for(dev = PCI_DEV(0, 0, 0);
dev <= PCI_DEV(0, 0x1f, 0x7);
dev += PCI_DEV(0,0,1)) {
uint32_t id;
id = pci_read_config32(dev, PCI_VENDOR_ID);
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
continue;
}
print_debug_pci_dev(dev);
print_debug("\r\n");
}
}
static void dump_pci_device(unsigned dev)
{
int i;
print_debug_pci_dev(dev);
print_debug("\r\n");
for(i = 0; i <= 255; i++) {
unsigned char val;
if ((i & 0x0f) == 0) {
print_debug_hex8(i);
print_debug_char(':');
}
val = pci_read_config8(dev, i);
print_debug_char(' ');
print_debug_hex8(val);
if ((i & 0x0f) == 0x0f) {
print_debug("\r\n");
}
}
}
static void dump_pci_devices(void)
{
device_t dev;
for(dev = PCI_DEV(0, 0, 0);
dev <= PCI_DEV(0, 0x1f, 0x7);
dev += PCI_DEV(0,0,1)) {
uint32_t id;
id = pci_read_config32(dev, PCI_VENDOR_ID);
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
continue;
}
dump_pci_device(dev);
}
}
static void dump_spd_registers(int controllers, const struct mem_controller *ctrl)
{
int n;
for(n = 0; n < controllers; n++) {
int i;
print_debug("\r\n");
activate_spd_rom(&ctrl[n]);
for(i = 0; i < 4; i++) {
unsigned device;
device = ctrl[n].channel0[i];
if (device) {
int j;
print_debug("dimm: ");
print_debug_hex8(n);
print_debug_char('.');
print_debug_hex8(i);
print_debug(".0: ");
print_debug_hex8(device);
for(j = 0; j < 256; j++) {
int status;
unsigned char byte;
if ((j & 0xf) == 0) {
print_debug("\r\n");
print_debug_hex8(j);
print_debug(": ");
}
status = spd_read_byte(device, j);
if (status < 0) {
print_debug("bad device\r\n");
break;
}
#if 0
byte = status & 0xff;
print_debug_hex8(byte);
#else
print_debug_hex8(status & 0xff);
#endif
print_debug_char(' ');
}
print_debug("\r\n");
}
device = ctrl[n].channel1[i];
if (device) {
int j;
print_debug("dimm: ");
print_debug_hex8(n);
print_debug_char('.');
print_debug_hex8(i);
print_debug(".1: ");
print_debug_hex8(device);
for(j = 0; j < 256; j++) {
int status;
unsigned char byte;
if ((j & 0xf) == 0) {
print_debug("\r\n");
print_debug_hex8(j);
print_debug(": ");
}
status = spd_read_byte(device, j);
if (status < 0) {
print_debug("bad device\r\n");
break;
}
#if 0
byte = status & 0xff;
print_debug_hex8(byte);
#else
print_debug_hex8(status & 0xff);
#endif
print_debug_char(' ');
}
print_debug("\r\n");
}
}
}
}

View File

@ -4,6 +4,40 @@
#include <string.h>
#include <stdint.h>
static unsigned node_link_to_bus(unsigned node, unsigned link)
{
device_t dev;
unsigned reg;
dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
if (!dev) {
return 0;
}
for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
uint32_t config_map;
unsigned dst_node;
unsigned dst_link;
unsigned bus_base;
config_map = pci_read_config32(dev, reg);
if ((config_map & 3) != 3) {
continue;
}
dst_node = (config_map >> 4) & 7;
dst_link = (config_map >> 8) & 3;
bus_base = (config_map >> 16) & 0xff;
#if 0
printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
dst_node, dst_link, bus_base,
reg, config_map);
#endif
if ((dst_node == node) && (dst_link == link))
{
return bus_base;
}
}
return 0;
}
void *smp_write_config_table(void *v)
{
static const char sig[4] = "PCMP";
@ -12,6 +46,7 @@ void *smp_write_config_table(void *v)
struct mp_config_table *mc;
unsigned char bus_num;
unsigned char bus_isa;
unsigned char bus_chain_0;
unsigned char bus_8131_1;
unsigned char bus_8131_2;
unsigned char bus_8111_1;
@ -38,8 +73,15 @@ void *smp_write_config_table(void *v)
{
device_t dev;
/* HT chain 0 */
bus_chain_0 = node_link_to_bus(0, 0);
if (bus_chain_0 == 0) {
printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
bus_chain_0 = 1;
}
/* 8111 */
dev = dev_find_slot(1, PCI_DEVFN(0x03,0));
dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0));
if (dev) {
bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
@ -52,7 +94,7 @@ void *smp_write_config_table(void *v)
bus_isa = 5;
}
/* 8131-1 */
dev = dev_find_slot(1, PCI_DEVFN(0x01,0));
dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
if (dev) {
bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
@ -63,7 +105,7 @@ void *smp_write_config_table(void *v)
bus_8131_1 = 2;
}
/* 8131-2 */
dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
if (dev) {
bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
@ -87,7 +129,7 @@ void *smp_write_config_table(void *v)
device_t dev;
struct resource *res;
/* 8131 apic 3 */
dev = dev_find_slot(1, PCI_DEVFN(0x01,1));
dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,1));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
@ -95,7 +137,7 @@ void *smp_write_config_table(void *v)
}
}
/* 8131 apic 4 */
dev = dev_find_slot(1, PCI_DEVFN(0x02,1));
dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,1));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 0);
}

View File

@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -72,13 +69,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=0
##
## Funky hard reset implementation
##
# default HARD_RESET_BUS=1
# default HARD_RESET_DEVICE=4
# default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -45,6 +45,7 @@ arch i386 end
driver mainboard.o
if HAVE_MP_TABLE object mptable.o end
if HAVE_PIRQ_TABLE object irq_tables.o end
object reset.o
##
## Romcc output

View File

@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -74,13 +71,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=1
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 1);
}

View File

@ -0,0 +1,213 @@
##
## Only use the option table in a normal image
##
default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
##
## Compute the location and size of where this firmware image
## (linuxBIOS 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 linuxBIOS bootloader.
##
default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
##
## Compute where this copy of linuxBIOS will start in the boot rom
##
default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
##
## Compute a range of ROM that can cached to speed up linuxBIOS,
## 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=131072
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
object reset.o
##
## Romcc output
##
makerule ./failover.E
depends "$(MAINBOARD)/failover.c ./romcc"
action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
end
makerule ./failover.inc
depends "$(MAINBOARD)/failover.c ./romcc"
action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
end
makerule ./auto.E
depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
action "./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
end
makerule ./auto.inc
depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
action "./romcc -mcpu=p4 -fno-simplify-phi -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
end
##
## Build our 16 bit and 32 bit linuxBIOS 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 linuxBIOS 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
### Should this be in the northbridge code?
mainboardinit arch/i386/lib/cpu_reset.inc
##
## Include an id string (For safe flashing)
##
mainboardinit arch/i386/lib/id.inc
ldscript /arch/i386/lib/id.lds
###
### This is the early phase of linuxBIOS startup
### Things are delicate and we test to see if we should
### failover to another image.
###
if USE_FALLBACK_IMAGE
ldscript /arch/i386/lib/failover.lds
mainboardinit ./failover.inc
end
###
### O.k. We aren't just an intermediary anymore!
###
##
## Setup RAM
##
mainboardinit cpu/x86/fpu/enable_fpu.inc
mainboardinit cpu/x86/mmx/enable_mmx.inc
mainboardinit cpu/x86/sse/enable_sse.inc
mainboardinit ./auto.inc
mainboardinit cpu/x86/sse/disable_sse.inc
mainboardinit cpu/x86/mmx/disable_mmx.inc
##
## Include the secondary Configuration files
##
dir /pc80
config chip.h
chip northbridge/intel/E7520
device pci_domain 0 on
device pci 00.0 on end
device pci 00.1 on end
device pci 01.0 on end
device pci 02.0 on
chip southbridge/intel/pxhd # pxhd1
device pci 00.0 on end
device pci 00.1 on end
device pci 00.2 on
chip drivers/generic/generic
device pci 04.0 on end
device pci 04.1 on end
end
end
device pci 00.3 on end
end
end
device pci 06.0 on end
chip southbridge/intel/ich5r # ich5r
device pci 1d.0 on end
device pci 1d.1 on end
device pci 1d.2 on end
device pci 1d.3 off end
device pci 1d.7 on end
device pci 1e.0 on
chip drivers/ati/ragexl
device pci 0c.0 on end
end
end
device pci 1f.0 on
chip superio/NSC/pc87427
device pnp 2e.0 off end
device pnp 2e.2 on
# io 0x60 = 0x2f8
# irq 0x70 = 3
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.3 on
# io 0x60 = 0x3f8
# irq 0x70 = 4
io 0x60 = 0x2f8
irq 0x70 = 3
end
device pnp 2e.4 off end
device pnp 2e.5 off end
device pnp 2e.6 on
io 0x60 = 0x60
io 0x62 = 0x64
irq 0x70 = 1
end
device pnp 2e.7 off end
device pnp 2e.9 off end
device pnp 2e.a off end
device pnp 2e.f on end
device pnp 2e.10 off end
device pnp 2e.14 off end
end
end
device pci 1f.1 on end
device pci 1f.2 off end
device pci 1f.3 on end
device pci 1f.5 off end
device pci 1f.6 off end
register "gpio[40]" = "ICH5R_GPIO_USE_AS_GPIO"
register "gpio[48]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_OUTPUT | ICH5R_GPIO_LVL_LOW"
register "gpio[41]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_INPUT"
end
end
device apic_cluster 0 on
chip cpu/intel/socket_mPGA604_800Mhz # cpu 0
device apic 0 on end
end
chip cpu/intel/socket_mPGA604_800Mhz # cpu 1
device apic 6 on end
end
end
end

View File

@ -0,0 +1,242 @@
uses HAVE_MP_TABLE
uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_LOGICAL_CPUS
uses CONFIG_MAX_CPUS
uses CONFIG_IOAPIC
uses CONFIG_SMP
uses FALLBACK_SIZE
uses ROM_SIZE
uses ROM_SECTION_SIZE
uses ROM_IMAGE_SIZE
uses ROM_SECTION_SIZE
uses ROM_SECTION_OFFSET
uses CONFIG_ROM_STREAM
uses CONFIG_ROM_STREAM_START
uses PAYLOAD_SIZE
uses _ROMBASE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
uses STACK_SIZE
uses HEAP_SIZE
uses USE_OPTION_TABLE
uses LB_CKS_RANGE_START
uses LB_CKS_RANGE_END
uses LB_CKS_LOC
uses MAINBOARD
uses MAINBOARD_PART_NUMBER
uses MAINBOARD_VENDOR
uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
uses LINUXBIOS_EXTRA_VERSION
uses CONFIG_UDELAY_TSC
uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
uses _RAMBASE
uses CONFIG_GDB_STUB
uses CONFIG_CONSOLE_SERIAL8250
uses TTYS0_BAUD
uses TTYS0_BASE
uses TTYS0_LCS
uses DEFAULT_CONSOLE_LOGLEVEL
uses MAXIMUM_CONSOLE_LOGLEVEL
uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
uses CONFIG_CONSOLE_BTEXT
uses CC
uses HOSTCC
uses CROSS_COMPILE
uses OBJCOPY
uses MAX_REBOOT_CNT
uses USE_WATCHDOG_ON_BOOT
###
### Build options
###
##
## Because we do the stutter start we need more attempts
##
default MAX_REBOOT_CNT=8
##
## Use the watchdog to break out of a lockup condition
##
default USE_WATCHDOG_ON_BOOT=1
##
## ROM_SIZE is the size of boot ROM that this board will use.
##
default ROM_SIZE=2097152
##
## Build code for the fallback boot
##
default HAVE_FALLBACK_BOOT=1
##
## Delay timer options
## Use timer2
##
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=9
##
## Build code to export an x86 MP table
## Useful for specifying IRQ routing values
##
default HAVE_MP_TABLE=1
##
## Build code to export a CMOS option table
##
default HAVE_OPTION_TABLE=1
##
## Move the default LinuxBIOS cmos range off of AMD RTC registers
##
default LB_CKS_RANGE_START=49
default LB_CKS_RANGE_END=122
default LB_CKS_LOC=123
##
## Build code for SMP support
## Only worry about 2 micro processors
##
default CONFIG_SMP=1
default CONFIG_MAX_CPUS=4
default CONFIG_LOGICAL_CPUS=0
##
## Build code to setup a generic IOAPIC
##
default CONFIG_IOAPIC=1
##
## Clean up the motherboard id strings
##
default MAINBOARD_PART_NUMBER="SE7520JR22D"
default MAINBOARD_VENDOR= "Intel"
default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x8086
default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x1079
#default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x3437
###
### LinuxBIOS layout values
###
## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
default ROM_IMAGE_SIZE = 65536
##
## Use a small 8K stack
##
default STACK_SIZE=0x2000
##
## Use a small 32K heap
##
default HEAP_SIZE=0x8000
###
### Compute the location and size of where this firmware image
### (linuxBIOS plus bootloader) will live in the boot rom chip.
###
default FALLBACK_SIZE=131072
##
## LinuxBIOS C code runs at this location in RAM
##
default _RAMBASE=0x00004000
##
## Load the payload from the ROM
##
default CONFIG_ROM_STREAM=1
###
### Defaults of options that you may want to override in the target config file
###
##
## The default compiler
##
default CC="$(CROSS_COMPILE)gcc -m32"
default HOSTCC="gcc"
##
## 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 linuxBIOS 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=8
## At a maximum only compile in this level of debugging
default MAXIMUM_CONSOLE_LOGLEVEL=8
##
## Select power on after power fail setting
default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
##
## Don't enable the btext console
##
default CONFIG_CONSOLE_BTEXT=0
### End Options.lb
end

View File

@ -0,0 +1,150 @@
#define ASSEMBLY 1
#include <stdint.h>
#include <device/pci_def.h>
#include <arch/io.h>
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <cpu/x86/lapic.h>
#include "option_table.h"
#include "pc80/mc146818rtc_early.c"
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
#include "southbridge/intel/ich5r/ich5r_early_smbus.c"
#include "northbridge/intel/E7520/raminit.h"
#include "superio/NSC/pc87427/pc87427.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "watchdog.c"
#include "reset.c"
#include "power_reset_check.c"
#include "jarrell_fixups.c"
#include "superio/NSC/pc87427/pc87427_early_init.c"
#include "northbridge/intel/E7520/memory_initialized.c"
#include "cpu/x86/bist.h"
#define SIO_GPIO_BASE 0x680
#define SIO_XBUS_BASE 0x4880
#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, PC87427_SP2)
#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, PC87427_SP1)
#define DEVPRES_CONFIG (DEVPRES_D1F0 | DEVPRES_D2F0 | DEVPRES_D6F0)
#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
/* Beta values: 0x00090800 */
/* Silver values: 0x000a0900 */
#define RECVENA_CONFIG 0x000a090a
#define RECVENB_CONFIG 0x000a090a
#define DIMM_MAP_LOGICAL 0x0124
static inline void activate_spd_rom(const struct mem_controller *ctrl)
{
/* nothing to do */
}
static inline int spd_read_byte(unsigned device, unsigned address)
{
return smbus_read_byte(device, address);
}
#include "northbridge/intel/E7520/raminit.c"
#include "sdram/generic_sdram.c"
#include "debug.c"
static void main(unsigned long bist)
{
/*
*
*
*/
static const struct mem_controller mch[] = {
{
.node_id = 0,
.f0 = PCI_DEV(0, 0x00, 0),
.f1 = PCI_DEV(0, 0x00, 1),
.f2 = PCI_DEV(0, 0x00, 2),
.f3 = PCI_DEV(0, 0x00, 3),
.channel0 = { (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, 0 },
.channel1 = { (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, 0 },
}
};
if (bist == 0) {
/* Skip this if there was a built in self test failure */
early_mtrr_init();
if (memory_initialized()) {
asm volatile ("jmp __cpu_reset");
}
}
/* Setup the console */
pc87427_disable_dev(CONSOLE_SERIAL_DEV);
pc87427_disable_dev(HIDDEN_SERIAL_DEV);
pc87427_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
/* Enable Serial 2 lines instead of GPIO */
outb(0x2c, 0x2e);
outb((inb(0x2f) & (~1<<1)), 0x2f);
uart_init();
console_init();
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
pc87427_enable_dev(PC87427_GPIO_DEV, SIO_GPIO_BASE);
pc87427_enable_dev(PC87427_XBUS_DEV, SIO_XBUS_BASE);
xbus_cfg(PC87427_XBUS_DEV);
/* MOVE ME TO A BETTER LOCATION !!! */
/* config LPC decode for flash memory access */
device_t dev;
dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
if (dev == PCI_DEV_INVALID) {
die("Missing ich5?");
}
pci_write_config32(dev, 0xe8, 0x00000000);
pci_write_config8(dev, 0xf0, 0x00);
#if 0
print_pci_devices();
#endif
enable_smbus();
#if 0
// dump_spd_registers(&cpu[0]);
int i;
for(i = 0; i < 1; i++) {
dump_spd_registers();
}
#endif
disable_watchdogs();
power_down_reset_check();
// dump_ipmi_registers();
mainboard_set_e7520_leds();
sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
ich5_watchdog_on();
#if 0
dump_pci_devices();
#endif
#if 0
dump_pci_device(PCI_DEV(0, 0x00, 0));
dump_bar14(PCI_DEV(0, 0x00, 0));
#endif
#if 0 // temporarily disabled
/* Check the first 1M */
// ram_check(0x00000000, 0x000100000);
// ram_check(0x00000000, 0x000a0000);
ram_check(0x00100000, 0x01000000);
/* check the first 1M in the 3rd Gig */
ram_check(0x30100000, 0x31000000);
#if 0
ram_check(0x00000000, 0x02000000);
#endif
#endif
#if 0
while(1) {
hlt();
}
#endif
}

View File

@ -0,0 +1,5 @@
struct chip_operations mainboard_intel_jarrell_ops;
struct mainboard_intel_jarrell_config {
int nothing;
};

View File

@ -0,0 +1,82 @@
entries
#start-bit length config config-ID name
#0 8 r 0 seconds
#8 8 r 0 alarm_seconds
#16 8 r 0 minutes
#24 8 r 0 alarm_minutes
#32 8 r 0 hours
#40 8 r 0 alarm_hours
#48 8 r 0 day_of_week
#56 8 r 0 day_of_month
#64 8 r 0 month
#72 8 r 0 year
#80 4 r 0 rate_select
#84 3 r 0 REF_Clock
#87 1 r 0 UIP
#88 1 r 0 auto_switch_DST
#89 1 r 0 24_hour_mode
#90 1 r 0 binary_values_enable
#91 1 r 0 square-wave_out_enable
#92 1 r 0 update_finished_enable
#93 1 r 0 alarm_interrupt_enable
#94 1 r 0 periodic_interrupt_enable
#95 1 r 0 disable_clock_updates
#96 288 r 0 temporary_filler
0 376 r 0 reserved_memory
376 1 e 1 power_up_watchdog
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
395 1 e 2 hyper_threading
397 1 e 1 pxhd_bus_speed_100
400 1 e 1 power_on_after_fail
412 4 e 6 debug_level
416 4 e 7 boot_first
420 4 e 7 boot_second
424 4 e 7 boot_third
428 4 h 0 boot_index
432 8 h 0 boot_countdown
728 256 h 0 user_data
984 16 h 0 check_sum
# Reserve the extended AMD configuration registers
1000 24 r 0 reserved_memory
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 983 984

View File

@ -0,0 +1,330 @@
#define SMBUS_MEM_DEVICE_START 0x50
#define SMBUS_MEM_DEVICE_END 0x57
#define SMBUS_MEM_DEVICE_INC 1
static void print_reg(unsigned char index)
{
unsigned char data;
outb(index, 0x2e);
data = inb(0x2f);
print_debug("0x");
print_debug_hex8(index);
print_debug(": 0x");
print_debug_hex8(data);
print_debug("\r\n");
return;
}
static void xbus_en(void)
{
/* select the XBUS function in the SIO */
outb(0x07, 0x2e);
outb(0x0f, 0x2f);
outb(0x30, 0x2e);
outb(0x01, 0x2f);
return;
}
static void setup_func(unsigned char func)
{
/* select the function in the SIO */
outb(0x07, 0x2e);
outb(func, 0x2f);
/* print out the regs */
print_reg(0x30);
print_reg(0x60);
print_reg(0x61);
print_reg(0x62);
print_reg(0x63);
print_reg(0x70);
print_reg(0x71);
print_reg(0x74);
print_reg(0x75);
return;
}
static void siodump(void)
{
int i;
unsigned char data;
print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n");
for (i=0x10; i<=0x2d; i++) {
print_reg((unsigned char)i);
}
#if 0
print_debug("\r\n*** XBUS REGISTERS ***\r\n");
setup_func(0x0f);
for (i=0xf0; i<=0xff; i++) {
print_reg((unsigned char)i);
}
print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n");
setup_func(0x03);
print_reg(0xf0);
print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n");
setup_func(0x02);
print_reg(0xf0);
#endif
print_debug("\r\n*** GPIO REGISTERS ***\r\n");
setup_func(0x07);
for (i=0xf0; i<=0xf8; i++) {
print_reg((unsigned char)i);
}
print_debug("\r\n*** GPIO VALUES ***\r\n");
data = inb(0x68a);
print_debug("\r\nGPDO 4: 0x");
print_debug_hex8(data);
data = inb(0x68b);
print_debug("\r\nGPDI 4: 0x");
print_debug_hex8(data);
print_debug("\r\n");
#if 0
print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n");
setup_func(0x0a);
print_reg(0xf0);
print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n");
setup_func(0x09);
print_reg(0xf0);
print_reg(0xf1);
print_debug("\r\n*** RTC REGISTERS ***\r\n");
setup_func(0x10);
print_reg(0xf0);
print_reg(0xf1);
print_reg(0xf3);
print_reg(0xf6);
print_reg(0xf7);
print_reg(0xfe);
print_reg(0xff);
print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n");
setup_func(0x14);
print_reg(0xf0);
#endif
return;
}
static void print_debug_pci_dev(unsigned dev)
{
print_debug("PCI: ");
print_debug_hex8((dev >> 16) & 0xff);
print_debug_char(':');
print_debug_hex8((dev >> 11) & 0x1f);
print_debug_char('.');
print_debug_hex8((dev >> 8) & 7);
}
static void print_pci_devices(void)
{
device_t dev;
for(dev = PCI_DEV(0, 0, 0);
dev <= PCI_DEV(0, 0x1f, 0x7);
dev += PCI_DEV(0,0,1)) {
uint32_t id;
id = pci_read_config32(dev, PCI_VENDOR_ID);
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
continue;
}
print_debug_pci_dev(dev);
print_debug("\r\n");
}
}
static void dump_pci_device(unsigned dev)
{
int i;
print_debug_pci_dev(dev);
print_debug("\r\n");
for(i = 0; i <= 255; i++) {
unsigned char val;
if ((i & 0x0f) == 0) {
print_debug_hex8(i);
print_debug_char(':');
}
val = pci_read_config8(dev, i);
print_debug_char(' ');
print_debug_hex8(val);
if ((i & 0x0f) == 0x0f) {
print_debug("\r\n");
}
}
}
static void dump_bar14(unsigned dev)
{
int i;
unsigned long bar;
print_debug("BAR 14 Dump\r\n");
bar = pci_read_config32(dev, 0x14);
for(i = 0; i <= 0x300; i+=4) {
#if 0
unsigned char val;
if ((i & 0x0f) == 0) {
print_debug_hex8(i);
print_debug_char(':');
}
val = pci_read_config8(dev, i);
#endif
if((i%4)==0) {
print_debug("\r\n");
print_debug_hex16(i);
print_debug_char(' ');
}
print_debug_hex32(read32(bar + i));
print_debug_char(' ');
}
print_debug("\r\n");
}
static void dump_pci_devices(void)
{
device_t dev;
for(dev = PCI_DEV(0, 0, 0);
dev <= PCI_DEV(0, 0x1f, 0x7);
dev += PCI_DEV(0,0,1)) {
uint32_t id;
id = pci_read_config32(dev, PCI_VENDOR_ID);
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
continue;
}
dump_pci_device(dev);
}
}
#if 0
static void dump_spd_registers(const struct mem_controller *ctrl)
{
int i;
print_debug("\r\n");
for(i = 0; i < 4; i++) {
unsigned device;
device = ctrl->channel0[i];
if (device) {
int j;
print_debug("dimm: ");
print_debug_hex8(i);
print_debug(".0: ");
print_debug_hex8(device);
for(j = 0; j < 256; j++) {
int status;
unsigned char byte;
if ((j & 0xf) == 0) {
print_debug("\r\n");
print_debug_hex8(j);
print_debug(": ");
}
status = smbus_read_byte(device, j);
if (status < 0) {
print_debug("bad device\r\n");
break;
}
byte = status & 0xff;
print_debug_hex8(byte);
print_debug_char(' ');
}
print_debug("\r\n");
}
device = ctrl->channel1[i];
if (device) {
int j;
print_debug("dimm: ");
print_debug_hex8(i);
print_debug(".1: ");
print_debug_hex8(device);
for(j = 0; j < 256; j++) {
int status;
unsigned char byte;
if ((j & 0xf) == 0) {
print_debug("\r\n");
print_debug_hex8(j);
print_debug(": ");
}
status = smbus_read_byte(device, j);
if (status < 0) {
print_debug("bad device\r\n");
break;
}
byte = status & 0xff;
print_debug_hex8(byte);
print_debug_char(' ');
}
print_debug("\r\n");
}
}
}
#endif
void dump_spd_registers(void)
{
unsigned device;
device = SMBUS_MEM_DEVICE_START;
while(device <= SMBUS_MEM_DEVICE_END) {
int status = 0;
int i;
print_debug("\r\n");
print_debug("dimm ");
print_debug_hex8(device);
for(i = 0; (i < 256) ; i++) {
unsigned char byte;
if ((i % 16) == 0) {
print_debug("\r\n");
print_debug_hex8(i);
print_debug(": ");
}
status = smbus_read_byte(device, i);
if (status < 0) {
print_debug("bad device: ");
print_debug_hex8(-status);
print_debug("\r\n");
break;
}
print_debug_hex8(status);
print_debug_char(' ');
}
device += SMBUS_MEM_DEVICE_INC;
print_debug("\n");
}
}
void dump_ipmi_registers(void)
{
unsigned device;
device = 0x42;
while(device <= 0x42) {
int status = 0;
int i;
print_debug("\r\n");
print_debug("ipmi ");
print_debug_hex8(device);
for(i = 0; (i < 8) ; i++) {
unsigned char byte;
status = smbus_read_byte(device, 2);
if (status < 0) {
print_debug("bad device: ");
print_debug_hex8(-status);
print_debug("\r\n");
break;
}
print_debug_hex8(status);
print_debug_char(' ');
}
device += SMBUS_MEM_DEVICE_INC;
print_debug("\n");
}
}

View File

@ -0,0 +1,46 @@
#define ASSEMBLY 1
#include <stdint.h>
#include <device/pci_def.h>
#include <device/pci_ids.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <cpu/x86/lapic.h>
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "pc80/mc146818rtc_early.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "northbridge/intel/E7520/memory_initialized.c"
static unsigned long main(unsigned long bist)
{
/* Did just the cpu reset? */
if (memory_initialized()) {
if (last_boot_normal()) {
goto normal_image;
} else {
goto cpu_reset;
}
}
/* This is the primary cpu how should I boot? */
else if (do_normal_boot()) {
goto normal_image;
}
else {
goto fallback_image;
}
normal_image:
asm volatile ("jmp __normal_image"
: /* outputs */
: "a" (bist) /* inputs */
: /* clobbers */
);
cpu_reset:
asm volatile ("jmp __cpu_reset"
: /* outputs */
: "a"(bist) /* inputs */
: /* clobbers */
);
fallback_image:
return bist;
}

View File

@ -0,0 +1,37 @@
/* PCI: Interrupt Routing Table found at 0x40114180 size = 320 */
#include <arch/pirq_routing.h>
const struct irq_routing_table intel_irq_routing_table = {
0x52495024, /* u32 signature */
0x0100, /* u16 version */
320, /* u16 Table size 32+(16*devices) */
0x00, /* u8 Bus 0 */
0xf8, /* u8 Device 1, Function 0 */
0x0000, /* u16 reserve IRQ for PCI */
0x8086, /* u16 Vendor */
0x24d0, /* Device ID */
0x00000000, /* u32 miniport_data */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0x38, /* u8 checksum - mod 256 checksum must give zero */
{ /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
{0x00, 0x08, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00},
{0x00, 0xf8, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00},
{0x00, 0xe8, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00, 0x00},
{0x02, 0x20, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00},
{0x03, 0x28, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00},
{0x04, 0x60, {{0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00},
{0x02, 0x08, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}}, 0x04, 0x00},
{0x02, 0x10, {{0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}, {0x60, 0xdcf8}}, 0x05, 0x00},
{0x02, 0x18, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0xdcf8}}, 0x06, 0x00},
{0x03, 0x08, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0xdcf8}}, 0x01, 0x00},
{0x03, 0x10, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x61, 0xdcf8}}, 0x02, 0x00},
{0x03, 0x18, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}}, 0x03, 0x00},
{0x00, 0x10, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00},
{0x00, 0x18, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00},
{0x00, 0x20, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00},
{0x00, 0x28, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00},
{0x00, 0x30, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00},
{0x00, 0x38, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00}
}
};

View File

@ -0,0 +1,123 @@
#include <arch/romcc_io.h>
static void mch_reset(void)
{
device_t dev;
unsigned long value, base;
dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
if (dev != PCI_DEV_INVALID) {
/* I/O space is always enables */
/* Set gpio base */
pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1);
base = ICH5_GPIOBASE;
/* Enable GPIO Bar */
value = pci_read_config32(dev, 0x5c);
value |= 0x10;
pci_write_config32(dev, 0x5c, value);
/* Set GPIO 19 mux to IO usage */
value = inl(base);
value |= (1 <<19);
outl(value, base);
/* Pull GPIO 19 low */
value = inl(base + 0x0c);
value &= ~(1 << 19);
outl(value, base + 0x0c);
}
return;
}
static void mainboard_set_e7520_pll(unsigned bits)
{
uint16_t gpio_index;
uint8_t data;
device_t dev;
/* currently only handle the Jarrell/PC87427 case */
dev = PC87427_GPIO_DEV;
pnp_set_logical_device(dev);
gpio_index = pnp_read_iobase(dev, 0x60);
/* select SIO GPIO port 4, pin 2 */
pnp_write_config(dev, PC87427_GPSEL, ((pnp_read_config(dev, PC87427_GPSEL) & 0x88) | 0x42));
/* set to push-pull, enable output */
pnp_write_config(dev, PC87427_GPCFG1, 0x03);
/* select SIO GPIO port 4, pin 4 */
pnp_write_config(dev, PC87427_GPSEL, ((pnp_read_config(dev, PC87427_GPSEL) & 0x88) | 0x44));
/* set to push-pull, enable output */
pnp_write_config(dev, PC87427_GPCFG1, 0x03);
/* set gpio 42,44 signal levels */
data = inb(gpio_index + PC87427_GPDO_4);
if ((data & 0x14) == (0xff & (((bits&2)?0:1)<<4 | ((bits&1)?0:1)<<2))) {
print_debug("set_pllsel: correct settings detected!\r\n");
return; /* settings already configured */
} else {
outb((data & 0xeb) | ((bits&2)?0:1)<<4 | ((bits&1)?0:1)<<2, gpio_index + PC87427_GPDO_4);
/* reset */
print_debug("set_pllsel: settings adjusted, now resetting...\r\n");
// hard_reset(); /* should activate a PCI_RST, which should reset MCH, but it doesn't seem to work ???? */
// mch_reset();
full_reset();
}
return;
}
static void mainboard_set_e7520_leds(void)
{
uint8_t cnt;
uint8_t data;
device_t dev;
/* currently only handle the Jarrell/PC87427 case */
dev = PC87427_GPIO_DEV;
pnp_set_logical_device(dev);
/* enable */
outb(0x30, 0x2e);
outb(0x01, 0x2f);
outb(0x2d, 0x2e);
outb(0x01, 0x2f);
/* Set auto mode for dimm leds and post */
outb(0xf0,0x2e);
outb(0x70,0x2f);
outb(0xf4,0x2e);
outb(0x30,0x2f);
outb(0xf5,0x2e);
outb(0x88,0x2f);
outb(0xf6,0x2e);
outb(0x00,0x2f);
outb(0xf7,0x2e);
outb(0x90,0x2f);
outb(0xf8,0x2e);
outb(0x00,0x2f);
/* Turn the leds off */
outb(0x00,0x88);
outb(0x00,0x90);
/* Disable the ports */
outb(0xf5,0x2e);
outb(0x00,0x2f);
outb(0xf7,0x2e);
outb(0x00,0x2f);
outb(0xf4,0x2e);
outb(0x00,0x2f);
return;
}

View File

@ -0,0 +1,13 @@
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <cpu/x86/msr.h>
#include <arch/io.h>
#include "chip.h"
struct chip_operations mainboard_intel_e7520_ops = {
CHIP_NAME("Intel Jarell mainboard ")
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,293 @@
#include <console/console.h>
#include <arch/smp/mpspec.h>
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
void *smp_write_config_table(void *v)
{
static const char sig[4] = "PCMP";
static const char oem[8] = "LNXI ";
static const char productid[12] = "SE7520JR20 ";
struct mp_config_table *mc;
unsigned char bus_num;
unsigned char bus_isa;
unsigned char bus_pxhd_1;
unsigned char bus_pxhd_2;
unsigned char bus_pxhd_3 = 0;
unsigned char bus_pxhd_4 = 0;
unsigned char bus_pxhd_x;
unsigned char bus_ich5r_1;
unsigned int bus_pxhd_id;
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);
{
device_t dev;
/* ich5r */
dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
if (dev) {
bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
bus_isa++;
}
else {
printk_debug("ERROR - could not find PCI 0:1f.0, using defaults\n");
bus_ich5r_1 = 4;
bus_isa = 5;
}
/* pxhd-1 */
dev = dev_find_slot(1, PCI_DEVFN(0x0,0));
if (dev) {
bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
}
else {
printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n");
bus_pxhd_1 = 2;
}
/* pxhd-2 */
dev = dev_find_slot(1, PCI_DEVFN(0x00,2));
if (dev) {
bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
}
else {
printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
bus_pxhd_2 = 3;
}
/* test for active riser with 2nd pxh device */
dev = dev_find_slot(0, PCI_DEVFN(0x06,0));
if (dev) {
bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
if(bus_pxhd_id == 0x35998086) {
bus_pxhd_x = pci_read_config8(dev, PCI_SECONDARY_BUS);
/* pxhd-3 */
dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x0,0));
if (dev) {
bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
if(bus_pxhd_id == 0x03298086) {
bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
}
}
/* pxhd-4 */
dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,2));
if (dev) {
bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
if(bus_pxhd_id == 0x032a8086) {
bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
}
}
}
}
}
/* define bus and isa numbers */
for(bus_num = 0; bus_num < bus_isa; bus_num++) {
smp_write_bus(mc, bus_num, "PCI ");
}
smp_write_bus(mc, bus_isa, "ISA ");
/* IOAPIC handling */
smp_write_ioapic(mc, 8, 0x20, 0xfec00000);
{
struct resource *res;
device_t dev;
/* pxhd apic 3 */
dev = dev_find_slot(1, PCI_DEVFN(0x00,1));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 0x09, 0x20, res->base);
}
}
else {
printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n");
}
/* pxhd apic 4 */
dev = dev_find_slot(1, PCI_DEVFN(0x00,3));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 0x0a, 0x20, res->base);
}
}
else {
printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n");
}
/* pxhd apic 5 */
if(bus_pxhd_3) { /* Active riser pxhd */
dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,1));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 0x0b, 0x20, res->base);
}
}
else {
printk_debug("ERROR - could not find IOAPIC PCI %d:00.1\n",bus_pxhd_x);
}
}
/* pxhd apic 6 */
if(bus_pxhd_4) { /* active riser pxhd */
dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,3));
if (dev) {
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 0x0c, 0x20, res->base);
}
}
else {
printk_debug("ERROR - could not find IOAPIC PCI %d:00.3\n",bus_pxhd_x);
}
}
}
/* ISA backward compatibility interrupts */
smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x00, 0x08, 0x00);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x01, 0x08, 0x01);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x00, 0x08, 0x02);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x03, 0x08, 0x03);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x04, 0x08, 0x04);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x06, 0x08, 0x06);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x08, 0x08, 0x08);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x09, 0x08, 0x09);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x0c, 0x08, 0x0c);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x0d, 0x08, 0x0d);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x0e, 0x08, 0x0e);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x0f, 0x08, 0x0f);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x0a, 0x08, 0x10);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x0b, 0x08, 0x11);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x0a, 0x08, 0x10);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x07, 0x08, 0x13);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x0b, 0x08, 0x12);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x05, 0x08, 0x17);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x0b, 0x08, 0x12);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x07, 0x08, 0x13);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x0b, 0x08, 0x11);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_isa, 0x0a, 0x08, 0x10);
/* Standard local interrupt assignments */
smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x00, MP_APIC_ALL, 0x00);
smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_isa, 0x00, MP_APIC_ALL, 0x01);
#warning "FIXME verify I have the irqs handled for all of the risers"
/* 2:3.0 PCI Slot 1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_1, (3<<2)|0, 0x9, 0x0);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_1, (3<<2)|1, 0x9, 0x3);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_1, (3<<2)|2, 0x9, 0x5);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_1, (3<<2)|3, 0x9, 0x4);
/* 3:7.0 PCI Slot 2 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_2, (7<<2)|0, 0xa, 0x4);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_2, (7<<2)|1, 0xa, 0x3);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_2, (7<<2)|2, 0xa, 0x2);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_2, (7<<2)|3, 0xa, 0x1);
/* PCI Slot 3 (if active riser) */
if(bus_pxhd_3) {
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_3, (1<<2)|0, 0xb, 0x0);
}
/* PCI Slot 4 (if active riser) */
if(bus_pxhd_4) {
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_4, (1<<2)|0, 0xc, 0x0);
}
/* Onboard SCSI 0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_1, (5<<2)|0, 0x9, 0x2);
/* Onboard SCSI 1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_1, (5<<2)|1, 0x9, 0x1);
/* Onboard NIC 0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_2, (4<<2)|0, 0xa, 0x6);
/* Onboard NIC 1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_pxhd_2, (4<<2)|1, 0xa, 0x7);
/* Onboard VGA */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
bus_ich5r_1, (12<<2)|0, 0x8, 0x11);
/* There is no extension information... */
/* 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,12 @@
static void power_down_reset_check(void)
{
uint8_t cmos;
cmos=cmos_read(RTC_BOOT_BYTE)>>4 ;
print_debug("Boot byte = ");
print_debug_hex8(cmos);
print_debug("\r\n");
if((cmos>2)&&(cmos&1)) full_reset();
}

View File

@ -0,0 +1,40 @@
#include <arch/io.h>
#include <device/pci_def.h>
#include <device/pci_ids.h>
#ifndef __ROMCC__
#include <device/device.h>
#define PCI_ID(VENDOR_ID, DEVICE_ID) \
((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
#define PCI_DEV_INVALID 0
static inline device_t pci_locate_device(unsigned pci_id, device_t from)
{
return dev_find_device(pci_id >> 16, pci_id & 0xffff, from);
}
#endif
void soft_reset(void)
{
outb(0x04, 0xcf9);
}
void hard_reset(void)
{
outb(0x02, 0xcf9);
outb(0x06, 0xcf9);
}
void full_reset(void)
{
device_t dev;
/* Enable power on after power fail... */
dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0);
if (dev != PCI_DEV_INVALID) {
unsigned byte;
byte = pci_read_config8(dev, 0xa4);
byte &= 0xfe;
pci_write_config8(dev, 0xa4, byte);
}
outb(0x0e, 0xcf9);
}

View File

@ -0,0 +1,138 @@
#include <device/pnp_def.h>
#define NSC_WD_DEV PNP_DEV(0x2e, 0xa)
#define NSC_WDBASE 0x600
#define ICH5_WDBASE 0x400
#define ICH5_GPIOBASE 0x500
static void disable_sio_watchdog(device_t dev)
{
/* FIXME move me somewhere more appropriate */
pnp_set_logical_device(dev);
pnp_set_enable(dev, 1);
pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE);
/* disable the sio watchdog */
outb(0, NSC_WDBASE + 0);
pnp_set_enable(dev, 0);
}
static void disable_ich5_watchdog(void)
{
/* FIXME move me somewhere more appropriate */
device_t dev;
unsigned long value, base;
dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
if (dev == PCI_DEV_INVALID) {
die("Missing ich5?");
}
/* Enable I/O space */
value = pci_read_config16(dev, 0x04);
value |= (1 << 10);
pci_write_config16(dev, 0x04, value);
/* Set and enable acpibase */
pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
pci_write_config8(dev, 0x44, 0x10);
base = ICH5_WDBASE + 0x60;
/* Set bit 11 in TCO1_CNT */
value = inw(base + 0x08);
value |= 1 << 11;
outw(value, base + 0x08);
/* Clear TCO timeout status */
outw(0x0008, base + 0x04);
outw(0x0002, base + 0x06);
}
static void disable_jarell_frb3(void)
{
device_t dev;
unsigned long value, base;
dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
if (dev == PCI_DEV_INVALID) {
die("Missing ich5?");
}
/* Enable I/O space */
value = pci_read_config16(dev, 0x04);
value |= (1 << 0);
pci_write_config16(dev, 0x04, value);
/* Set gpio base */
pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1);
base = ICH5_GPIOBASE;
/* Enable GPIO Bar */
value = pci_read_config32(dev, 0x5c);
value |= 0x10;
pci_write_config32(dev, 0x5c, value);
/* Configure GPIO 48 and 40 as GPIO */
value = inl(base + 0x30);
value |= (1 << 16) | ( 1 << 8);
outl(value, base + 0x30);
/* Configure GPIO 48 as Output */
value = inl(base + 0x34);
value &= ~(1 << 16);
outl(value, base + 0x34);
/* Toggle GPIO 48 high to low */
value = inl(base + 0x38);
value |= (1 << 16);
outl(value, base + 0x38);
value &= ~(1 << 16);
outl(value, base + 0x38);
}
static void disable_watchdogs(void)
{
disable_sio_watchdog(NSC_WD_DEV);
disable_ich5_watchdog();
disable_jarell_frb3();
print_debug("Watchdogs disabled\r\n");
}
static void ich5_watchdog_on(void)
{
device_t dev;
unsigned long value, base;
unsigned char byte;
/* check cmos options */
byte = cmos_read(RTC_BOOT_BYTE-1);
if(!(byte & 1)) return; /* no boot watchdog */
byte = cmos_read(RTC_BOOT_BYTE);
if(!(byte & 2)) return; /* fallback so ignore */
dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
if (dev == PCI_DEV_INVALID) {
die("Missing ich5?");
}
/* Enable I/O space */
value = pci_read_config16(dev, 0x04);
value |= (1 << 10);
pci_write_config16(dev, 0x04, value);
/* Set and enable acpibase */
pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
pci_write_config8(dev, 0x44, 0x10);
base = ICH5_WDBASE + 0x60;
/* Clear TCO timeout status */
outw(0x0008, base + 0x04);
outw(0x0002, base + 0x06);
/* set the time value 1 cnt = .6 sec */
outw(0x0010, base + 0x01);
/* reload the timer with the value */
outw(0x0001, base + 0x00);
/* clear bit 11 in TCO1_CNT to start watchdog */
value = inw(base + 0x08);
value &= ~(1 << 11);
outw(value, base + 0x08);
print_debug("Watchdog ICH5 enabled\r\n");
}

View File

@ -46,6 +46,7 @@ if HAVE_ACPI_TABLES
object fadt.o
object dsdt.o
end
object reset.o
##

View File

@ -4,9 +4,6 @@ uses HAVE_ACPI_TABLES
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -81,13 +78,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=0
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 1);
}

View File

@ -45,6 +45,7 @@ arch i386 end
driver mainboard.o
if HAVE_MP_TABLE object mptable.o end
if HAVE_PIRQ_TABLE object irq_tables.o end
object reset.o
dir /drivers/trident/blade3d

View File

@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses HARD_RESET_BUS
uses HARD_RESET_DEVICE
uses HARD_RESET_FUNCTION
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_MAX_CPUS
@ -73,13 +70,6 @@ default HAVE_FALLBACK_BOOT=1
##
default HAVE_HARD_RESET=1
##
## Funky hard reset implementation
##
default HARD_RESET_BUS=1
default HARD_RESET_DEVICE=4
default HARD_RESET_FUNCTION=0
##
## Build code to export a programmable irq routing table
##

View File

@ -0,0 +1,6 @@
#include "../../../southbridge/amd/amd8111/amd8111_reset.c"
void hard_reset(void)
{
amd8111_hard_reset(0, 2);
}

View File

@ -0,0 +1,198 @@
##
## Only use the option table in a normal image
##
default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
##
## Compute the location and size of where this firmware image
## (linuxBIOS 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 linuxBIOS bootloader.
##
default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
##
## Compute where this copy of linuxBIOS will start in the boot rom
##
default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE )
##
## Compute a range of ROM that can be cached to speed up linuxBIOS,
## 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=131072
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
object reset.o
##
## Romcc output
##
makerule ./failover.E
depends "$(MAINBOARD)/failover.c ./romcc"
action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
end
makerule ./failover.inc
depends "$(MAINBOARD)/failover.c ./romcc"
action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
end
makerule ./auto.E
depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
action "./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
end
makerule ./auto.inc
depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
action "./romcc -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
end
##
## Build our 16 bit and 32 bit linuxBIOS 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 linuxBIOS 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
### Should this be in the northbridge code?
mainboardinit arch/i386/lib/cpu_reset.inc
##
## Include an id string (For safe flashing)
##
mainboardinit arch/i386/lib/id.inc
ldscript /arch/i386/lib/id.lds
###
### This is the early phase of linuxBIOS startup
### Things are delicate and we test to see if we should
### failover to another image.
###
if USE_FALLBACK_IMAGE
ldscript /arch/i386/lib/failover.lds
mainboardinit ./failover.inc
end
###
### O.k. We aren't just an intermediary anymore!
###
##
## Setup RAM
##
mainboardinit cpu/x86/fpu/enable_fpu.inc
mainboardinit cpu/x86/mmx/enable_mmx.inc
mainboardinit cpu/x86/sse/enable_sse.inc
mainboardinit ./auto.inc
mainboardinit cpu/x86/sse/disable_sse.inc
mainboardinit cpu/x86/mmx/disable_mmx.inc
##
## Include the secondary Configuration files
##
dir /pc80
config chip.h
chip northbridge/intel/E7525 # mch
device pci_domain 0 on
chip southbridge/intel/esb6300 # esb6300
register "pirq_a_d" = "0x0b0a0a05"
register "pirq_e_h" = "0x0a0b0c80"
device pci 1c.0 on end
device pci 1d.0 on end
device pci 1d.1 on end
device pci 1d.4 on end
device pci 1d.5 on end
device pci 1d.7 on end
device pci 1e.0 on end
device pci 1f.0 on
chip superio/winbond/w83627hf
device pnp 2e.0 off end
device pnp 2e.1 off end
device pnp 2e.2 on
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.3 on
io 0x60 = 0x2f8
irq 0x70 = 3
end
device pnp 2e.4 off end
device pnp 2e.5 off end
device pnp 2e.6 off end
device pnp 2e.7 off end
device pnp 2e.9 off end
device pnp 2e.a on end
device pnp 2e.b off end
device pnp 2e.f off end
device pnp 2e.10 off end
device pnp 2e.14 off end
end
end
device pci 1f.1 on end
device pci 1f.2 on end
device pci 1f.3 on end
device pci 1f.5 off end
device pci 1f.6 on end
end
device pci 00.0 on end
device pci 00.1 on end
device pci 00.2 on end
device pci 02.0 on end
device pci 03.0 on end
device pci 04.0 on end
device pci 08.0 on end
end
device apic_cluster 0 on
chip cpu/intel/socket_mPGA604_800Mhz # cpu0
device apic 0 on end
end
chip cpu/intel/socket_mPGA604_800Mhz # cpu1
device apic 6 on end
end
end
end

View File

@ -0,0 +1,229 @@
uses HAVE_MP_TABLE
uses HAVE_PIRQ_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses IRQ_SLOT_COUNT
uses HAVE_OPTION_TABLE
uses CONFIG_LOGICAL_CPUS
uses CONFIG_MAX_CPUS
uses CONFIG_IOAPIC
uses CONFIG_SMP
uses FALLBACK_SIZE
uses ROM_SIZE
uses ROM_SECTION_SIZE
uses ROM_IMAGE_SIZE
uses ROM_SECTION_SIZE
uses ROM_SECTION_OFFSET
uses CONFIG_ROM_STREAM
uses CONFIG_ROM_STREAM_START
uses PAYLOAD_SIZE
uses _ROMBASE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
uses STACK_SIZE
uses HEAP_SIZE
uses USE_OPTION_TABLE
uses LB_CKS_RANGE_START
uses LB_CKS_RANGE_END
uses LB_CKS_LOC
uses MAINBOARD
uses MAINBOARD_PART_NUMBER
uses MAINBOARD_VENDOR
uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
uses LINUXBIOS_EXTRA_VERSION
uses CONFIG_UDELAY_TSC
uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
uses _RAMBASE
uses CONFIG_GDB_STUB
uses CONFIG_CONSOLE_SERIAL8250
uses TTYS0_BAUD
uses TTYS0_BASE
uses TTYS0_LCS
uses DEFAULT_CONSOLE_LOGLEVEL
uses MAXIMUM_CONSOLE_LOGLEVEL
uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL
uses CONFIG_CONSOLE_BTEXT
uses CC
uses HOSTCC
uses CROSS_COMPILE
uses OBJCOPY
###
### Build options
###
##
## ROM_SIZE is the size of boot ROM that this board will use.
##
default ROM_SIZE=1048576
##
## Build code for the fallback boot
##
default HAVE_FALLBACK_BOOT=1
##
## Delay timer options
## Use timer2
##
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=16
##
## Build code to export an x86 MP table
## Useful for specifying IRQ routing values
##
default HAVE_MP_TABLE=1
##
## Build code to export a CMOS option table
##
default HAVE_OPTION_TABLE=1
##
## Move the default LinuxBIOS cmos range off of AMD RTC registers
##
default LB_CKS_RANGE_START=49
default LB_CKS_RANGE_END=122
default LB_CKS_LOC=123
##
## Build code for SMP support
## Only worry about 2 micro processors
##
default CONFIG_SMP=1
default CONFIG_MAX_CPUS=4
default CONFIG_LOGICAL_CPUS=0
##
## Build code to setup a generic IOAPIC
##
default CONFIG_IOAPIC=1
##
## Clean up the motherboard id strings
##
default MAINBOARD_PART_NUMBER="X6DAI"
default MAINBOARD_VENDOR= "Supermicro"
default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9
default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x6780
###
### LinuxBIOS layout values
###
## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
default ROM_IMAGE_SIZE = 65536
##
## Use a small 8K stack
##
default STACK_SIZE=0x2000
##
## Use a small 32K heap
##
default HEAP_SIZE=0x8000
###
### Compute the location and size of where this firmware image
### (linuxBIOS plus bootloader) will live in the boot rom chip.
###
default FALLBACK_SIZE=131072
##
## LinuxBIOS C code runs at this location in RAM
##
default _RAMBASE=0x00004000
##
## Load the payload from the ROM
##
default CONFIG_ROM_STREAM=1
###
### Defaults of options that you may want to override in the target config file
###
##
## The default compiler
##
default CC="$(CROSS_COMPILE)gcc -m32"
default HOSTCC="gcc"
##
## 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 linuxBIOS 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=8
## At a maximum only compile in this level of debugging
default MAXIMUM_CONSOLE_LOGLEVEL=8
##
## Select power on after power fail setting
default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON"
##
## Don't enable the btext console
##
default CONFIG_CONSOLE_BTEXT=0
### End Options.lb
end

View File

@ -0,0 +1,139 @@
#define ASSEMBLY 1
#include <stdint.h>
#include <device/pci_def.h>
#include <arch/io.h>
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <cpu/x86/lapic.h>
#include "option_table.h"
#include "pc80/mc146818rtc_early.c"
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
#include "southbridge/intel/esb6300/esb6300_early_smbus.c"
#include "northbridge/intel/E7525/raminit.h"
#include "superio/winbond/w83627hf/w83627hf.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "debug.c"
#include "watchdog.c"
#include "reset.c"
#include "superio/winbond/w83627hf/w83627hf_early_init.c"
#include "northbridge/intel/E7525/memory_initialized.c"
#include "cpu/x86/bist.h"
#define SIO_GPIO_BASE 0x680
#define SIO_XBUS_BASE 0x4880
#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP2)
#define DEVPRES_CONFIG ( \
DEVPRES_D1F0 | \
DEVPRES_D2F0 | \
DEVPRES_D3F0 | \
DEVPRES_D4F0 | \
DEVPRES_D6F0 | \
0 )
#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)
#define RECVENA_CONFIG 0x0808090a
#define RECVENB_CONFIG 0x0808090a
static inline void activate_spd_rom(const struct mem_controller *ctrl)
{
/* nothing to do */
}
static inline int spd_read_byte(unsigned device, unsigned address)
{
return smbus_read_byte(device, address);
}
#include "northbridge/intel/E7525/raminit.c"
#include "sdram/generic_sdram.c"
static void main(unsigned long bist)
{
/*
*
*
*/
static const struct mem_controller mch[] = {
{
.node_id = 0,
.f0 = PCI_DEV(0, 0x00, 0),
.f1 = PCI_DEV(0, 0x00, 1),
.f2 = PCI_DEV(0, 0x00, 2),
.f3 = PCI_DEV(0, 0x00, 3),
.channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, },
.channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, },
}
};
if (bist == 0) {
/* Skip this if there was a built in self test failure */
early_mtrr_init();
if (memory_initialized()) {
asm volatile ("jmp __cpu_reset");
}
}
/* Setup the console */
outb(0x87,0x2e);
outb(0x87,0x2e);
pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6));
w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE);
uart_init();
console_init();
/* MOVE ME TO A BETTER LOCATION !!! */
/* config LPC decode for flash memory access */
device_t dev;
dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0);
if (dev == PCI_DEV_INVALID) {
die("Missing 6300ESB?");
}
pci_write_config32(dev, 0xe8, 0x00000000);
pci_write_config8(dev, 0xf0, 0x00);
#if 0
display_cpuid_update_microcode();
#endif
#if 0
print_pci_devices();
#endif
#if 1
enable_smbus();
#endif
#if 0
int i;
for(i = 0; i < 1; i++) {
dump_spd_registers();
}
#endif
disable_watchdogs();
sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch);
#if 1
dump_pci_device(PCI_DEV(0, 0x00, 0));
// dump_bar14(PCI_DEV(0, 0x00, 0));
#endif
#if 0 // temporarily disabled
/* Check the first 1M */
// ram_check(0x00000000, 0x000100000);
// ram_check(0x00000000, 0x000a0000);
ram_check(0x00100000, 0x01000000);
/* check the first 1M in the 3rd Gig */
ram_check(0x30100000, 0x31000000);
#endif
#if 0
ram_check(0x00000000, 0x02000000);
#endif
#if 0
while(1) {
hlt();
}
#endif
}

View File

@ -0,0 +1,5 @@
struct chip_operations mainboard_supermicro_x6dai_g_ops;
struct mainboard_supermicro_x6dai_g_config {
int nothing;
};

View File

@ -0,0 +1,80 @@
entries
#start-bit length config config-ID name
#0 8 r 0 seconds
#8 8 r 0 alarm_seconds
#16 8 r 0 minutes
#24 8 r 0 alarm_minutes
#32 8 r 0 hours
#40 8 r 0 alarm_hours
#48 8 r 0 day_of_week
#56 8 r 0 day_of_month
#64 8 r 0 month
#72 8 r 0 year
#80 4 r 0 rate_select
#84 3 r 0 REF_Clock
#87 1 r 0 UIP
#88 1 r 0 auto_switch_DST
#89 1 r 0 24_hour_mode
#90 1 r 0 binary_values_enable
#91 1 r 0 square-wave_out_enable
#92 1 r 0 update_finished_enable
#93 1 r 0 alarm_interrupt_enable
#94 1 r 0 periodic_interrupt_enable
#95 1 r 0 disable_clock_updates
#96 288 r 0 temporary_filler
0 384 r 0 reserved_memory
384 1 e 4 boot_option
385 1 e 4 last_boot
386 1 e 1 ECC_memory
388 4 r 0 reboot_bits
392 3 e 5 baud_rate
395 1 e 2 hyper_threading
400 1 e 1 power_on_after_fail
412 4 e 6 debug_level
416 4 e 7 boot_first
420 4 e 7 boot_second
424 4 e 7 boot_third
428 4 h 0 boot_index
432 8 h 0 boot_countdown
728 256 h 0 user_data
984 16 h 0 check_sum
# Reserve the extended AMD configuration registers
1000 24 r 0 reserved_memory
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 983 984

View File

@ -0,0 +1,330 @@
#define SMBUS_MEM_DEVICE_START 0x50
#define SMBUS_MEM_DEVICE_END 0x57
#define SMBUS_MEM_DEVICE_INC 1
static void print_reg(unsigned char index)
{
unsigned char data;
outb(index, 0x2e);
data = inb(0x2f);
print_debug("0x");
print_debug_hex8(index);
print_debug(": 0x");
print_debug_hex8(data);
print_debug("\r\n");
return;
}
static void xbus_en(void)
{
/* select the XBUS function in the SIO */
outb(0x07, 0x2e);
outb(0x0f, 0x2f);
outb(0x30, 0x2e);
outb(0x01, 0x2f);
return;
}
static void setup_func(unsigned char func)
{
/* select the function in the SIO */
outb(0x07, 0x2e);
outb(func, 0x2f);
/* print out the regs */
print_reg(0x30);
print_reg(0x60);
print_reg(0x61);
print_reg(0x62);
print_reg(0x63);
print_reg(0x70);
print_reg(0x71);
print_reg(0x74);
print_reg(0x75);
return;
}
static void siodump(void)
{
int i;
unsigned char data;
print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n");
for (i=0x10; i<=0x2d; i++) {
print_reg((unsigned char)i);
}
#if 0
print_debug("\r\n*** XBUS REGISTERS ***\r\n");
setup_func(0x0f);
for (i=0xf0; i<=0xff; i++) {
print_reg((unsigned char)i);
}
print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n");
setup_func(0x03);
print_reg(0xf0);
print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n");
setup_func(0x02);
print_reg(0xf0);
#endif
print_debug("\r\n*** GPIO REGISTERS ***\r\n");
setup_func(0x07);
for (i=0xf0; i<=0xf8; i++) {
print_reg((unsigned char)i);
}
print_debug("\r\n*** GPIO VALUES ***\r\n");
data = inb(0x68a);
print_debug("\r\nGPDO 4: 0x");
print_debug_hex8(data);
data = inb(0x68b);
print_debug("\r\nGPDI 4: 0x");
print_debug_hex8(data);
print_debug("\r\n");
#if 0
print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n");
setup_func(0x0a);
print_reg(0xf0);
print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n");
setup_func(0x09);
print_reg(0xf0);
print_reg(0xf1);
print_debug("\r\n*** RTC REGISTERS ***\r\n");
setup_func(0x10);
print_reg(0xf0);
print_reg(0xf1);
print_reg(0xf3);
print_reg(0xf6);
print_reg(0xf7);
print_reg(0xfe);
print_reg(0xff);
print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n");
setup_func(0x14);
print_reg(0xf0);
#endif
return;
}
static void print_debug_pci_dev(unsigned dev)
{
print_debug("PCI: ");
print_debug_hex8((dev >> 16) & 0xff);
print_debug_char(':');
print_debug_hex8((dev >> 11) & 0x1f);
print_debug_char('.');
print_debug_hex8((dev >> 8) & 7);
}
static void print_pci_devices(void)
{
device_t dev;
for(dev = PCI_DEV(0, 0, 0);
dev <= PCI_DEV(0, 0x1f, 0x7);
dev += PCI_DEV(0,0,1)) {
uint32_t id;
id = pci_read_config32(dev, PCI_VENDOR_ID);
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
continue;
}
print_debug_pci_dev(dev);
print_debug("\r\n");
}
}
static void dump_pci_device(unsigned dev)
{
int i;
print_debug_pci_dev(dev);
print_debug("\r\n");
for(i = 0; i <= 255; i++) {
unsigned char val;
if ((i & 0x0f) == 0) {
print_debug_hex8(i);
print_debug_char(':');
}
val = pci_read_config8(dev, i);
print_debug_char(' ');
print_debug_hex8(val);
if ((i & 0x0f) == 0x0f) {
print_debug("\r\n");
}
}
}
static void dump_bar14(unsigned dev)
{
int i;
unsigned long bar;
print_debug("BAR 14 Dump\r\n");
bar = pci_read_config32(dev, 0x14);
for(i = 0; i <= 0x300; i+=4) {
#if 0
unsigned char val;
if ((i & 0x0f) == 0) {
print_debug_hex8(i);
print_debug_char(':');
}
val = pci_read_config8(dev, i);
#endif
if((i%4)==0) {
print_debug("\r\n");
print_debug_hex16(i);
print_debug_char(' ');
}
print_debug_hex32(read32(bar + i));
print_debug_char(' ');
}
print_debug("\r\n");
}
static void dump_pci_devices(void)
{
device_t dev;
for(dev = PCI_DEV(0, 0, 0);
dev <= PCI_DEV(0, 0x1f, 0x7);
dev += PCI_DEV(0,0,1)) {
uint32_t id;
id = pci_read_config32(dev, PCI_VENDOR_ID);
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
continue;
}
dump_pci_device(dev);
}
}
#if 0
static void dump_spd_registers(const struct mem_controller *ctrl)
{
int i;
print_debug("\r\n");
for(i = 0; i < 4; i++) {
unsigned device;
device = ctrl->channel0[i];
if (device) {
int j;
print_debug("dimm: ");
print_debug_hex8(i);
print_debug(".0: ");
print_debug_hex8(device);
for(j = 0; j < 256; j++) {
int status;
unsigned char byte;
if ((j & 0xf) == 0) {
print_debug("\r\n");
print_debug_hex8(j);
print_debug(": ");
}
status = smbus_read_byte(device, j);
if (status < 0) {
print_debug("bad device\r\n");
break;
}
byte = status & 0xff;
print_debug_hex8(byte);
print_debug_char(' ');
}
print_debug("\r\n");
}
device = ctrl->channel1[i];
if (device) {
int j;
print_debug("dimm: ");
print_debug_hex8(i);
print_debug(".1: ");
print_debug_hex8(device);
for(j = 0; j < 256; j++) {
int status;
unsigned char byte;
if ((j & 0xf) == 0) {
print_debug("\r\n");
print_debug_hex8(j);
print_debug(": ");
}
status = smbus_read_byte(device, j);
if (status < 0) {
print_debug("bad device\r\n");
break;
}
byte = status & 0xff;
print_debug_hex8(byte);
print_debug_char(' ');
}
print_debug("\r\n");
}
}
}
#endif
void dump_spd_registers(void)
{
unsigned device;
device = SMBUS_MEM_DEVICE_START;
while(device <= SMBUS_MEM_DEVICE_END) {
int status = 0;
int i;
print_debug("\r\n");
print_debug("dimm ");
print_debug_hex8(device);
for(i = 0; (i < 256) ; i++) {
unsigned char byte;
if ((i % 16) == 0) {
print_debug("\r\n");
print_debug_hex8(i);
print_debug(": ");
}
status = smbus_read_byte(device, i);
if (status < 0) {
print_debug("bad device: ");
print_debug_hex8(-status);
print_debug("\r\n");
break;
}
print_debug_hex8(status);
print_debug_char(' ');
}
device += SMBUS_MEM_DEVICE_INC;
print_debug("\n");
}
}
void dump_ipmi_registers(void)
{
unsigned device;
device = 0x42;
while(device <= 0x42) {
int status = 0;
int i;
print_debug("\r\n");
print_debug("ipmi ");
print_debug_hex8(device);
for(i = 0; (i < 8) ; i++) {
unsigned char byte;
status = smbus_read_byte(device, 2);
if (status < 0) {
print_debug("bad device: ");
print_debug_hex8(-status);
print_debug("\r\n");
break;
}
print_debug_hex8(status);
print_debug_char(' ');
}
device += SMBUS_MEM_DEVICE_INC;
print_debug("\n");
}
}

View File

@ -0,0 +1,46 @@
#define ASSEMBLY 1
#include <stdint.h>
#include <device/pci_def.h>
#include <device/pci_ids.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <cpu/x86/lapic.h>
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "pc80/mc146818rtc_early.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "northbridge/intel/E7525/memory_initialized.c"
static unsigned long main(unsigned long bist)
{
/* Did just the cpu reset? */
if (memory_initialized()) {
if (last_boot_normal()) {
goto normal_image;
} else {
goto cpu_reset;
}
}
/* This is the primary cpu how should I boot? */
else if (do_normal_boot()) {
goto normal_image;
}
else {
goto fallback_image;
}
normal_image:
asm volatile ("jmp __normal_image"
: /* outputs */
: "a" (bist) /* inputs */
: /* clobbers */
);
cpu_reset:
asm volatile ("jmp __cpu_reset"
: /* outputs */
: "a"(bist) /* inputs */
: /* clobbers */
);
fallback_image:
return bist;
}

View File

@ -0,0 +1,34 @@
/* PCI: Interrupt Routing Table found at 0x40163ed0 size = 272 */
#include <arch/pirq_routing.h>
const struct irq_routing_table intel_irq_routing_table = {
0x52495024, /* u32 signature */
0x0100, /* u16 version */
272, /* u16 Table size 32+(16*devices) */
0x00, /* u8 Bus 0 */
0xf8, /* u8 Device 1, Function 0 */
0x0000, /* u16 reserve IRQ for PCI */
0x8086, /* u16 Vendor */
0x122e, /* Device ID */
0x00000000, /* u32 miniport_data */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0x78, /* u8 checksum - mod 256 checksum must give zero */
{ /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
{0x00, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00},
{0x00, 0x10, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00},
{0x01, 0x00, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}}, 0x04, 0x00},
{0x00, 0x20, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00},
{0x02, 0x00, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}}, 0x06, 0x00},
{0x00, 0xe0, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00},
{0x04, 0x08, {{0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}}, 0x01, 0x00},
{0x04, 0x10, {{0x6a, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x07, 0x00},
{0x04, 0x18, {{0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}}, 0x02, 0x00},
{0x00, 0xf0, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00},
{0x05, 0x40, {{0x68, 0x1ef8}, {0x69, 0x1ef8}, {0x6a, 0x1ef8}, {0x6b, 0x1ef8}}, 0x03, 0x00},
{0x05, 0x18, {{0x6a, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x08, 0x00},
{0x05, 0x10, {{0x69, 0x1ef8}, {0x6a, 0x1ef8}, {0x6b, 0x1ef8}, {0x68, 0x1ef8}}, 0x05, 0x00},
{0x00, 0xf8, {{0x62, 0x1ef8}, {0x61, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00},
{0x00, 0xe8, {{0x60, 0x1ef8}, {0x63, 0x1ef8}, {0x00, 0xdef8}, {0x6b, 0x1ef8}}, 0x00, 0x00}
}
};

View File

@ -0,0 +1,12 @@
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <cpu/x86/msr.h>
#include "chip.h"
struct chip_operations supermicro_x6dai_g_ops = {
CHIP_NAME("Supermicro X6DAI_G mainboard ")
};

View File

@ -0,0 +1,142 @@
#include <console/console.h>
#include <arch/smp/mpspec.h>
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
void *smp_write_config_table(void *v)
{
static const char sig[4] = "PCMP";
static const char oem[8] = "LNXI ";
static const char productid[12] = "X6DAI-G ";
struct mp_config_table *mc;
unsigned char bus_num;
unsigned char bus_isa;
unsigned char bus_6300;
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);
{
device_t dev;
/* southbridge */
dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
if (dev) {
bus_6300 = pci_read_config8(dev, PCI_SECONDARY_BUS);
bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
bus_isa++;
}
else {
printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n");
bus_6300 = 5;
bus_isa = 6;
}
}
/* define bus and isa numbers */
for(bus_num = 0; bus_num < bus_isa; bus_num++) {
smp_write_bus(mc, bus_num, "PCI ");
}
smp_write_bus(mc, bus_isa, "ISA ");
/* IOAPIC handling */
smp_write_ioapic(mc, 2, 0x20, 0xfec00000);
smp_write_ioapic(mc, 3, 0x20, 0xfec10000);
/* ISA backward compatibility interrupts */
smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x00, 0x02, 0x00);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x01, 0x02, 0x01);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x00, 0x02, 0x02);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x03, 0x02, 0x03);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x04, 0x02, 0x04);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
0x00, 0x74, 0x02, 0x10);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x06, 0x02, 0x06);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x07, 0x02, 0x07);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x08, 0x02, 0x08);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x09, 0x02, 0x09);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
0x00, 0x77, 0x02, 0x17);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
0x00, 0x75, 0x02, 0x13);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x0c, 0x02, 0x0c);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x0d, 0x02, 0x0d);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x0e, 0x02, 0x0e);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x0f, 0x02, 0x0f);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
0x00, 0x7c, 0x02, 0x12);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
0x00, 0x7d, 0x02, 0x11);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
0x00, 0x7d, 0x02, 0x11);
/* Slot 1 function 0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
4, 0x04, 0x03, 0x00);
/* Slot 2 function 0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
4, 0x0c, 0x03, 0x01);
/* Slot 3 function 0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_6300, 0x20, 0x02, 0x14);
/* Slot 4 function 0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_6300, 0x08, 0x02, 0x15);
/* On board NIC */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
bus_6300, 0x0c, 0x02, 0x16);
/* Standard local interrupt assignments */
// smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
// bus_isa, 0x00, MP_APIC_ALL, 0x00);
smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
bus_isa, 0x00, MP_APIC_ALL, 0x01);
/* There is no extension information... */
/* 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,40 @@
#include <arch/io.h>
#include <device/pci_def.h>
#include <device/pci_ids.h>
#ifndef __ROMCC__
#include <device/device.h>
#define PCI_ID(VENDOR_ID, DEVICE_ID) \
((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
#define PCI_DEV_INVALID 0
static inline device_t pci_locate_device(unsigned pci_id, device_t from)
{
return dev_find_device(pci_id >> 16, pci_id & 0xffff, from);
}
#endif
void soft_reset(void)
{
outb(0x04, 0xcf9);
}
void hard_reset(void)
{
outb(0x02, 0xcf9);
outb(0x06, 0xcf9);
}
void full_reset(void)
{
device_t dev;
/* Enable power on after power fail... */
dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_6300ESB_ISA), 0);
if (dev != PCI_DEV_INVALID) {
unsigned byte;
byte = pci_read_config8(dev, 0xa4);
byte &= 0xfe;
pci_write_config8(dev, 0xa4, byte);
}
outb(0x0e, 0xcf9);
}

Some files were not shown because too many files have changed in this diff Show More