- 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:
parent
cadfd4c462
commit
b78c1972fe
52 changed files with 1714 additions and 1769 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue