- First pass through with with device tree enhancement merge. Most of the mechanisms should

be in place but don't expect anything to quite work yet.


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1662 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Eric Biederman 2004-10-14 20:54:17 +00:00
commit b78c1972fe
52 changed files with 1714 additions and 1769 deletions

View file

@ -31,6 +31,8 @@ uses LB_CKS_RANGE_END
uses LB_CKS_LOC
uses MAINBOARD_PART_NUMBER
uses MAINBOARD_VENDOR
uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID
uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID
## ROM_SIZE is the size of boot ROM that this board will use.
@ -95,6 +97,8 @@ default CONFIG_IOAPIC=1
##
default MAINBOARD_PART_NUMBER="HDAMA"
default MAINBOARD_VENDOR="ARIMA"
default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x161f
default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x3016
###
### LinuxBIOS layout values
@ -109,9 +113,9 @@ default ROM_IMAGE_SIZE = 65536
default STACK_SIZE=0x2000
##
## Use a small 16K heap
## Use a small 32K heap
##
default HEAP_SIZE=0x4000
default HEAP_SIZE=0x8000
##
## Only use the option table in a normal image
@ -158,7 +162,6 @@ default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
##
arch i386 end
#cpu k8 end
##
## Build the objects we have code for in this directory.
@ -193,21 +196,20 @@ end
##
## Build our 16 bit and 32 bit linuxBIOS entry code
##
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
mainboardinit cpu/i386/bist32.inc
ldscript /cpu/i386/entry16.lds
ldscript /cpu/i386/entry32.lds
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/i386/reset16.inc
ldscript /cpu/i386/reset16.lds
mainboardinit cpu/x86/16bit/reset16.inc
ldscript /cpu/x86/16bit/reset16.lds
else
mainboardinit cpu/i386/reset32.inc
ldscript /cpu/i386/reset32.lds
mainboardinit cpu/x86/32bit/reset32.inc
ldscript /cpu/x86/32bit/reset32.lds
end
### Should this be in the northbridge code?
@ -219,11 +221,6 @@ mainboardinit arch/i386/lib/cpu_reset.inc
mainboardinit arch/i386/lib/id.inc
ldscript /arch/i386/lib/id.lds
##
## Setup our mtrrs
##
mainboardinit cpu/k8/earlymtrr.inc
###
### This is the early phase of linuxBIOS startup
### Things are delicate and we test to see if we should
@ -241,9 +238,12 @@ end
##
## Setup RAM
##
mainboardinit cpu/k8/enable_mmx_sse.inc
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/k8/disable_mmx_sse.inc
mainboardinit cpu/x86/sse/disable_sse.inc
mainboardinit cpu/x86/mmx/disable_mmx.inc
##
## Include the secondary Configuration files
@ -252,30 +252,25 @@ dir /pc80
config chip.h
northbridge amd/amdk8 "mc0"
pci 0:18.0
pci 0:18.0
pci 0:18.0
pci 0:18.1
pci 0:18.2
pci 0:18.3
southbridge amd/amd8131 "amd8131" link 0
pnp cf8.0
northbridge amd/amdk8 "mc1" link 0
pci 0:19.0
pci 0:19.0
pci 0:19.0
pci 0:19.1
pci 0:19.2
pci 0:19.3
end
pci 1:18.0
southbridge amd/amd8131 "amd8131" link 1
pci 0:0.0
pci 0:0.1
pci 0:1.0
pci 0:1.1
end
southbridge amd/amd8111 "amd8111" link 0
southbridge amd/amd8111 "amd8111" link 1
pci 0:0.0
pci 0:1.0 on
pci 0:1.1 on
pci 0:1.2 on
pci 0:1.3 on
pci 0:1.5 off
pci 0:1.6 off
pci 1:0.0 on
pci 1:0.1 on
pci 1:0.2 on
pci 1:1.0 off
superio NSC/pc87360 link 1
pnp 2e.0 off # Floppy
io 0x60 = 0x3f0
@ -301,29 +296,64 @@ northbridge amd/amdk8 "mc0"
pnp 2e.9 off # FSCM
pnp 2e.a off # WDT
end
pci 0:1.1 on
pci 0:1.2 on
pci 0:1.3 on # ACPI/SMBUS
chip drivers/generic/generic link 4
#phillips pca9545 smbus mux
i2c 70
# analog_devices adm1026
chip drivers/generic/generic link 0
i2c 2c
end
i2c 70
i2c 70
i2c 70
end
chip drivers/generic/generic link 4 #dimm 0-0-0
i2c 50
end
chip drivers/generic/generic link 4 #dimm 0-0-1
i2c 51
end
chip drivers/generic/generic link 4 #dimm 0-1-0
i2c 52
end
chip drivers/generic/generic link 4 #dimm 0-1-1
i2c 53
end
chip drivers/generic/generic link 4 #dimm 1-0-0
i2c 54
end
chip drivers/generic/generic link 4 #dimm 1-0-1
i2c 55
end
chip drivers/generic/generic link 4 #dimm 1-1-0
i2c 56
end
chip drivers/generic/generic link 4 #dimm 1-1-1
i2c 57
end
pci 0:1.5 off
pci 0:1.6 off
pci 1:0.0 on
pci 1:0.1 on
pci 1:0.2 on
pci 1:1.0 off
end
pci 1:18.0
pci 1:18.0
pci 1:18.1
pci 1:18.2
pci 1:18.3
end
northbridge amd/amdk8 "mc1"
pci 0:19.0
pci 0:19.0
pci 0:19.0
pci 0:19.1
pci 0:19.2
pci 0:19.3
cpu amd/socket_940 "cpu0" link 1
apic 0
end
cpu k8 "cpu0"
register "ldt0" = "{ .chip = &amd8131, .ht_width=16, .ht_speed=600 }"
cpu amd/socket_940 "cpu1" link 1
apic 1
end
cpu k8 "cpu1"
end
##
## Include the old serial code for those few places that still need it.
##
mainboardinit pc80/serial.inc
mainboardinit arch/i386/lib/console.inc
mainboardinit cpu/i386/bist32_fail.inc

View file

@ -4,7 +4,8 @@
#include <arch/io.h>
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <arch/smp/lapic.h>
#include <cpu/x86/lapic.h>
#include <arch/cpu.h>
#include "option_table.h"
#include "pc80/mc146818rtc_early.c"
#include "pc80/serial.c"
@ -13,13 +14,15 @@
#include "northbridge/amd/amdk8/incoherent_ht.c"
#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/k8/apic_timer.c"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/p6/boot_cpu.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)
@ -50,7 +53,8 @@ static void memreset_setup(void)
outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
/* Ensure the BIOS has control of the memory lines */
outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
} else {
}
else {
/* Ensure the CPU has controll of the memory lines */
outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 29);
}
@ -128,7 +132,7 @@ static inline int spd_read_byte(unsigned device, unsigned address)
#define FIRST_CPU 1
#define SECOND_CPU 1
#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
static void main(void)
static void main(unsigned long bist)
{
static const struct mem_controller cpu[] = {
#if FIRST_CPU
@ -156,25 +160,29 @@ static void main(void)
};
int needs_reset;
enable_lapic();
init_timer();
if (cpu_init_detected()) {
asm volatile ("jmp __cpu_reset");
if (bist == 0) {
/* Skip this if there was a built in self test failure */
amd_early_mtrr_init();
enable_lapic();
init_timer();
if (cpu_init_detected()) {
asm volatile ("jmp __cpu_reset");
}
distinguish_cpu_resets();
if (!boot_cpu()) {
stop_this_cpu();
}
}
distinguish_cpu_resets();
if (!boot_cpu()) {
stop_this_cpu();
}
/* Setup the console */
pc87360_enable_serial(SERIAL_DEV, TTYS0_BASE);
uart_init();
console_init();
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
setup_default_resource_map();
needs_reset = setup_coherent_ht_domain();
/* Non-coherent HT is on LDT0 */
needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0x80);
if (needs_reset) {
print_info("ht reset -\r\n");
@ -184,9 +192,7 @@ static void main(void)
#if 0
print_pci_devices();
#endif
enable_smbus();
#if 0
dump_spd_registers(&cpu[0]);
#endif

View file

@ -41,6 +41,7 @@ entries
432 8 h 0 boot_countdown
440 4 e 9 slow_cpu
444 1 e 1 nmi
445 1 e 1 iommu
728 256 h 0 user_data
984 16 h 0 check_sum
# Reserve the extended AMD configuration registers

View file

@ -4,22 +4,15 @@
#include <device/pci_ids.h>
#include <arch/io.h>
#include <arch/romcc_io.h>
#include <arch/smp/lapic.h>
#include <cpu/x86/lapic.h>
#include "pc80/mc146818rtc_early.c"
#include "southbridge/amd/amd8111/amd8111_enable_rom.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include "cpu/p6/boot_cpu.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "northbridge/amd/amdk8/reset_test.c"
#define HAVE_REGPARM_SUPPORT 0
#if HAVE_REGPARM_SUPPORT
static unsigned long main(unsigned long bist)
{
#else
static void main(void)
{
unsigned long bist = 0;
#endif
/* Make cerain my local apic is useable */
enable_lapic();
@ -72,9 +65,5 @@ static void main(void)
: /* clobbers */
);
fallback_image:
#if HAVE_REGPARM_SUPPORT
return bist;
#else
return;
#endif
}

View file

@ -3,145 +3,251 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <cpu/p6/msr.h>
#include <cpu/x86/msr.h>
#include <part/hard_reset.h>
#include <device/smbus.h>
#include <delay.h>
#include <arch/io.h>
#include <device/chip.h>
#include "../../../northbridge/amd/amdk8/northbridge.h"
#include "../../../northbridge/amd/amdk8/cpu_rev.c"
#include "chip.h"
#include "pc80/mc146818rtc.h"
unsigned long initial_apicid[CONFIG_MAX_CPUS] =
#undef DEBUG
#define DEBUG 0
#if DEBUG
static void debug_init(device_t dev)
{
0, 1,
unsigned bus;
unsigned devfn;
#if 0
for(bus = 0; bus < 256; bus++) {
for(devfn = 0; devfn < 256; devfn++) {
int i;
dev = dev_find_slot(bus, devfn);
if (!dev) {
continue;
}
if (!dev->enabled) {
continue;
}
printk_info("%02x:%02x.%0x aka %s\n",
bus, devfn >> 3, devfn & 7, dev_path(dev));
for(i = 0; i < 256; i++) {
if ((i & 0x0f) == 0) {
printk_info("%02x:", i);
}
printk_info(" %02x", pci_read_config8(dev, i));
if ((i & 0x0f) == 0xf) {
printk_info("\n");
}
}
printk_info("\n");
}
}
#endif
#if 0
msr_t msr;
unsigned index;
unsigned eax, ebx, ecx, edx;
index = 0x80000007;
printk_debug("calling cpuid 0x%08x\n", index);
asm volatile(
"cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "a" (index)
);
printk_debug("cpuid[%08x]: %08x %08x %08x %08x\n",
index, eax, ebx, ecx, edx);
if (edx & (3 << 1)) {
index = 0xC0010042;
printk_debug("Reading msr: 0x%08x\n", index);
msr = rdmsr(index);
printk_debug("msr[0x%08x]: 0x%08x%08x\n",
index, msr.hi, msr.hi);
}
#endif
}
static void debug_noop(device_t dummy)
{
}
static struct device_operations debug_operations = {
.read_resources = debug_noop,
.set_resources = debug_noop,
.enable_resources = debug_noop,
.init = debug_init,
};
#define SMBGSTATUS 0xe0
#define SMBGCTL 0xe2
#define SMBHSTADDR 0xe4
#define SMBHSTDAT 0xe6
#define SMBHSTCMD 0xe8
#define SMBHSTFIFO 0xe9
#define SMBUS_TIMEOUT (100*1000*10)
static inline void smbus_delay(void)
static unsigned int scan_root_bus(device_t root, unsigned int max)
{
outb(0x80, 0x80);
struct device_path path;
device_t debug;
max = root_dev_scan_bus(root, max);
path.type = DEVICE_PATH_PNP;
path.u.pnp.port = 0;
path.u.pnp.device = 0;
debug = alloc_dev(&root->link[1], &path);
debug->ops = &debug_operations;
return max;
}
#endif
#if 0
static void handle_smbus_error(int value, const char *msg)
{
if (value >= 0) {
return;
}
switch(value) {
case SMBUS_WAIT_UNTIL_READY_TIMEOUT:
printk_emerg("SMBUS wait until ready timed out - resetting...");
hard_reset();
break;
case SMBUS_WAIT_UNTIL_DONE_TIMEOUT:
printk_emerg("SMBUS wait until done timed out - resetting...");
hard_reset();
break;
default:
die(msg);
break;
}
}
static int smbus_wait_until_ready(unsigned smbus_io_base)
{
unsigned long loops;
loops = SMBUS_TIMEOUT;
do {
unsigned short val;
smbus_delay();
val = inw(smbus_io_base + SMBGSTATUS);
if ((val & 0x800) == 0) {
break;
}
if(loops == (SMBUS_TIMEOUT / 2)) {
outw(inw(smbus_io_base + SMBGSTATUS),
smbus_io_base + SMBGSTATUS);
}
} while(--loops);
return loops?0:-2;
}
#define ADM1026_DEVICE 0x2c /* 0x2e or 0x2d */
#define ADM1026_REG_CONFIG1 0x00
#define CFG1_MONITOR 0x01
#define CFG1_INT_ENABLE 0x02
#define CFG1_INT_CLEAR 0x04
#define CFG1_AIN8_9 0x08
#define CFG1_THERM_HOT 0x10
#define CFT1_DAC_AFC 0x20
#define CFG1_PWM_AFC 0x40
#define CFG1_RESET 0x80
#define ADM1026_REG_CONFIG2 0x01
#define ADM1026_REG_CONFIG3 0x07
static int smbus_wait_until_done(unsigned smbus_io_base)
#define BILLION 1000000000UL
static void verify_cpu_voltage(const char *name,
device_t dev, unsigned int reg,
unsigned factor, unsigned cpu_volts, unsigned delta)
{
unsigned long loops;
loops = SMBUS_TIMEOUT;
unsigned nvolts_lo, nvolts_hi;
unsigned cpuvolts_hi, cpuvolts_lo;
int value;
int loops;
loops = 1000;
do {
unsigned short val;
smbus_delay();
value = smbus_read_byte(dev, reg);
handle_smbus_error(value, "SMBUS read byte failed");
} while ((--loops > 0) && value == 0);
/* Convert the byte value to nanoVolts.
* My accuracy is nowhere near that good but I don't
* have to round so the math is simple.
* I can only go up to about 4.2 Volts this way so my range is
* limited.
*/
nvolts_lo = ((unsigned)value * factor);
nvolts_hi = nvolts_lo + factor - 1;
/* Get the range of acceptable cpu voltage values */
cpuvolts_lo = cpu_volts - delta;
cpuvolts_hi = cpu_volts + delta;
if ((nvolts_lo < cpuvolts_lo) || (nvolts_hi > cpuvolts_hi)) {
printk_emerg("%s at (%u.%09u-%u.%09u)Volts expected %u.%09u+/-%u.%09uVolts\n",
name,
nvolts_lo/BILLION, nvolts_lo%BILLION,
nvolts_hi/BILLION, nvolts_hi%BILLION,
cpu_volts/BILLION, cpu_volts%BILLION,
delta/BILLION, delta%BILLION);
die("");
}
printk_info("%s at (%u.%09u-%u.%09u)Volts\n",
name,
nvolts_lo/BILLION, nvolts_lo%BILLION,
nvolts_hi/BILLION, nvolts_hi%BILLION);
val = inw(smbus_io_base + SMBGSTATUS);
if (((val & 0x8) == 0) | ((val & 0x437) != 0)) {
break;
}
} while(--loops);
return loops?0:-3;
}
static int smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned value)
static void adm1026_enable_monitoring(device_t dev)
{
unsigned char global_status_register;
int result;
result = smbus_read_byte(dev, ADM1026_REG_CONFIG1);
handle_smbus_error(result, "ADM1026: cannot read config1");
result = (result | CFG1_MONITOR) & ~(CFG1_INT_CLEAR | CFG1_RESET);
result = smbus_write_byte(dev, ADM1026_REG_CONFIG1, result);
handle_smbus_error(result, "ADM1026: cannot write to config1");
result = smbus_read_byte(dev, ADM1026_REG_CONFIG1);
handle_smbus_error(result, "ADM1026: cannot reread config1");
if (!(result & CFG1_MONITOR)) {
die("ADM1026: monitoring would not enable");
}
}
static unsigned k8_cpu_volts(void)
{
unsigned volts = ~0;
if (is_cpu_c0()) {
volts = 1500000000;
}
if (is_cpu_b3()) {
volts = 1550000000;
}
return volts;
}
static void verify_cpu_voltages(device_t dev)
{
unsigned cpu_volts;
unsigned delta;
#if 0
delta = 50000000;
#else
delta = 75000000;
#endif
cpu_volts = k8_cpu_volts();
if (cpu_volts == ~0) {
printk_info("Required cpu voltage unknwon not checking\n");
return;
}
/* I need to read registers 0x37 == Ain7CPU1 core 0x2d == VcppCPU0 core */
/* CPU1 core
* The sensor has a range of 0-2.5V and reports in
* 256 distinct steps.
*/
verify_cpu_voltage("CPU1 Vcore", dev, 0x37, 9765625,
cpu_volts, delta);
/* CPU0 core
* The sensor has range of 0-3.0V and reports in
* 256 distinct steps.
*/
verify_cpu_voltage("CPU0 Vcore", dev, 0x2d, 11718750,
cpu_volts, delta);
}
#define SMBUS_MUX 0x70
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return -2;
}
/* setup transaction */
/* disable interrupts */
outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
/* set the device I'm talking too */
outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
/* set the command/address... */
outb(0, smbus_io_base + SMBHSTCMD);
/* set up for a send byte */
outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
/* clear any lingering errors, so the transaction will run */
/* Do I need to write the bits to a 1 to clear an error? */
outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
/* set the data word...*/
outw(value, smbus_io_base + SMBHSTDAT);
/* start the command */
outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return -3;
}
global_status_register = inw(smbus_io_base + SMBGSTATUS);
if (global_status_register != (1 << 4)) {
return -1;
}
return 0;
}
static int smbus_recv_byte(unsigned smbus_io_base, unsigned device)
{
unsigned char global_status_register;
unsigned char byte;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return -2;
}
/* setup transaction */
/* disable interrupts */
outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
/* set the device I'm talking too */
outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
/* set the command/address... */
outb(0, smbus_io_base + SMBHSTCMD);
/* set up for a send byte */
outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
/* clear any lingering errors, so the transaction will run */
/* Do I need to write the bits to a 1 to clear an error? */
outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
/* set the data word...*/
outw(0, smbus_io_base + SMBHSTDAT);
/* start the command */
outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return -3;
/* Find the smbus mux */
mux_path.type = DEVICE_PATH_I2C;
mux_path.u.i2c.device = SMBUS_MUX;
mux = find_dev_path(smbus_dev, &mux_path);
if (!mux) {
die("SMBUS mux not found\n");
}
global_status_register = inw(smbus_io_base + SMBGSTATUS);
@ -165,119 +271,54 @@ static int smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned add
return -2;
}
/* setup transaction */
/* disable interrupts */
outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
/* set the device I'm talking too */
outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
/* set the command/address... */
outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
/* set up for a byte data read */
outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x2), smbus_io_base + SMBGCTL);
/* Set the mux to see the temperature sensors */
mux_setting = 1;
result = smbus_send_byte(mux, mux_setting);
handle_smbus_error(result, "SMBUS send byte failed\n");
/* clear any lingering errors, so the transaction will run */
/* Do I need to write the bits to a 1 to clear an error? */
outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
/* clear the data word...*/
outw(0, smbus_io_base + SMBHSTDAT);
/* start the command */
outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return -3;
result = smbus_recv_byte(mux);
handle_smbus_error(result, "SMBUS recv byte failed\n");
if (result != mux_setting) {
printk_emerg("SMBUS mux would not set to %d\n", mux_setting);
die("");
}
global_status_register = inw(smbus_io_base + SMBGSTATUS);
adm1026_enable_monitoring(sensor);
/* read results of transaction */
byte = inw(smbus_io_base + SMBHSTDAT) & 0xff;
/* It takes 11.38ms to read a new voltage sensor value */
mdelay(12);
if (global_status_register != (1 << 4)) {
return -1;
}
return byte;
}
static int smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
{
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return -2;
}
/* setup transaction */
/* disable interrupts */
outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)),
smbus_io_base + SMBGCTL);
/* set the device I'm talking too */
outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
/* set up for a byte data write */ /* FIXME */
outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
/* clear any lingering errors, so the transaction will run */
/* Do I need to write the bits to a 1 to clear an error? */
outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
/* clear the data word...*/
outw(val, smbus_io_base + SMBHSTDAT);
/* start the command */
outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return -3;
}
return 0;
/* Read the cpu voltages and make certain everything looks sane */
verify_cpu_voltages(sensor);
}
#else
#define do_verify_cpu_voltages() do {} while(0)
#endif
#define SMBUS_MUX 0x70
static void mainboard_init(device_t dev)
{
/* Set the mux to see the temperature sensors */
dev = dev_find_device(0x1022, 0x746b, 0);
if (dev) {
unsigned smbus_io_base;
unsigned device;
int result;
int mux_setting;
device = SMBUS_MUX;
mux_setting = 1;
smbus_io_base = pci_read_config32(dev, 0x58) & ~1;;
result = smbus_send_byte(smbus_io_base, device, mux_setting);
if ((result < 0) ||
(smbus_recv_byte(smbus_io_base, device) != mux_setting)) {
printk_err("SMBUS mux would not set to %d\n", mux_setting);
}
}
else {
printk_err("SMBUS_controller not found\n");
}
root_dev_init(dev);
do_verify_cpu_voltages();
}
static struct device_operations mainboard_operations = {
.read_resources = root_dev_read_resources,
.set_resources = root_dev_set_resources,
.enable_resources = enable_childrens_resources,
.enable_resources = root_dev_enable_resources,
.init = mainboard_init,
.scan_bus = amdk8_scan_root_bus,
#if !DEBUG
.scan_bus = root_dev_scan_bus,
#else
.scan_bus = scan_root_bus,
#endif
.enable = 0,
};
static void enumerate(struct chip *chip)
{
struct chip *child;
dev_root.ops = &mainboard_operations;
chip->dev = &dev_root;
chip->bus = 0;
for(child = chip->children; child; child = child->next) {
child->bus = &dev_root.link[0];
}
chip_enumerate(chip);
}
struct chip_control mainboard_arima_hdama_control = {
.enumerate = enumerate,

View file

@ -4,7 +4,7 @@
#include <string.h>
#include <stdint.h>
void *smp_write_config_table(void *v, unsigned long * processor_map)
void *smp_write_config_table(void *v)
{
static const char sig[4] = "PCMP";
static const char oem[8] = "LNXI ";
@ -33,7 +33,7 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
mc->mpe_checksum = 0;
mc->reserved = 0;
smp_write_processors(mc, processor_map);
smp_write_processors(mc);
{
device_t dev;
@ -44,7 +44,8 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
bus_isa++;
} else {
}
else {
printk_debug("ERROR - could not find PCI 1:03.0, using defaults\n");
bus_8111_1 = 4;
@ -54,15 +55,20 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
dev = dev_find_slot(1, PCI_DEVFN(0x01,0));
if (dev) {
bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
} else {
}
else {
printk_debug("ERROR - could not find PCI 1:01.0, using defaults\n");
bus_8131_1 = 2;
}
/* 8131-2 */
dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
if (dev) {
bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
} else {
}
else {
printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
bus_8131_2 = 3;
@ -79,20 +85,22 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
smp_write_ioapic(mc, 2, 0x11, 0xfec00000);
{
device_t dev;
uint32_t base;
/* 8131-1 apic #3 */
struct resource *res;
/* 8131 apic 3 */
dev = dev_find_slot(1, PCI_DEVFN(0x01,1));
if (dev) {
base = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
base &= PCI_BASE_ADDRESS_MEM_MASK;
smp_write_ioapic(mc, 0x03, 0x11, base);
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 0x03, 0x11, res->base);
}
}
/* 8131-2 apic #4 */
/* 8131 apic 4 */
dev = dev_find_slot(1, PCI_DEVFN(0x02,1));
if (dev) {
base = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
base &= PCI_BASE_ADDRESS_MEM_MASK;
smp_write_ioapic(mc, 0x04, 0x11, base);
res = find_resource(dev, PCI_BASE_ADDRESS_0);
if (res) {
smp_write_ioapic(mc, 0x04, 0x11, res->base);
}
}
}
@ -193,14 +201,14 @@ void *smp_write_config_table(void *v, unsigned long * processor_map)
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));
mc, smp_next_mpe_entry(mc));
return smp_next_mpe_entry(mc);
}
unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map)
unsigned long write_smp_table(unsigned long addr)
{
void *v;
v = smp_write_floating_table(addr);
return (unsigned long)smp_write_config_table(v, processor_map);
return (unsigned long)smp_write_config_table(v);
}