1201_ht_bus0_dev0_fidvid_core.diff
https://openbios.org/roundup/linuxbios/issue41 Lord have mercy upon us. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2118 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
c2455dc0ce
commit
7ce8c54e2b
|
@ -7,7 +7,7 @@ static void hlt(void)
|
|||
__builtin_hlt();
|
||||
}
|
||||
#else
|
||||
static inline void hlt(void)
|
||||
static inline __attribute__((always_inline)) void hlt(void)
|
||||
{
|
||||
asm("hlt");
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ static inline int log2f(int value)
|
|||
|
||||
typedef unsigned device_t;
|
||||
|
||||
static inline uint8_t pci_read_config8(device_t dev, unsigned where)
|
||||
static inline __attribute__((always_inline)) uint8_t pci_read_config8(device_t dev, unsigned where)
|
||||
{
|
||||
unsigned addr;
|
||||
addr = dev | where;
|
||||
|
@ -125,7 +125,7 @@ static inline uint8_t pci_read_config8(device_t dev, unsigned where)
|
|||
return inb(0xCFC + (addr & 3));
|
||||
}
|
||||
|
||||
static inline uint16_t pci_read_config16(device_t dev, unsigned where)
|
||||
static inline __attribute__((always_inline)) uint16_t pci_read_config16(device_t dev, unsigned where)
|
||||
{
|
||||
unsigned addr;
|
||||
addr = dev | where;
|
||||
|
@ -133,7 +133,7 @@ static inline uint16_t pci_read_config16(device_t dev, unsigned where)
|
|||
return inw(0xCFC + (addr & 2));
|
||||
}
|
||||
|
||||
static inline uint32_t pci_read_config32(device_t dev, unsigned where)
|
||||
static inline __attribute__((always_inline)) uint32_t pci_read_config32(device_t dev, unsigned where)
|
||||
{
|
||||
unsigned addr;
|
||||
addr = dev | where;
|
||||
|
@ -141,7 +141,7 @@ static inline uint32_t pci_read_config32(device_t dev, unsigned where)
|
|||
return inl(0xCFC);
|
||||
}
|
||||
|
||||
static inline void pci_write_config8(device_t dev, unsigned where, uint8_t value)
|
||||
static inline __attribute__((always_inline)) void pci_write_config8(device_t dev, unsigned where, uint8_t value)
|
||||
{
|
||||
unsigned addr;
|
||||
addr = dev | where;
|
||||
|
@ -149,7 +149,7 @@ static inline void pci_write_config8(device_t dev, unsigned where, uint8_t value
|
|||
outb(value, 0xCFC + (addr & 3));
|
||||
}
|
||||
|
||||
static inline void pci_write_config16(device_t dev, unsigned where, uint16_t value)
|
||||
static inline __attribute__((always_inline)) void pci_write_config16(device_t dev, unsigned where, uint16_t value)
|
||||
{
|
||||
unsigned addr;
|
||||
addr = dev | where;
|
||||
|
@ -157,7 +157,7 @@ static inline void pci_write_config16(device_t dev, unsigned where, uint16_t val
|
|||
outw(value, 0xCFC + (addr & 2));
|
||||
}
|
||||
|
||||
static inline void pci_write_config32(device_t dev, unsigned where, uint32_t value)
|
||||
static inline __attribute__((always_inline)) void pci_write_config32(device_t dev, unsigned where, uint32_t value)
|
||||
{
|
||||
unsigned addr;
|
||||
addr = dev | where;
|
||||
|
@ -180,53 +180,53 @@ static device_t pci_locate_device(unsigned pci_id, device_t dev)
|
|||
|
||||
|
||||
/* Generic functions for pnp devices */
|
||||
static inline void pnp_write_config(device_t dev, uint8_t reg, uint8_t value)
|
||||
static inline __attribute__((always_inline)) void pnp_write_config(device_t dev, uint8_t reg, uint8_t value)
|
||||
{
|
||||
unsigned port = dev >> 8;
|
||||
outb(reg, port );
|
||||
outb(value, port +1);
|
||||
}
|
||||
|
||||
static inline uint8_t pnp_read_config(device_t dev, uint8_t reg)
|
||||
static inline __attribute__((always_inline)) uint8_t pnp_read_config(device_t dev, uint8_t reg)
|
||||
{
|
||||
unsigned port = dev >> 8;
|
||||
outb(reg, port);
|
||||
return inb(port +1);
|
||||
}
|
||||
|
||||
static inline void pnp_set_logical_device(device_t dev)
|
||||
static inline __attribute__((always_inline)) void pnp_set_logical_device(device_t dev)
|
||||
{
|
||||
unsigned device = dev & 0xff;
|
||||
pnp_write_config(dev, 0x07, device);
|
||||
}
|
||||
|
||||
static inline void pnp_set_enable(device_t dev, int enable)
|
||||
static inline __attribute__((always_inline)) void pnp_set_enable(device_t dev, int enable)
|
||||
{
|
||||
pnp_write_config(dev, 0x30, enable?0x1:0x0);
|
||||
}
|
||||
|
||||
static inline int pnp_read_enable(device_t dev)
|
||||
static inline __attribute__((always_inline)) int pnp_read_enable(device_t dev)
|
||||
{
|
||||
return !!pnp_read_config(dev, 0x30);
|
||||
}
|
||||
|
||||
static inline void pnp_set_iobase(device_t dev, unsigned index, unsigned iobase)
|
||||
static inline __attribute__((always_inline)) void pnp_set_iobase(device_t dev, unsigned index, unsigned iobase)
|
||||
{
|
||||
pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
|
||||
pnp_write_config(dev, index + 1, iobase & 0xff);
|
||||
}
|
||||
|
||||
static inline uint16_t pnp_read_iobase(device_t dev, unsigned index)
|
||||
static inline __attribute__((always_inline)) uint16_t pnp_read_iobase(device_t dev, unsigned index)
|
||||
{
|
||||
return (uint16_t)((pnp_read_config(dev, index) << 8) | pnp_read_config(dev, index + 1));
|
||||
return ((uint16_t)(pnp_read_config(dev, index)) << 8) | pnp_read_config(dev, index + 1);
|
||||
}
|
||||
|
||||
static inline void pnp_set_irq(device_t dev, unsigned index, unsigned irq)
|
||||
static inline __attribute__((always_inline)) void pnp_set_irq(device_t dev, unsigned index, unsigned irq)
|
||||
{
|
||||
pnp_write_config(dev, index, irq);
|
||||
}
|
||||
|
||||
static inline void pnp_set_drq(device_t dev, unsigned index, unsigned drq)
|
||||
static inline __attribute__((always_inline)) void pnp_set_drq(device_t dev, unsigned index, unsigned drq)
|
||||
{
|
||||
pnp_write_config(dev, index, drq & 0xff);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ typedef struct { volatile int counter; } atomic_t;
|
|||
* Atomically increments @v by 1. Note that the guaranteed
|
||||
* useful range of an atomic_t is only 24 bits.
|
||||
*/
|
||||
static __inline__ void atomic_inc(atomic_t *v)
|
||||
static __inline__ __attribute__((always_inline)) void atomic_inc(atomic_t *v)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"lock ; incl %0"
|
||||
|
@ -56,7 +56,7 @@ static __inline__ void atomic_inc(atomic_t *v)
|
|||
* Atomically decrements @v by 1. Note that the guaranteed
|
||||
* useful range of an atomic_t is only 24 bits.
|
||||
*/
|
||||
static __inline__ void atomic_dec(atomic_t *v)
|
||||
static __inline__ __attribute__((always_inline)) void atomic_dec(atomic_t *v)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"lock ; decl %0"
|
||||
|
|
|
@ -40,14 +40,14 @@ typedef struct {
|
|||
#define spin_unlock_string \
|
||||
"movb $1,%0"
|
||||
|
||||
static inline void spin_lock(spinlock_t *lock)
|
||||
static inline __attribute__((always_inline)) void spin_lock(spinlock_t *lock)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
spin_lock_string
|
||||
:"=m" (lock->lock) : : "memory");
|
||||
}
|
||||
|
||||
static inline void spin_unlock(spinlock_t *lock)
|
||||
static inline __attribute__((always_inline)) void spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
spin_unlock_string
|
||||
|
@ -55,7 +55,7 @@ static inline void spin_unlock(spinlock_t *lock)
|
|||
}
|
||||
|
||||
/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
|
||||
static inline void cpu_relax(void)
|
||||
static inline __attribute__((always_inline)) void cpu_relax(void)
|
||||
{
|
||||
__asm__ __volatile__("rep;nop": : :"memory");
|
||||
}
|
||||
|
|
|
@ -22,18 +22,20 @@ _start:
|
|||
leal _stack, %edi
|
||||
movl $_estack, %ecx
|
||||
subl %edi, %ecx
|
||||
shrl $2, %ecx /* it is 32 bit align, right? */
|
||||
xorl %eax, %eax
|
||||
rep
|
||||
stosb
|
||||
stosl
|
||||
|
||||
/** clear bss */
|
||||
leal _bss, %edi
|
||||
movl $_ebss, %ecx
|
||||
subl %edi, %ecx
|
||||
jz .Lnobss
|
||||
shrl $2, %ecx /* it is 32 bit align, right? */
|
||||
xorl %eax, %eax
|
||||
rep
|
||||
stosb
|
||||
stosl
|
||||
.Lnobss:
|
||||
|
||||
/* set new stack */
|
||||
|
|
|
@ -120,58 +120,8 @@ static void print_spew_hex16(unsigned short value){ __console_tx_hex16(BIOS_SPEW
|
|||
static void print_spew_hex32(unsigned int value) { __console_tx_hex32(BIOS_SPEW, value); }
|
||||
static void print_spew(const char *str) { __console_tx_string(BIOS_SPEW, str); }
|
||||
|
||||
/* Non inline versions.... */
|
||||
#if 0
|
||||
static void print_alert_char_(unsigned char value) NOINLINE { print_alert_char(value); }
|
||||
static void print_alert_hex8_(unsigned char value) NOINLINE { print_alert_hex8(value); }
|
||||
static void print_alert_hex16_(unsigned short value) NOINLINE { print_alert_hex16(value); }
|
||||
static void print_alert_hex32_(unsigned int value) NOINLINE { print_alert_hex32(value); }
|
||||
static void print_alert_(const char *str) NOINLINE { print_alert(str); }
|
||||
|
||||
static void print_crit_char_(unsigned char value) NOINLINE { print_crit_char(value); }
|
||||
static void print_crit_hex8_(unsigned char value) NOINLINE { print_crit_hex8(value); }
|
||||
static void print_crit_hex16_(unsigned short value) NOINLINE { print_crit_hex16(value); }
|
||||
static void print_crit_hex32_(unsigned int value) NOINLINE { print_crit_hex32(value); }
|
||||
static void print_crit_(const char *str) NOINLINE { print_crit(str); }
|
||||
|
||||
static void print_err_char_(unsigned char value) NOINLINE { print_err_char(value); }
|
||||
static void print_err_hex8_(unsigned char value) NOINLINE { print_err_hex8(value); }
|
||||
static void print_err_hex16_(unsigned short value) NOINLINE { print_err_hex16(value); }
|
||||
static void print_err_hex32_(unsigned int value) NOINLINE { print_err_hex32(value); }
|
||||
static void print_err_(const char *str) NOINLINE { print_err(str); }
|
||||
|
||||
static void print_warning_char_(unsigned char value) NOINLINE { print_warning_char(value); }
|
||||
static void print_warning_hex8_(unsigned char value) NOINLINE { print_warning_hex8(value); }
|
||||
static void print_warning_hex16_(unsigned short value) NOINLINE { print_warning_hex16(value); }
|
||||
static void print_warning_hex32_(unsigned int value) NOINLINE { print_warning_hex32(value); }
|
||||
static void print_warning_(const char *str) NOINLINE { print_warning(str); }
|
||||
|
||||
static void print_notice_char_(unsigned char value) NOINLINE { print_notice_char(value); }
|
||||
static void print_notice_hex8_(unsigned char value) NOINLINE { print_notice_hex8(value); }
|
||||
static void print_notice_hex16_(unsigned short value) NOINLINE { print_notice_hex16(value); }
|
||||
static void print_notice_hex32_(unsigned int value) NOINLINE { print_notice_hex32(value); }
|
||||
static void print_notice_(const char *str) NOINLINE { print_notice(str); }
|
||||
|
||||
static void print_info_char_(unsigned char value) NOINLINE { print_info_char(value); }
|
||||
static void print_info_hex8_(unsigned char value) NOINLINE { print_info_hex8(value); }
|
||||
static void print_info_hex16_(unsigned short value) NOINLINE { print_info_hex16(value); }
|
||||
static void print_info_hex32_(unsigned int value) NOINLINE { print_info_hex32(value); }
|
||||
static void print_info_(const char *str) NOINLINE { print_info(str); }
|
||||
|
||||
static void print_debug_char_(unsigned char value) NOINLINE { print_debug_char(value); }
|
||||
static void print_debug_hex8_(unsigned char value) NOINLINE { print_debug_hex8(value); }
|
||||
static void print_debug_hex16_(unsigned short value) NOINLINE { print_debug_hex16(value); }
|
||||
static void print_debug_hex32_(unsigned int value) NOINLINE { print_debug_hex32(value); }
|
||||
static void print_debug_(const char *str) NOINLINE { print_debug(str); }
|
||||
|
||||
static void print_spew_char_(unsigned char value) NOINLINE { print_spew_char(value); }
|
||||
static void print_spew_hex8_(unsigned char value) NOINLINE { print_spew_hex8(value); }
|
||||
static void print_spew_hex16_(unsigned short value) NOINLINE { print_spew_hex16(value); }
|
||||
static void print_spew_hex32_(unsigned int value) NOINLINE { print_spew_hex32(value); }
|
||||
static void print_spew_(const char *str) NOINLINE { print_spew(str); }
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* CONFIG_USE_INIT == 1 */
|
||||
|
||||
extern int do_printk(int msg_level, const char *fmt, ...);
|
||||
|
||||
|
@ -273,12 +223,13 @@ extern int do_printk(int msg_level, const char *fmt, ...);
|
|||
#define print_spew_hex32(HEX) printk_spew ("%08x", (HEX))
|
||||
|
||||
|
||||
#endif /* CONFIG_USE_INIT == 0 */
|
||||
#endif /* CONFIG_USE_INIT */
|
||||
|
||||
#ifndef LINUXBIOS_EXTRA_VERSION
|
||||
#define LINUXBIOS_EXTRA_VERSION ""
|
||||
#endif
|
||||
|
||||
|
||||
static void console_init(void)
|
||||
{
|
||||
static const char console_test[] =
|
||||
|
|
|
@ -815,6 +815,30 @@ define CK804_DEVN_BASE
|
|||
comment "CK804 device count from 0 or 1"
|
||||
end
|
||||
|
||||
define HT_CHAIN_UNITID_BASE
|
||||
default 1
|
||||
export always
|
||||
comment "this will be first hypertransport device's unitid base, if sb ht chain only has one ht device, it could be 0"
|
||||
end
|
||||
|
||||
define HT_CHAIN_END_UNITID_BASE
|
||||
default 0x20
|
||||
export always
|
||||
comment "this will be unit id of the end of hypertransport chain (usually the real SB) if it is small than HT_CHAIN_UNITID_BASE, it could be 0"
|
||||
end
|
||||
|
||||
define SB_HT_CHAIN_UNITID_OFFSET_ONLY
|
||||
default 1
|
||||
export always
|
||||
comment "this will decided if only offset SB hypertransport chain"
|
||||
end
|
||||
|
||||
define K8_SB_HT_CHAIN_ON_BUS0
|
||||
default 0
|
||||
export always
|
||||
comment "this will make SB hypertransport chain sit on bus 0"
|
||||
end
|
||||
|
||||
define K8_HW_MEM_HOLE_SIZEK
|
||||
default 0
|
||||
export always
|
||||
|
|
|
@ -57,9 +57,10 @@ unsigned char console_rx_byte(void)
|
|||
struct console_driver *driver;
|
||||
if (!initialized)
|
||||
return 0;
|
||||
for(driver = console_drivers; driver < econsole_drivers; driver++)
|
||||
for(driver = console_drivers; driver < econsole_drivers; driver++) {
|
||||
if (driver->tst_byte)
|
||||
break;
|
||||
}
|
||||
if (driver == econsole_drivers)
|
||||
return 0;
|
||||
while (!driver->tst_byte());
|
||||
|
|
|
@ -25,7 +25,7 @@ int default_console_loglevel = DEFAULT_CONSOLE_LOGLEVEL;
|
|||
void display(char*);
|
||||
extern int vtxprintf(void (*)(unsigned char), const char *, va_list);
|
||||
|
||||
spinlock_t console_lock = SPIN_LOCK_UNLOCKED;
|
||||
static spinlock_t console_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
int do_printk(int msg_level, const char *fmt, ...)
|
||||
{
|
||||
|
|
|
@ -15,11 +15,7 @@ static char *vidmem;
|
|||
|
||||
int vga_line, vga_col;
|
||||
|
||||
#if CONFIG_CONSOLE_VGA == 1
|
||||
extern int vga_inited; // it will be changed in pci_rom.c
|
||||
#else
|
||||
int vga_inited = 0;
|
||||
#endif
|
||||
int vga_inited = 0; // it will be changed in pci_rom.c
|
||||
|
||||
static int vga_console_inited = 0;
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* by yhlu 6.2005 */
|
||||
/* be warned, this file will be used core 0/node 0 only */
|
||||
static inline __attribute__((always_inline)) void clear_1m_ram(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
|
||||
/* disable cache */
|
||||
|
@ -51,3 +53,4 @@
|
|||
"invd\n\t"
|
||||
|
||||
);
|
||||
}
|
||||
|
|
|
@ -28,10 +28,18 @@
|
|||
#define GETBIT(bb, src, ilen) GETBIT_LE32(bb, src, ilen)
|
||||
#endif
|
||||
|
||||
static inline void print_debug_cp_run(const char *strval, uint32_t val)
|
||||
{
|
||||
#if CONFIG_USE_INIT
|
||||
printk_debug("%s%08x\r\n", strval, val);
|
||||
#else
|
||||
print_debug(strval); print_debug_hex32(val); print_debug("\r\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void copy_and_run(unsigned cpu_reset)
|
||||
{
|
||||
uint8_t *src, *dst;
|
||||
unsigned long dst_len;
|
||||
unsigned long ilen = 0, olen = 0, last_m_off = 1;
|
||||
uint32_t bb = 0;
|
||||
unsigned bc = 0;
|
||||
|
@ -44,9 +52,9 @@ static void copy_and_run(unsigned cpu_reset)
|
|||
"leal _iseg, %1\n\t"
|
||||
"leal _eiseg, %2\n\t"
|
||||
"subl %1, %2\n\t"
|
||||
: "=a" (src), "=b" (dst), "=c" (dst_len)
|
||||
: "=a" (src), "=b" (dst), "=c" (olen)
|
||||
);
|
||||
memcpy(src, dst, dst_len);
|
||||
memcpy(src, dst, olen);
|
||||
#else
|
||||
|
||||
__asm__ volatile (
|
||||
|
@ -55,13 +63,10 @@ static void copy_and_run(unsigned cpu_reset)
|
|||
: "=a" (src) , "=b" (dst)
|
||||
);
|
||||
|
||||
#if CONFIG_USE_INIT
|
||||
printk_debug("src=%08x\r\n",src);
|
||||
printk_debug("dst=%08x\r\n",dst);
|
||||
#else
|
||||
print_debug("src="); print_debug_hex32(src); print_debug("\r\n");
|
||||
print_debug("dst="); print_debug_hex32(dst); print_debug("\r\n");
|
||||
#endif
|
||||
print_debug_cp_run("src=",(uint32_t)src);
|
||||
print_debug_cp_run("dst=",(uint32_t)dst);
|
||||
|
||||
// dump_mem(src, src+0x100);
|
||||
|
||||
for(;;) {
|
||||
unsigned int m_off, m_len;
|
||||
|
@ -105,11 +110,9 @@ static void copy_and_run(unsigned cpu_reset)
|
|||
}
|
||||
#endif
|
||||
// dump_mem(dst, dst+0x100);
|
||||
#if CONFIG_USE_INIT
|
||||
printk_debug("linxbios_ram.bin length = %08x\r\n", olen);
|
||||
#else
|
||||
print_debug("linxbios_ram.bin length = "); print_debug_hex32(olen); print_debug("\r\n");
|
||||
#endif
|
||||
|
||||
print_debug_cp_run("linxbios_ram.bin length = ", olen);
|
||||
|
||||
print_debug("Jumping to LinuxBIOS.\r\n");
|
||||
|
||||
if(cpu_reset == 1 ) {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
/* by yhlu 6.2005 */
|
||||
/* be warned, this file will be used other cores and core 0 / node 0 */
|
||||
static inline __attribute__((always_inline)) void disable_cache_as_ram(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
/*
|
||||
FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.
|
||||
It is only needed if we want to go back
|
||||
*/
|
||||
|
||||
/* We don't need cache as ram for now on */
|
||||
/* disable cache */
|
||||
"movl %cr0, %eax\n\t"
|
||||
|
@ -42,5 +43,5 @@
|
|||
"movl %cr0, %eax\n\t"
|
||||
"andl $0x9fffffff,%eax\n\t"
|
||||
"movl %eax, %cr0\n\t"
|
||||
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1 @@
|
|||
uses CONFIG_LOGICAL_CPUS
|
||||
|
||||
if CONFIG_LOGICAL_CPUS
|
||||
object amd_sibling.o
|
||||
end
|
||||
|
|
|
@ -1,21 +1,26 @@
|
|||
/* 2004.12 yhlu add dual core support */
|
||||
|
||||
|
||||
#ifndef SET_NB_CFG_54
|
||||
#define SET_NB_CFG_54 1
|
||||
#endif
|
||||
|
||||
#include "cpu/amd/dualcore/dualcore_id.c"
|
||||
|
||||
static inline unsigned get_core_num_in_bsp(unsigned nodeid)
|
||||
{
|
||||
return ((pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8)>>12) & 3);
|
||||
uint32_t dword;
|
||||
dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8);
|
||||
dword >>= 12;
|
||||
dword &= 3;
|
||||
return dword;
|
||||
}
|
||||
|
||||
#if SET_NB_CFG_54 == 1
|
||||
static inline uint8_t set_apicid_cpuid_lo(void)
|
||||
{
|
||||
if(is_cpu_pre_e0()) return 0; // pre_e0 can not be set
|
||||
|
||||
|
||||
if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) { // disable dual_core
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set the NB_CFG[54]=1; why the OS will be happy with that ???
|
||||
msr_t msr;
|
||||
msr = rdmsr(NB_CFG_MSR);
|
||||
|
@ -23,9 +28,45 @@ static inline uint8_t set_apicid_cpuid_lo(void)
|
|||
wrmsr(NB_CFG_MSR, msr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
|
||||
static inline void set_apicid_cpuid_lo(void) { }
|
||||
|
||||
#endif
|
||||
|
||||
static inline void real_start_other_core(unsigned nodeid)
|
||||
{
|
||||
uint32_t dword;
|
||||
// set PCI_DEV(0, 0x18+nodeid, 3), 0x44 bit 27 to redirect all MC4 accesses and error logging to core0
|
||||
dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44);
|
||||
dword |= 1<<27; // NbMcaToMstCpuEn bit
|
||||
pci_write_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44, dword);
|
||||
// set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1
|
||||
dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68);
|
||||
dword |= 1<<5;
|
||||
pci_write_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68, dword);
|
||||
}
|
||||
|
||||
//it is running on core0 of node0
|
||||
static inline void start_other_cores(void)
|
||||
{
|
||||
unsigned nodes;
|
||||
unsigned nodeid;
|
||||
|
||||
if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) { // disable dual_core
|
||||
return;
|
||||
}
|
||||
|
||||
nodes = get_nodes();
|
||||
|
||||
for(nodeid=0; nodeid<nodes; nodeid++) {
|
||||
if( get_core_num_in_bsp(nodeid) > 0) {
|
||||
real_start_other_core(nodeid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#if USE_DCACHE_RAM == 0
|
||||
static void do_k8_init_and_stop_secondaries(void)
|
||||
{
|
||||
|
@ -62,7 +103,26 @@ static void do_k8_init_and_stop_secondaries(void)
|
|||
pci_write_config32(dev_f0, 0x68, val);
|
||||
|
||||
/* Set the lapicid */
|
||||
lapic_write(LAPIC_ID,(0x10 + id.coreid*0x10 + id.nodeid) << 24);
|
||||
#if (ENABLE_APIC_EXT_ID == 1)
|
||||
unsigned initial_apicid = get_initial_apicid();
|
||||
#if LIFT_BSP_APIC_ID == 0
|
||||
if( initial_apicid != 0 ) // other than bsp
|
||||
#endif
|
||||
{
|
||||
/* use initial apic id to lift it */
|
||||
uint32_t dword = lapic_read(LAPIC_ID);
|
||||
dword &= ~(0xff<<24);
|
||||
dword |= (((initial_apicid + APIC_ID_OFFSET) & 0xff)<<24);
|
||||
|
||||
lapic_write(LAPIC_ID, dword);
|
||||
}
|
||||
|
||||
#if LIFT_BSP_APIC_ID == 1
|
||||
bsp_apicid += APIC_ID_OFFSET;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Remember the cpuid */
|
||||
if (id.coreid == 0) {
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
/* 2004.12 yhlu add dual core support */
|
||||
|
||||
#include <arch/cpu.h>
|
||||
#include <cpu/amd/dualcore.h>
|
||||
#ifdef __ROMCC__
|
||||
#include <cpu/amd/model_fxx_msr.h>
|
||||
#endif
|
||||
|
||||
static inline unsigned int read_nb_cfg_54(void)
|
||||
//called by bus_cpu_scan too
|
||||
unsigned int read_nb_cfg_54(void)
|
||||
{
|
||||
msr_t msr;
|
||||
msr = rdmsr(NB_CFG_MSR);
|
||||
return ( ( msr.hi >> (54-32)) & 1);
|
||||
}
|
||||
|
||||
struct node_core_id {
|
||||
unsigned nodeid:8;
|
||||
unsigned coreid:8;
|
||||
};
|
||||
|
||||
static inline unsigned get_initial_apicid(void)
|
||||
{
|
||||
return ((cpuid_ebx(1) >> 24) & 0xf);
|
||||
}
|
||||
|
||||
static inline struct node_core_id get_node_core_id(unsigned nb_cfg_54) {
|
||||
//called by amd_siblings too
|
||||
struct node_core_id get_node_core_id(unsigned nb_cfg_54)
|
||||
{
|
||||
struct node_core_id id;
|
||||
// get the apicid via cpuid(1) ebx[27:24]
|
||||
if( nb_cfg_54) {
|
||||
|
@ -45,6 +46,7 @@ static inline unsigned get_core_num(void)
|
|||
}
|
||||
|
||||
static inline struct node_core_id get_node_core_id_x(void) {
|
||||
return get_node_core_id( read_nb_cfg_54() );
|
||||
|
||||
return get_node_core_id( read_nb_cfg_54() ); // for pre_e0() nb_cfg_54 always be 0
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,13 @@ void init_timer(void)
|
|||
{
|
||||
/* Set the apic timer to no interrupts and periodic mode */
|
||||
lapic_write(LAPIC_LVTT, (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0));
|
||||
|
||||
/* Set the divider to 1, no divider */
|
||||
lapic_write(LAPIC_TDCR, LAPIC_TDR_DIV_1);
|
||||
|
||||
/* Set the initial counter to 0xffffffff */
|
||||
lapic_write(LAPIC_TMICT, 0xffffffff);
|
||||
|
||||
}
|
||||
|
||||
void udelay(unsigned usecs)
|
||||
|
|
|
@ -0,0 +1,396 @@
|
|||
#if K8_SET_FIDVID == 1
|
||||
|
||||
#define K8_SET_FIDVID_DEBUG 0
|
||||
|
||||
#define K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST 1
|
||||
|
||||
static inline void print_debug_fv(const char *str, unsigned val)
|
||||
{
|
||||
#if K8_SET_FIDVID_DEBUG == 1
|
||||
#if CONFIG_USE_INIT==1
|
||||
printk_debug("%s%x\r\n", str, val);
|
||||
#else
|
||||
print_debug(str); print_debug_hex32(val); print_debug("\r\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void print_debug_fv_8(const char *str, unsigned val)
|
||||
{
|
||||
#if K8_SET_FIDVID_DEBUG == 1
|
||||
#if CONFIG_USE_INIT==1
|
||||
printk_debug("%s%02x\r\n", str, val);
|
||||
#else
|
||||
print_debug(str); print_debug_hex8(val); print_debug("\r\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void print_debug_fv_64(const char *str, unsigned val, unsigned val2)
|
||||
{
|
||||
#if K8_SET_FIDVID_DEBUG == 1
|
||||
#if CONFIG_USE_INIT==1
|
||||
printk_debug("%s%x%x\r\n", str, val, val2);
|
||||
#else
|
||||
print_debug(str); print_debug_hex32(val); print_debug_hex32(val2); print_debug("\r\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void enable_fid_change(void)
|
||||
{
|
||||
uint32_t dword;
|
||||
unsigned nodes;
|
||||
int i;
|
||||
|
||||
nodes = ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
|
||||
|
||||
for(i=0; i<nodes; i++) {
|
||||
dword = pci_read_config32(PCI_DEV(0, 0x18+i, 3), 0xd8);
|
||||
dword &= 0x8ff00000;
|
||||
dword |= (2<<28) | (0x02710);
|
||||
pci_write_config32(PCI_DEV(0, 0x18+i, 3), 0xd8, dword);
|
||||
|
||||
dword = 0x04e2a707;
|
||||
pci_write_config32(PCI_DEV(0, 0x18+i, 3), 0xd4, dword);
|
||||
|
||||
dword = pci_read_config32(PCI_DEV(0, 0x18+i, 2), 0x94);
|
||||
dword |= (1<<14);// disable the DRAM interface at first, it will be enabled by raminit again
|
||||
pci_write_config32(PCI_DEV(0, 0x18+i, 2), 0x94, dword);
|
||||
|
||||
dword = 0x23070000; //enable FID/VID change
|
||||
// dword = 0x00070000; //enable FID/VID change
|
||||
pci_write_config32(PCI_DEV(0, 0x18+i, 3), 0x80, dword);
|
||||
|
||||
dword = 0x00132113;
|
||||
pci_write_config32(PCI_DEV(0, 0x18+i, 3), 0x84, dword);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned set_fidvid(unsigned apicid, unsigned fidvid, int showmessage)
|
||||
{
|
||||
//for (cur, new) there is one <1600MHz x8 to find out next_fid
|
||||
const static uint8_t next_fid_a[] = {
|
||||
/* x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 */ // 0:x4, 2:x5....BASE=4, MIN=4, MAX=25, INC=2 result = (xX-BASE)*INC
|
||||
/* x4 */ 0, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
/* x5 */ 9, 0, 11, 11, 9, 9, 10, 11, 11, 11, 11, 11,
|
||||
/* x6 */ 11, 11, 0, 13, 11, 11, 11, 11, 12, 13, 13, 13,
|
||||
/* x7 */ 13, 13, 13, 0, 13, 13, 13, 13, 13, 13, 14, 15,
|
||||
/* x8 */ 4, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9,
|
||||
/* x9 */ 4, 5, 10, 10, 8, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*x10 */ 9, 5, 11, 11, 9, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*x11 */ 10, 5, 6, 12, 10, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*x12 */ 11, 11, 6, 13, 11, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*x13 */ 12, 12, 6, 7, 12, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*x14 */ 13, 13, 13, 7, 13, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*x15 */ 14, 14, 14, 7, 14, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
msr_t msr;
|
||||
uint32_t vid;
|
||||
uint32_t fid;
|
||||
uint32_t vid_max;
|
||||
uint32_t fid_max;
|
||||
uint32_t vid_cur;
|
||||
uint32_t fid_cur;
|
||||
unsigned apicidx;
|
||||
|
||||
int steps;
|
||||
int loop;
|
||||
|
||||
apicidx = lapicid();
|
||||
|
||||
if(apicid!=apicidx) {
|
||||
#if CONFIG_USE_INIT == 1
|
||||
printk_err("wrong apicid, we want change %x, but it is %x\r\n", apicid, apicidx);
|
||||
#else
|
||||
print_err("wrong apicid, we want change "); print_err_hex8(apicid); print_err(" but it is "); print_err_hex8(apicidx); print_err("\r\n");
|
||||
#endif
|
||||
return fidvid;
|
||||
}
|
||||
|
||||
fid = (fidvid >> 8) & 0x3f;
|
||||
vid = (fidvid >> 16) & 0x3f;
|
||||
|
||||
msr = rdmsr(0xc0010042);
|
||||
|
||||
vid_cur = msr.hi & 0x3f;
|
||||
fid_cur = msr.lo & 0x3f;
|
||||
|
||||
if((vid_cur==vid) && (fid_cur==fid)) return fidvid;
|
||||
|
||||
vid_max = (msr.hi>>(48-32)) & 0x3f;
|
||||
fid_max = (msr.lo>>16) & 0x3f;
|
||||
|
||||
//set vid to max
|
||||
msr.hi = 1;
|
||||
msr.lo = (vid_max<<8) | (fid_cur);
|
||||
msr.lo |= (1<<16); // init changes
|
||||
wrmsr(0xc0010041, msr);
|
||||
|
||||
for(loop=0;loop<100000;loop++){
|
||||
msr = rdmsr(0xc0010042);
|
||||
if(!(msr.lo & (1<<31))) break;
|
||||
}
|
||||
vid_cur = msr.hi & 0x3f;
|
||||
|
||||
steps = 8; //??
|
||||
while((fid_cur!=fid) && (steps-->0)) {
|
||||
uint32_t fid_temp;
|
||||
if((fid_cur > (8-4)*2) && (fid> (8-4)*2)) {
|
||||
if(fid_cur<fid) {
|
||||
fid_temp = fid_cur + 2;
|
||||
} else {
|
||||
fid_temp = fid_cur - 2;
|
||||
}
|
||||
}
|
||||
else { //there is one < 8, So we need to lookup the table to find the fid_cur
|
||||
int temp;
|
||||
temp = next_fid_a[(fid_cur/2)*12+(fid/2)];
|
||||
if(temp <= 0) break;
|
||||
fid_temp = (temp-4) * 2;
|
||||
}
|
||||
if(fid_temp>fid_max) break;
|
||||
|
||||
fid_cur = fid_temp;
|
||||
|
||||
//set target fid
|
||||
msr.hi = (100000/5);
|
||||
msr.lo = (vid_cur<<8) | fid_cur;
|
||||
msr.lo |= (1<<16); // init changes
|
||||
wrmsr(0xc0010041, msr);
|
||||
|
||||
|
||||
#if K8_SET_FIDVID_DEBUG == 1
|
||||
if(showmessage) {
|
||||
print_debug_fv_8("\tapicid in set_fidvid = ", apicid);
|
||||
print_debug_fv_64("ctrl msr fid, vid ", msr.hi, msr.lo);
|
||||
}
|
||||
#endif
|
||||
|
||||
for(loop=0;loop<100000;loop++){
|
||||
msr = rdmsr(0xc0010042);
|
||||
if(!(msr.lo & (1<<31))) break;
|
||||
}
|
||||
fid_cur = msr.lo & 0x3f;
|
||||
|
||||
#if K8_SET_FIDVID_DEBUG == 1
|
||||
if(showmessage) {
|
||||
print_debug_fv_64("status msr fid, vid ", msr.hi, msr.lo);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//set vid to final
|
||||
msr.hi = 1;
|
||||
msr.lo = (vid<<8) | (fid_cur);
|
||||
msr.lo |= (1<<16); // init changes
|
||||
wrmsr(0xc0010041, msr);
|
||||
|
||||
for(loop=0;loop<100000;loop++){
|
||||
msr = rdmsr(0xc0010042);
|
||||
if(!(msr.lo & (1<<31))) break;
|
||||
}
|
||||
vid_cur = msr.hi & 0x3f;
|
||||
|
||||
fidvid = (vid_cur<< 16) | (fid_cur<<8);
|
||||
|
||||
if(showmessage) {
|
||||
if((fid!=fid_cur) || (vid!=vid_cur)) {
|
||||
print_err("set fidvid failed\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
return fidvid;
|
||||
|
||||
}
|
||||
|
||||
static void init_fidvid_ap(unsigned bsp_apicid, unsigned apicid)
|
||||
{
|
||||
|
||||
uint32_t send;
|
||||
uint32_t readback;
|
||||
msr_t msr;
|
||||
uint32_t vid_cur;
|
||||
uint32_t fid_cur;
|
||||
int loop;
|
||||
|
||||
msr = rdmsr(0xc0010042);
|
||||
send = ((msr.lo>>16) & 0x3f) << 8; //max fid
|
||||
send |= ((msr.hi>>(48-32)) & 0x3f) << 16; //max vid
|
||||
send |= (apicid<<24); // ap apicid
|
||||
|
||||
vid_cur = msr.hi & 0x3f;
|
||||
fid_cur = msr.lo & 0x3f;
|
||||
|
||||
// set to current
|
||||
msr.hi = 1;
|
||||
msr.lo = (vid_cur<<8) | (fid_cur);
|
||||
wrmsr(0xc0010041, msr);
|
||||
|
||||
wait_cpu_state(bsp_apicid, 1);
|
||||
//send signal to BSP about this AP max fid and vid
|
||||
lapic_write(LAPIC_MSG_REG, send | 1); //AP at state 1 that sent our fid and vid
|
||||
|
||||
// wait_cpu_state(bsp_apicid, 2);// don't need we can use apicid directly
|
||||
loop = 100000;
|
||||
while(--loop>0) {
|
||||
//remote read BSP signal that include vid and fid that need to set
|
||||
if(lapic_remote_read(bsp_apicid, LAPIC_MSG_REG, &readback)!=0) continue;
|
||||
if(((readback>>24) & 0xff) == apicid) break; // it is this cpu turn
|
||||
}
|
||||
|
||||
if(loop>0) {
|
||||
readback = set_fidvid(apicid, readback & 0xffff00, 1); // this AP
|
||||
//send signal to BSP that this AP fid/vid is set // allow to change state2 is together with apicid
|
||||
send = (apicid<<24) | (readback & 0x00ffff00); // AP at state that We set the requested fid/vid
|
||||
}
|
||||
|
||||
lapic_write(LAPIC_MSG_REG, send | 2);
|
||||
|
||||
wait_cpu_state(bsp_apicid, 3);
|
||||
}
|
||||
|
||||
static unsigned calc_common_fidvid(unsigned fidvid, unsigned fidvidx)
|
||||
{
|
||||
/* FIXME: need to check the change path to verify if it is reachable when common fid is small than 1.6G */
|
||||
if((fidvid & 0xff00)<=(fidvidx & 0xff00)) {
|
||||
return fidvid;
|
||||
}
|
||||
else {
|
||||
return fidvidx;
|
||||
}
|
||||
}
|
||||
|
||||
struct fidvid_st {
|
||||
unsigned common_fidvid;
|
||||
};
|
||||
|
||||
static void init_fidvid_bsp_stage1(unsigned ap_apicid, void *gp )
|
||||
{
|
||||
unsigned readback;
|
||||
|
||||
struct fidvid_st *fvp = gp;
|
||||
int loop;
|
||||
|
||||
print_debug_fv("state 1: ap_apicid=", ap_apicid);
|
||||
|
||||
loop = 100000;
|
||||
while(--loop > 0) {
|
||||
if(lapic_remote_read(ap_apicid, LAPIC_MSG_REG, &readback)!=0) continue;
|
||||
if((readback & 0xff) == 1) break; //target ap is in stage 1
|
||||
}
|
||||
|
||||
print_debug_fv("\treadback=", readback);
|
||||
|
||||
fvp->common_fidvid = calc_common_fidvid(fvp->common_fidvid, readback & 0xffff00);
|
||||
|
||||
print_debug_fv("\tcommon_fidvid=", fvp->common_fidvid);
|
||||
|
||||
}
|
||||
static void init_fidvid_bsp_stage2(unsigned ap_apicid, void *gp)
|
||||
{
|
||||
unsigned readback;
|
||||
|
||||
struct fidvid_st *fvp = gp;
|
||||
int loop;
|
||||
|
||||
print_debug_fv("state 2: ap_apicid=", ap_apicid);
|
||||
|
||||
lapic_write(LAPIC_MSG_REG, fvp->common_fidvid | (ap_apicid<<24) | 2); // all set to state2
|
||||
|
||||
loop = 100000;
|
||||
while(--loop > 0) {
|
||||
if(lapic_remote_read(ap_apicid, LAPIC_MSG_REG, &readback)!=0) continue;
|
||||
if((readback & 0xff) == 2) break; // target ap is stage 2, and it'd FID has beed set
|
||||
}
|
||||
|
||||
print_debug_fv("\treadback=", readback);
|
||||
}
|
||||
|
||||
#if K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST == 1
|
||||
struct ap_apicid_st {
|
||||
unsigned num;
|
||||
unsigned apicid[16]; // 8 way dual core need 16
|
||||
/* FIXME: 32 node quad core, may need 128 */
|
||||
};
|
||||
|
||||
static void store_ap_apicid(unsigned ap_apicid, void *gp)
|
||||
{
|
||||
struct ap_apicid_st *p = gp;
|
||||
|
||||
p->apicid[p->num++] = ap_apicid;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static void init_fidvid_bsp(unsigned bsp_apicid)
|
||||
{
|
||||
uint32_t vid_max;
|
||||
uint32_t fid_max;
|
||||
|
||||
struct fidvid_st fv;
|
||||
|
||||
#if K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST == 1
|
||||
struct ap_apicid_st ap_apicidx;
|
||||
unsigned i;
|
||||
#endif
|
||||
|
||||
|
||||
msr_t msr;
|
||||
msr = rdmsr(0xc0010042);
|
||||
fid_max = ((msr.lo>>16) & 0x3f); //max fid
|
||||
vid_max = ((msr.hi>>(48-32)) & 0x3f); //max vid
|
||||
fv.common_fidvid = (fid_max<<8)|(vid_max<<16);
|
||||
|
||||
|
||||
// for all APs (We know the APIC ID of all APs even the APIC ID is lifted)
|
||||
// remote read from AP about max fid/vid
|
||||
|
||||
//let all ap trains to state 1
|
||||
lapic_write(LAPIC_MSG_REG, (bsp_apicid<<24) | 1);
|
||||
|
||||
// calculate the common max fid/vid that could be used for all APs and BSP
|
||||
#if K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST == 1
|
||||
ap_apicidx.num = 0;
|
||||
|
||||
for_each_ap(bsp_apicid, K8_SET_FIDVID_CORE0_ONLY, store_ap_apicid, &ap_apicidx);
|
||||
|
||||
for(i=0;i<ap_apicidx.num;i++) {
|
||||
init_fidvid_bsp_stage1(ap_apicidx.apicid[i], &fv);
|
||||
}
|
||||
#else
|
||||
for_each_ap(bsp_apicid, K8_SET_FIDVID_CORE0_ONLY, init_fidvid_bsp_stage1, &fv);
|
||||
#endif
|
||||
|
||||
|
||||
// set BSP fid and vid
|
||||
print_debug_fv("bsp apicid=", bsp_apicid);
|
||||
fv.common_fidvid = set_fidvid(bsp_apicid, fv.common_fidvid, 1);
|
||||
print_debug_fv("common_fidvid=", fv.common_fidvid);
|
||||
|
||||
|
||||
//for all APs ( We know the APIC ID of all AP even the APIC ID is lifted)
|
||||
// send signal to the AP it could change it's fid/vid
|
||||
// remote read singnal from AP that AP is done
|
||||
|
||||
fv.common_fidvid &= 0xffff00;
|
||||
|
||||
//set state 2 allow is in init_fidvid_bsp_stage2
|
||||
#if K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST == 1
|
||||
for(i=0;i<ap_apicidx.num;i++) {
|
||||
init_fidvid_bsp_stage2(ap_apicidx.apicid[i], &fv);
|
||||
}
|
||||
#else
|
||||
for_each_ap(bsp_apicid, K8_SET_FIDVID_CORE0_ONLY, init_fidvid_bsp_stage2, &fv);
|
||||
#endif
|
||||
|
||||
lapic_write(LAPIC_MSG_REG, fv.common_fidvid | (bsp_apicid<<24) | 3); // clear the state
|
||||
|
||||
//here wait a while, so last ap could read pack, and stop it, don't call init_timer too early or just don't use init_timer
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,4 +1,13 @@
|
|||
//it takes the ENABLE_APIC_EXT_ID and APIC_ID_OFFSET and LIFT_BSP_APIC_ID
|
||||
#ifndef K8_SET_FIDVID
|
||||
#define K8_SET_FIDVID 0
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef K8_SET_FIDVID_CORE0_ONLY
|
||||
/* MSR FIDVID_CTL and FIDVID_STATUS are shared by cores, so may don't need to do twice*/
|
||||
#define K8_SET_FIDVID_CORE0_ONLY 1
|
||||
#endif
|
||||
|
||||
typedef void (*process_ap_t)(unsigned apicid, void *gp);
|
||||
|
||||
|
@ -100,6 +109,10 @@ static inline int lapic_remote_read(int apicid, int reg, unsigned *pvalue)
|
|||
#define LAPIC_MSG_REG 0x380
|
||||
|
||||
|
||||
#if K8_SET_FIDVID == 1
|
||||
static void init_fidvid_ap(unsigned bsp_apicid, unsigned apicid);
|
||||
#endif
|
||||
|
||||
static inline __attribute__((always_inline)) void print_apicid_nodeid_coreid(unsigned apicid, struct node_core_id id, const char *str)
|
||||
{
|
||||
#if CONFIG_USE_INIT == 0
|
||||
|
@ -139,7 +152,11 @@ static void allow_all_aps_stop(unsigned bsp_apicid)
|
|||
}
|
||||
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
static unsigned init_cpus(unsigned cpu_init_detectedx ,struct sys_info *sysinfo)
|
||||
#else
|
||||
static unsigned init_cpus(unsigned cpu_init_detectedx)
|
||||
#endif
|
||||
{
|
||||
unsigned bsp_apicid = 0;
|
||||
unsigned apicid;
|
||||
|
@ -193,7 +210,7 @@ static unsigned init_cpus(unsigned cpu_init_detectedx)
|
|||
if (id.nodeid!=0) //all core0 except bsp
|
||||
print_apicid_nodeid_coreid(apicid, id, " core0: ");
|
||||
}
|
||||
#if 1
|
||||
#if 0
|
||||
else { //all core1
|
||||
print_apicid_nodeid_coreid(apicid, id, " core1: ");
|
||||
}
|
||||
|
@ -202,11 +219,20 @@ static unsigned init_cpus(unsigned cpu_init_detectedx)
|
|||
#endif
|
||||
|
||||
if (cpu_init_detectedx) {
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
//We need to init sblnk and sbbusn, because it is called before ht_setup_chains_x
|
||||
sysinfo->sblnk = get_sblnk();
|
||||
sysinfo->sbbusn = node_link_to_bus(0, sysinfo->sblnk);
|
||||
#endif
|
||||
print_apicid_nodeid_coreid(apicid, id, "\r\n\r\n\r\nINIT detect from ");
|
||||
|
||||
print_debug("\r\nIssuing SOFT_RESET...\r\n");
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
soft_reset(sysinfo);
|
||||
#else
|
||||
soft_reset();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -219,6 +245,13 @@ static unsigned init_cpus(unsigned cpu_init_detectedx)
|
|||
lapic_write(LAPIC_MSG_REG, (apicid<<24) | 0x33); // mark the cpu is started
|
||||
|
||||
if(apicid != bsp_apicid) {
|
||||
#if K8_SET_FIDVID == 1
|
||||
#if (CONFIG_LOGICAL_CPUS == 1) && (K8_SET_FIDVID_CORE0_ONLY == 1)
|
||||
if(id.coreid == 0 ) // only need set fid for core0
|
||||
#endif
|
||||
init_fidvid_ap(bsp_apicid, apicid);
|
||||
#endif
|
||||
|
||||
// We need to stop the CACHE as RAM for this CPU, really?
|
||||
wait_cpu_state(bsp_apicid, 0x44);
|
||||
lapic_write(LAPIC_MSG_REG, (apicid<<24) | 0x44); // bsp can not check it before stop_this_cpu
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
SECTIONS {
|
||||
/* Trigger an error if I have an unuseable start address */
|
||||
_ROMTOP = (_start >= 0xffff0000) ? 0xfffffff0 : 0xfffffff8;
|
||||
_bogus = ASSERT(_start >= 0xffff0000, "_start to low please decrease ROM_IMAGE_SIZE");
|
||||
_ROMTOP = 0xfffffff0;
|
||||
. = _ROMTOP;
|
||||
.reset . : {
|
||||
*(.reset)
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
_cache_ram_seg_base = DEFINED(CACHE_RAM_BASE)? CACHE_RAM_BASE - _rodata : 0;
|
||||
_cache_ram_seg_base_low = (_cache_ram_seg_base) & 0xffff;
|
||||
_cache_ram_seg_base_middle = (_cache_ram_seg_base >> 16) & 0xff;
|
||||
_cache_ram_seg_base_high = (_cache_ram_seg_base >> 24) & 0xff;
|
||||
|
||||
_rom_code_seg_base = _ltext - _text;
|
||||
_rom_code_seg_base_low = (_rom_code_seg_base) & 0xffff;
|
||||
_rom_code_seg_base_middle = (_rom_code_seg_base >> 16) & 0xff;
|
||||
_rom_code_seg_base_high = (_rom_code_seg_base >> 24) & 0xff;
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -227,24 +227,19 @@ int start_cpu(device_t cpu)
|
|||
}
|
||||
|
||||
/* C entry point of secondary cpus */
|
||||
|
||||
// secondary_cpu_lock is used to serialize initialization of secondary CPUs
|
||||
// This can be used to avoid interleaved debugging messages.
|
||||
|
||||
static spinlock_t secondary_cpu_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
void secondary_cpu_init(void)
|
||||
{
|
||||
atomic_inc(&active_cpus);
|
||||
|
||||
#if SERIAL_CPU_INIT == 1
|
||||
spin_lock(&secondary_cpu_lock);
|
||||
#if CONFIG_MAX_CPUS>2
|
||||
spin_lock(&start_cpu_lock);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
cpu_initialize();
|
||||
|
||||
#if SERIAL_CPU_INIT == 1
|
||||
spin_unlock(&secondary_cpu_lock);
|
||||
#if CONFIG_MAX_CPUS>2
|
||||
spin_unlock(&start_cpu_lock);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
atomic_dec(&active_cpus);
|
||||
|
@ -260,12 +255,15 @@ static void initialize_other_cpus(struct bus *cpu_bus)
|
|||
if (cpu->path.type != DEVICE_PATH_APIC) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cpu->enabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cpu->initialized) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!start_cpu(cpu)) {
|
||||
/* Record the error in cpu? */
|
||||
printk_err("CPU %u would not start!\n",
|
||||
|
|
|
@ -369,7 +369,6 @@ void compute_allocate_resource(
|
|||
}
|
||||
|
||||
#if CONFIG_CONSOLE_VGA == 1
|
||||
|
||||
device_t vga_pri = 0;
|
||||
static void allocate_vga_resource(void)
|
||||
{
|
||||
|
@ -377,32 +376,53 @@ static void allocate_vga_resource(void)
|
|||
#warning "This function knows to much about PCI stuff, it should be just a ietrator/visitor."
|
||||
|
||||
/* FIXME handle the VGA pallette snooping */
|
||||
struct device *dev, *vga, *vga_onboard;
|
||||
struct device *dev, *vga, *vga_onboard, *vga_first, *vga_last;
|
||||
struct bus *bus;
|
||||
bus = 0;
|
||||
vga = 0;
|
||||
vga_onboard = 0;
|
||||
vga_first = 0;
|
||||
vga_last = 0;
|
||||
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))
|
||||
{
|
||||
if (!vga) {
|
||||
if (!vga_first) {
|
||||
if (dev->on_mainboard) {
|
||||
vga_onboard = dev;
|
||||
} else {
|
||||
vga = dev;
|
||||
vga_first = dev;
|
||||
}
|
||||
} else {
|
||||
if (dev->on_mainboard) {
|
||||
vga_onboard = dev;
|
||||
} else {
|
||||
vga_last = dev;
|
||||
}
|
||||
}
|
||||
|
||||
/* It isn't safe to enable other VGA cards */
|
||||
dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
|
||||
}
|
||||
}
|
||||
|
||||
vga = vga_last;
|
||||
|
||||
if(!vga) {
|
||||
vga = vga_first;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (vga_onboard) // will use on board vga as pri
|
||||
#else
|
||||
if (!vga) // will use last add on adapter as pri
|
||||
#endif
|
||||
{
|
||||
vga = vga_onboard;
|
||||
}
|
||||
|
||||
|
||||
if (vga) {
|
||||
/* vga is first add on card or the only onboard vga */
|
||||
printk_debug("Allocating VGA resource %s\n", dev_path(vga));
|
||||
|
@ -419,6 +439,7 @@ static void allocate_vga_resource(void)
|
|||
bus = (bus == bus->dev->bus)? 0 : bus->dev->bus;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -499,7 +520,6 @@ void enable_resources(struct device *dev)
|
|||
*/
|
||||
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);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
2005.11 yhlu add let the real sb to use small uintid
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <bitops.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
|
@ -11,7 +17,7 @@
|
|||
#define OPT_HT_LINK 0
|
||||
|
||||
#if OPT_HT_LINK == 1
|
||||
#include "../northbridge/amd/amdk8/cpu_rev.c"
|
||||
#include <cpu/amd/model_fxx_rev.h>
|
||||
#endif
|
||||
|
||||
static device_t ht_scan_get_devs(device_t *old_devices)
|
||||
|
@ -72,11 +78,12 @@ static unsigned ht_read_freq_cap(device_t dev, unsigned pos)
|
|||
/* 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
|
||||
{
|
||||
if (is_cpu_pre_e0()) { // only e0 later suupport 1GHz HT
|
||||
freq_cap &= ~(1 << HT_FREQ_1000Mhz);
|
||||
}
|
||||
#else
|
||||
freq_cap &= ~(1 << HT_FREQ_1000Mhz);
|
||||
#endif
|
||||
|
||||
}
|
||||
return freq_cap;
|
||||
|
@ -248,7 +255,7 @@ static unsigned ht_lookup_slave_capability(struct device *dev)
|
|||
return pos;
|
||||
}
|
||||
|
||||
static void ht_collapse_early_enumeration(struct bus *bus)
|
||||
static void ht_collapse_early_enumeration(struct bus *bus, unsigned offset_unitid)
|
||||
{
|
||||
unsigned int devfn;
|
||||
struct ht_link prev;
|
||||
|
@ -275,6 +282,26 @@ static void ht_collapse_early_enumeration(struct bus *bus)
|
|||
}
|
||||
} while((ctrl & (1 << 5)) == 0);
|
||||
|
||||
//actually, only for one HT device HT chain, and unitid is 0
|
||||
#if HT_CHAIN_UNITID_BASE == 0
|
||||
if(offset_unitid) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if is already collapsed */
|
||||
if((!offset_unitid)|| (offset_unitid && (!((HT_CHAIN_END_UNITID_BASE == 0) && (HT_CHAIN_END_UNITID_BASE <HT_CHAIN_UNITID_BASE))))) {
|
||||
struct device dummy;
|
||||
uint32_t id;
|
||||
dummy.bus = bus;
|
||||
dummy.path.type = DEVICE_PATH_PCI;
|
||||
dummy.path.u.pci.devfn = PCI_DEVFN(0, 0);
|
||||
id = pci_read_config32(&dummy, PCI_VENDOR_ID);
|
||||
if ( ! ( (id == 0xffffffff) || (id == 0x00000000) ||
|
||||
(id == 0x0000ffff) || (id == 0xffff0000) ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Spin through the devices and collapse any early
|
||||
* hypertransport enumeration.
|
||||
|
@ -309,15 +336,25 @@ static void ht_collapse_early_enumeration(struct bus *bus)
|
|||
}
|
||||
|
||||
unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||
unsigned min_devfn, unsigned max_devfn, unsigned int max)
|
||||
unsigned min_devfn, unsigned max_devfn, unsigned int max, unsigned offset_unitid)
|
||||
{
|
||||
//even HT_CHAIN_UNITID_BASE == 0, we still can go through this function, because of end_of_chain check, also We need it to optimize link
|
||||
unsigned next_unitid, last_unitid;
|
||||
device_t old_devices, dev, func;
|
||||
unsigned min_unitid = 1;
|
||||
unsigned min_unitid = (offset_unitid) ? HT_CHAIN_UNITID_BASE:1;
|
||||
struct ht_link prev;
|
||||
device_t last_func = 0;
|
||||
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
||||
unsigned real_last_unitid;
|
||||
uint8_t real_last_pos;
|
||||
device_t real_last_dev;
|
||||
int ht_dev_num = 0;
|
||||
#endif
|
||||
|
||||
/* Restore the hypertransport chain to it's unitialized state */
|
||||
ht_collapse_early_enumeration(bus);
|
||||
ht_collapse_early_enumeration(bus, offset_unitid);
|
||||
|
||||
/* See which static device nodes I have */
|
||||
old_devices = bus->children;
|
||||
|
@ -405,6 +442,7 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
|||
func->path.u.pci.devfn += (next_unitid << 3);
|
||||
static_count = (func->path.u.pci.devfn >> 3)
|
||||
- (dev->path.u.pci.devfn >> 3) + 1;
|
||||
last_func = func;
|
||||
}
|
||||
|
||||
/* Compute the number of unitids consumed */
|
||||
|
@ -416,6 +454,14 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
|||
}
|
||||
|
||||
/* Update the Unitid of the next device */
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
if(offset_unitid) {
|
||||
real_last_unitid = next_unitid;
|
||||
real_last_pos = pos;
|
||||
real_last_dev = dev;
|
||||
ht_dev_num++;
|
||||
}
|
||||
#endif
|
||||
next_unitid += count;
|
||||
|
||||
/* Setup the hypetransport link */
|
||||
|
@ -442,6 +488,26 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
|||
printk_debug("HyperT reset not needed\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
if(offset_unitid && (ht_dev_num>0)) {
|
||||
uint16_t flags;
|
||||
int i;
|
||||
device_t last_func = 0;
|
||||
flags = pci_read_config16(real_last_dev, real_last_pos + PCI_CAP_FLAGS);
|
||||
flags &= ~0x1f;
|
||||
flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
|
||||
pci_write_config16(real_last_dev, real_last_pos + PCI_CAP_FLAGS, flags);
|
||||
|
||||
for(func = real_last_dev; func; func = func->sibling) {
|
||||
func->path.u.pci.devfn -= ((real_last_unitid - HT_CHAIN_END_UNITID_BASE) << 3);
|
||||
last_func = func;
|
||||
}
|
||||
|
||||
next_unitid = real_last_unitid;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (next_unitid > 0x1f) {
|
||||
next_unitid = 0x1f;
|
||||
}
|
||||
|
@ -454,7 +520,9 @@ unsigned int hypertransport_scan_chain(struct bus *bus,
|
|||
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");
|
||||
printk_err("HT: Left over static devices. Check your Config.lb\n");
|
||||
if(last_func && !last_func->sibling) // put back the left over static device, and let pci_scan_bus disable it
|
||||
last_func->sibling = old_devices;
|
||||
}
|
||||
|
||||
/* Now that nothing is overlapping it is safe to scan the
|
||||
|
|
|
@ -1043,7 +1043,7 @@ unsigned int pci_scan_bus(struct bus *bus,
|
|||
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");
|
||||
die("PCI: Left over static devices. Check your Config.lb\n");
|
||||
}
|
||||
|
||||
/* For all children that implement scan_bus (i.e. bridges)
|
||||
|
|
|
@ -23,13 +23,14 @@ struct rom_header * pci_rom_probe(struct device *dev)
|
|||
|
||||
printk_debug("rom address for %s = %x\n", dev_path(dev), rom_address);
|
||||
|
||||
if(!dev->on_mainboard) {
|
||||
/* enable expansion ROM address decoding */
|
||||
pci_write_config32(dev, PCI_ROM_ADDRESS,
|
||||
rom_address|PCI_ROM_ADDRESS_ENABLE);
|
||||
}
|
||||
|
||||
rom_header = (struct rom_header *)rom_address;
|
||||
printk_spew("PCI Expansion ROM, signature 0x%04x, \n\t"
|
||||
"INIT size 0x%04x, data ptr 0x%04x\n",
|
||||
printk_spew("PCI Expansion ROM, signature 0x%04x, INIT size 0x%04x, data ptr 0x%04x\n",
|
||||
le32_to_cpu(rom_header->signature),
|
||||
rom_header->size * 512, le32_to_cpu(rom_header->data));
|
||||
if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
|
||||
|
@ -38,7 +39,7 @@ struct rom_header * pci_rom_probe(struct device *dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
rom_data = (struct pci_data *) ((unsigned char *) rom_header + le32_to_cpu(rom_header->data));
|
||||
rom_data = (unsigned char *) rom_header + le32_to_cpu(rom_header->data);
|
||||
printk_spew("PCI ROM Image, Vendor %04x, Device %04x,\n",
|
||||
rom_data->vendor, rom_data->device);
|
||||
if (dev->vendor != rom_data->vendor || dev->device != rom_data->device) {
|
||||
|
@ -51,7 +52,7 @@ struct rom_header * pci_rom_probe(struct device *dev)
|
|||
rom_data->class_hi, rom_data->class_lo,
|
||||
rom_data->type);
|
||||
if (dev->class != ((rom_data->class_hi << 8) | rom_data->class_lo)) {
|
||||
printk_err("Class Code mismatch ROM %08x, dev %08x\n",
|
||||
printk_debug("Class Code mismatch ROM %08x, dev %08x\n",
|
||||
(rom_data->class_hi << 8) | rom_data->class_lo, dev->class);
|
||||
//return NULL;
|
||||
}
|
||||
|
@ -59,12 +60,14 @@ struct rom_header * pci_rom_probe(struct device *dev)
|
|||
return rom_header;
|
||||
}
|
||||
|
||||
static void *pci_ram_image_start = PCI_RAM_IMAGE_START;
|
||||
static void *pci_ram_image_start = (void *)PCI_RAM_IMAGE_START;
|
||||
|
||||
#if CONFIG_CONSOLE_VGA == 1
|
||||
int vga_inited = 0; // used by vga_console.c
|
||||
extern int vga_inited; // defined in vga_console.c
|
||||
#if CONFIG_CONSOLE_VGA_MULTI == 0
|
||||
extern device_t vga_pri; // the primary vga device, defined in device.c
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_header)
|
||||
{
|
||||
|
@ -76,8 +79,8 @@ struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_heade
|
|||
rom_address = pci_read_config32(dev, PCI_ROM_ADDRESS);
|
||||
|
||||
do {
|
||||
rom_header = (struct rom_header *) ((unsigned char *) rom_header + image_size); // get next image
|
||||
rom_data = (struct pci_data *) ((unsigned char *) rom_header + le32_to_cpu(rom_header->data));
|
||||
rom_header = (unsigned char *) rom_header + image_size; // get next image
|
||||
rom_data = (unsigned char *) rom_header + le32_to_cpu(rom_header->data);
|
||||
image_size = le32_to_cpu(rom_data->ilen) * 512;
|
||||
} while ((rom_data->type!=0) && (rom_data->indicator!=0)); // make sure we got x86 version
|
||||
|
||||
|
@ -87,7 +90,9 @@ struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_heade
|
|||
|
||||
if (PCI_CLASS_DISPLAY_VGA == rom_data->class_hi) {
|
||||
#if CONFIG_CONSOLE_VGA == 1
|
||||
#if CONFIG_CONSOLE_VGA_MULTI == 0
|
||||
if (dev != vga_pri) return NULL; // only one VGA supported
|
||||
#endif
|
||||
printk_debug("copying VGA ROM Image from %x to %x, %x bytes\n",
|
||||
rom_header, PCI_VGA_RAM_IMAGE_START, rom_size);
|
||||
memcpy(PCI_VGA_RAM_IMAGE_START, rom_header, rom_size);
|
||||
|
@ -95,11 +100,11 @@ struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_heade
|
|||
return (struct rom_header *) (PCI_VGA_RAM_IMAGE_START);
|
||||
#endif
|
||||
} else {
|
||||
printk_spew("%s, copying non-VGA ROM Image from %x to %x, %x bytes\n",
|
||||
__func__, rom_header, pci_ram_image_start, rom_size);
|
||||
printk_debug("copying non-VGA ROM Image from %x to %x, %x bytes\n",
|
||||
rom_header, pci_ram_image_start, rom_size);
|
||||
memcpy(pci_ram_image_start, rom_header, rom_size);
|
||||
pci_ram_image_start += rom_size;
|
||||
return (struct rom_header *) pci_ram_image_start;
|
||||
return (struct rom_header *) (pci_ram_image_start-rom_size);
|
||||
}
|
||||
/* disable expansion ROM address decoding */
|
||||
pci_write_config32(dev, PCI_ROM_ADDRESS, rom_address & ~PCI_ROM_ADDRESS_ENABLE);
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
#ifndef CPU_AMD_DUALCORE_H
|
||||
#define CPU_AMD_DUALCORE_H
|
||||
|
||||
struct device;
|
||||
#if defined(__GNUC__)
|
||||
unsigned int read_nb_cfg_54(void);
|
||||
#endif
|
||||
|
||||
struct node_core_id {
|
||||
unsigned nodeid;
|
||||
unsigned coreid;
|
||||
};
|
||||
|
||||
void amd_sibling_init(struct device *cpu, struct node_core_id id);
|
||||
struct node_core_id get_node_core_id(void);
|
||||
#if defined(__GNUC__)
|
||||
// it can be used to get unitid and coreid it running only
|
||||
struct node_core_id get_node_core_id(unsigned int nb_cfg_54);
|
||||
#endif
|
||||
|
||||
#ifndef __ROMCC__
|
||||
struct device;
|
||||
unsigned get_apicid_base(unsigned ioapic_num);
|
||||
void amd_sibling_init(struct device *cpu);
|
||||
#endif
|
||||
|
||||
#endif /* CPU_AMD_DUALCORE_H */
|
||||
|
|
|
@ -10,17 +10,17 @@
|
|||
# define NEED_LAPIC 1
|
||||
#endif
|
||||
|
||||
static inline unsigned long lapic_read(unsigned long reg)
|
||||
static inline __attribute__((always_inline)) unsigned long lapic_read(unsigned long reg)
|
||||
{
|
||||
return *((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg));
|
||||
}
|
||||
|
||||
static inline void lapic_write(unsigned long reg, unsigned long v)
|
||||
static inline __attribute__((always_inline)) void lapic_write(unsigned long reg, unsigned long v)
|
||||
{
|
||||
*((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg)) = v;
|
||||
}
|
||||
|
||||
static inline void lapic_wait_icr_idle(void)
|
||||
static inline __attribute__((always_inline)) void lapic_wait_icr_idle(void)
|
||||
{
|
||||
do { } while ( lapic_read( LAPIC_ICR ) & LAPIC_ICR_BUSY );
|
||||
}
|
||||
|
@ -46,13 +46,14 @@ static inline void disable_lapic(void)
|
|||
wrmsr(LAPIC_BASE_MSR, msr);
|
||||
}
|
||||
|
||||
static inline unsigned long lapicid(void)
|
||||
static inline __attribute__((always_inline)) unsigned long lapicid(void)
|
||||
{
|
||||
return lapic_read(LAPIC_ID) >> 24;
|
||||
}
|
||||
|
||||
static inline void stop_this_cpu(void)
|
||||
static inline __attribute__((always_inline)) void stop_this_cpu(void)
|
||||
{
|
||||
|
||||
unsigned apicid;
|
||||
apicid = lapicid();
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <device/hypertransport_def.h>
|
||||
|
||||
unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||
unsigned min_devfn, unsigned max_devfn, unsigned int max);
|
||||
unsigned min_devfn, unsigned max_devfn, unsigned int max, unsigned offset_unitid);
|
||||
unsigned int ht_scan_bridge(struct device *dev, unsigned int max);
|
||||
extern struct device_operations default_ht_ops_bus;
|
||||
|
||||
|
|
|
@ -438,6 +438,9 @@
|
|||
#define PCI_DEVICE_ID_AMD_8131_PCIX 0x7450
|
||||
#define PCI_DEVICE_ID_AMD_8131_IOAPIC 0x7451
|
||||
|
||||
#define PCI_DEVICE_ID_AMD_8132_PCIX 0x7458
|
||||
#define PCI_DEVICE_ID_AMD_8132_IOAPIC 0x7459
|
||||
|
||||
#define PCI_VENDOR_ID_TRIDENT 0x1023
|
||||
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
|
||||
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
|
||||
|
@ -910,6 +913,20 @@
|
|||
#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021
|
||||
#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022
|
||||
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_HT 0x00e1
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_LPC 0x00e0
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_SM 0x00e4
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_USB 0x00e7
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_USB2 0x00e8
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_NIC 0x00e6
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_ACI 0x00ea
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_MCI 0x00e9
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_IDE 0x00e5
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_SATA0 0x00ee
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_SATA1 0x00e3
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_PCI 0x00ed
|
||||
#define PCI_DEVICE_ID_NVIDIA_CK8S_PCI_AGP 0x00e2
|
||||
|
||||
#define PCI_VENDOR_ID_NVIDIA 0x10de
|
||||
#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020
|
||||
#define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028
|
||||
|
@ -1207,6 +1224,21 @@
|
|||
#define PCI_DEVICE_ID_SERVERWORKS_GCLE2 0x0227
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
|
||||
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5780_PXB 0x0130
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5780_PCIE 0x0132
|
||||
#define PCI_DEVICE_ID_BROADCOM_BCM5780_NIC 0x1668
|
||||
#define PCI_DEVICE_ID_BROADCOM_BCM5780_NIC1 0x1669
|
||||
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_HT_PXB 0x0036
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_PXBX 0x0104
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_SATA 0x024a
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_SB_PCI_MAIN 0x0205
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_IDE 0x0214
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_LPC 0x0234
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_WDT 0x0238
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_XIOAPIC 0x0235
|
||||
#define PCI_DEVICE_ID_SERVERWORKS_BCM5785_USB 0x0223
|
||||
|
||||
#define PCI_VENDOR_ID_SBE 0x1176
|
||||
#define PCI_DEVICE_ID_SBE_WANXL100 0x0301
|
||||
#define PCI_DEVICE_ID_SBE_WANXL200 0x0302
|
||||
|
@ -1763,7 +1795,6 @@
|
|||
#define PCI_DEVICE_ID_INTEL_82801CA_1F3 0x2483
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_1D1 0x2484
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_1F5 0x2485
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_1F6 0x2486
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_1D2 0x2487
|
||||
#define PCI_DEVICE_ID_INTEL_82870_1E0 0x1461
|
||||
#define PCI_DEVICE_ID_INTEL_82870_1F0 0x1460
|
||||
|
@ -1793,17 +1824,15 @@
|
|||
#define PCI_DEVICE_ID_INTEL_82801E_11 0x245b
|
||||
#define PCI_DEVICE_ID_INTEL_82801E_13 0x245d
|
||||
#define PCI_DEVICE_ID_INTEL_82801E_14 0x245e
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_LAN 0x2449
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_PCI 0x244e // Same as 82801ER
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_LPC 0x2480
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_USB 0x2482
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_SMB 0x2483
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_USB2 0x2484
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_AC97_AUDIO 0x2485
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_AC97_MODEM 0x2486
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_USB3 0x2487
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_4 0x2484
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_7 0x2487
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_IDE 0x248b
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
|
||||
#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c
|
||||
#define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0
|
||||
#define PCI_DEVICE_ID_INTEL_82801DB_2 0x24c2
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#ifndef AMDK8_H
|
||||
|
||||
#define AMDK8_H
|
||||
|
||||
/* Definitions of various K8 registers */
|
||||
/* Function 0 */
|
||||
#define HT_TRANSACTION_CONTROL 0x68
|
||||
|
@ -226,3 +230,5 @@
|
|||
#define InitComplete (1 << 1)
|
||||
#define NonCoherent (1 << 2)
|
||||
#define ConnectionPending (1 << 4)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1812,9 +1812,9 @@ static int setup_coherent_ht_domain(void)
|
|||
|
||||
#if CONFIG_MAX_PHYSICAL_CPUS > 1
|
||||
result = setup_smp();
|
||||
#endif
|
||||
result.nodes = verify_mp_capabilities(result.nodes);
|
||||
clear_dead_routes(result.nodes);
|
||||
#endif
|
||||
if (result.nodes == 1) {
|
||||
setup_uniprocessor();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,18 @@
|
|||
* generic K8 debug code, used by mainboard specific auto.c
|
||||
*
|
||||
*/
|
||||
|
||||
static inline void print_debug_addr(const char *str, void *val)
|
||||
{
|
||||
#if CACHE_AS_RAM_ADDRESS_DEBUG == 1
|
||||
#if CONFIG_USE_INIT==1
|
||||
printk_debug("------Address debug: %s%x------\r\n", str, val);
|
||||
#else
|
||||
print_debug ("------Address debug: "); print_debug(str); print_debug_hex32(val); print_debug("------\r\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 1
|
||||
static void print_debug_pci_dev(unsigned dev)
|
||||
{
|
||||
|
@ -34,6 +46,7 @@ static void print_pci_devices(void)
|
|||
#if CONFIG_USE_INIT
|
||||
printk_debug(" %04x:%04x\r\n", (id & 0xffff), (id>>16));
|
||||
#else
|
||||
print_debug(" ");
|
||||
print_debug_hex32(id);
|
||||
print_debug("\r\n");
|
||||
#endif
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
static int enumerate_ht_chain(void)
|
||||
/*
|
||||
2005.11 yhlu add let the real sb to use small unitid
|
||||
*/
|
||||
// only for sb ht chain
|
||||
static void enumerate_ht_chain(void)
|
||||
{
|
||||
#if HT_CHAIN_UNITID_BASE != 0
|
||||
/* HT_CHAIN_UNITID_BASE could be 0 (only one ht device in the ht chain), if so, don't need to go through the chain */
|
||||
|
||||
/* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
|
||||
* On most boards this just happens. If a cpu has multiple
|
||||
* non Coherent links the appropriate bus registers for the
|
||||
* links needs to be programed to point at bus 0.
|
||||
*/
|
||||
unsigned next_unitid, last_unitid;
|
||||
int reset_needed = 0;
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
||||
unsigned real_last_unitid;
|
||||
uint8_t real_last_pos;
|
||||
int ht_dev_num = 0; // except host_bridge
|
||||
#endif
|
||||
|
||||
next_unitid = 1;
|
||||
next_unitid = HT_CHAIN_UNITID_BASE;
|
||||
do {
|
||||
uint32_t id;
|
||||
uint8_t hdr_type, pos;
|
||||
|
@ -58,6 +70,11 @@ static int enumerate_ht_chain(void)
|
|||
flags &= ~0x1f;
|
||||
flags |= next_unitid & 0x1f;
|
||||
count = (flags >> 5) & 0x1f;
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
real_last_unitid = next_unitid;
|
||||
real_last_pos = pos;
|
||||
ht_dev_num++ ;
|
||||
#endif
|
||||
next_unitid += count;
|
||||
|
||||
/* Test for end of chain */
|
||||
|
@ -78,7 +95,17 @@ static int enumerate_ht_chain(void)
|
|||
pos = pci_read_config8(PCI_DEV(0, 0, 0), pos + PCI_CAP_LIST_NEXT);
|
||||
}
|
||||
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
if(ht_dev_num>0) {
|
||||
uint16_t flags;
|
||||
flags = pci_read_config16(PCI_DEV(0,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
||||
flags &= ~0x1f;
|
||||
flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
|
||||
pci_write_config16(PCI_DEV(0, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return reset_needed;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
/*
|
||||
This should be done by Eric
|
||||
2004.12 yhlu add multi ht chain dynamically support
|
||||
|
||||
2005.11 yhlu add let real sb to use small unitid
|
||||
*/
|
||||
#include <device/pci_def.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <device/hypertransport_def.h>
|
||||
|
||||
|
||||
/* We can reduce the size of code generated by romcc by
|
||||
* changing all of the fixed size types that live in registers
|
||||
* into simple unsigned variables. (ie s/uint8_t/unsigned/g)
|
||||
*/
|
||||
#ifndef K8_HT_FREQ_1G_SUPPORT
|
||||
#define K8_HT_FREQ_1G_SUPPORT 0
|
||||
#endif
|
||||
|
@ -20,15 +15,22 @@
|
|||
#define K8_SCAN_PCI_BUS 0
|
||||
#endif
|
||||
|
||||
#ifndef K8_ALLOCATE_IO_RANGE
|
||||
#define K8_ALLOCATE_IO_RANGE 0
|
||||
#endif
|
||||
|
||||
// Do we need allocate MMIO? Current We direct last 64M to sblink only, We can not lose access to last 4M range to ROM
|
||||
#ifndef K8_ALLOCATE_MMIO_RANGE
|
||||
#define K8_ALLOCATE_MMIO_RANGE 0
|
||||
#endif
|
||||
|
||||
static inline void print_linkn_in (const char *strval, uint8_t byteval)
|
||||
{
|
||||
#if 1
|
||||
#if CONFIG_USE_INIT
|
||||
printk_debug("%s%02x\r\n", strval, byteval);
|
||||
#else
|
||||
print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t ht_lookup_capability(device_t dev, uint16_t val)
|
||||
|
@ -74,18 +76,27 @@ static uint8_t ht_lookup_host_capability(device_t dev)
|
|||
return ht_lookup_capability(dev, 1); // Host/Secondary Interface Block Format
|
||||
}
|
||||
|
||||
static void ht_collapse_previous_enumeration(uint8_t bus)
|
||||
static void ht_collapse_previous_enumeration(uint8_t bus, unsigned offset_unitid)
|
||||
{
|
||||
device_t dev;
|
||||
uint32_t id;
|
||||
|
||||
//actually, only for one HT device HT chain, and unitid is 0
|
||||
#if HT_CHAIN_UNITID_BASE == 0
|
||||
if(offset_unitid) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if is already collapsed */
|
||||
if((!offset_unitid) || (offset_unitid && (!((HT_CHAIN_END_UNITID_BASE == 0) && (HT_CHAIN_END_UNITID_BASE <HT_CHAIN_UNITID_BASE))))) {
|
||||
dev = PCI_DEV(bus, 0, 0);
|
||||
id = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||
if ( ! ( (id == 0xffffffff) || (id == 0x00000000) ||
|
||||
(id == 0x0000ffff) || (id == 0xffff0000) ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Spin through the devices and collapse any previous
|
||||
* hypertransport enumeration.
|
||||
|
@ -136,22 +147,25 @@ static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos)
|
|||
/* AMD 8131 Errata 48 */
|
||||
if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
|
||||
freq_cap &= ~(1 << HT_FREQ_800Mhz);
|
||||
return freq_cap;
|
||||
}
|
||||
|
||||
/* AMD 8151 Errata 23 */
|
||||
if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
|
||||
freq_cap &= ~(1 << HT_FREQ_800Mhz);
|
||||
return freq_cap;
|
||||
}
|
||||
|
||||
/* AMD K8 Unsupported 1Ghz? */
|
||||
if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
|
||||
#if K8_HT_FREQ_1G_SUPPORT == 1
|
||||
/* Supported starting with E0 */
|
||||
device_t dev_2 = PCI_DEV(0,0x18,2);
|
||||
if(pci_read_config32(dev_2,0x9c) < 0x20f00)
|
||||
#endif
|
||||
if (is_cpu_pre_e0()) { // only E0 later support 1GHz
|
||||
freq_cap &= ~(1 << HT_FREQ_1000Mhz);
|
||||
}
|
||||
#else
|
||||
freq_cap &= ~(1 << HT_FREQ_1000Mhz);
|
||||
#endif
|
||||
}
|
||||
|
||||
return freq_cap;
|
||||
}
|
||||
|
@ -236,6 +250,7 @@ static int ht_optimize_link(
|
|||
|
||||
/* See if I am changing dev1's width */
|
||||
old_width = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1);
|
||||
old_width &= 0x77;
|
||||
needs_reset |= old_width != width;
|
||||
|
||||
/* Set dev1's widths */
|
||||
|
@ -246,6 +261,7 @@ static int ht_optimize_link(
|
|||
|
||||
/* See if I am changing dev2's width */
|
||||
old_width = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1);
|
||||
old_width &= 0x77;
|
||||
needs_reset |= old_width != width;
|
||||
|
||||
/* Set dev2's widths */
|
||||
|
@ -254,8 +270,14 @@ static int ht_optimize_link(
|
|||
return needs_reset;
|
||||
}
|
||||
#if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
|
||||
static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus);
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo);
|
||||
static int scan_pci_bus( unsigned bus , struct sys_info *sysinfo)
|
||||
#else
|
||||
static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid);
|
||||
static int scan_pci_bus( unsigned bus)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7)
|
||||
|
@ -324,7 +346,6 @@ static int scan_pci_bus( unsigned bus)
|
|||
((unsigned int) max_bus << 16));
|
||||
pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
|
||||
|
||||
{
|
||||
/* here we need to figure out if dev is a ht bridge
|
||||
if it is ht bridge, we need to call ht_setup_chainx at first
|
||||
Not verified --- yhlu
|
||||
|
@ -335,13 +356,20 @@ static int scan_pci_bus( unsigned bus)
|
|||
uint8_t busn;
|
||||
busn = (new_bus & 0xff);
|
||||
/* Make certain the HT bus is not enumerated */
|
||||
ht_collapse_previous_enumeration(busn);
|
||||
ht_collapse_previous_enumeration(busn, 0);
|
||||
/* scan the ht chain */
|
||||
new_bus |= (ht_setup_chainx(dev,upos,busn)<<16); // store reset_needed to upword
|
||||
}
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
ht_setup_chainx(dev,upos,busn, 0, sysinfo); // don't need offset unitid
|
||||
#else
|
||||
new_bus |= (ht_setup_chainx(dev, upos, busn, 0)<<16); // store reset_needed to upword
|
||||
#endif
|
||||
}
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
new_bus = scan_pci_bus(new_bus, sysinfo);
|
||||
#else
|
||||
new_bus = scan_pci_bus(new_bus);
|
||||
#endif
|
||||
/* set real max bus num in that */
|
||||
|
||||
buses = (buses & 0xff00ffff) |
|
||||
|
@ -370,14 +398,31 @@ static int scan_pci_bus( unsigned bus)
|
|||
return new_bus;
|
||||
}
|
||||
#endif
|
||||
static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo)
|
||||
#else
|
||||
static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid)
|
||||
#endif
|
||||
{
|
||||
//even HT_CHAIN_UNITID_BASE == 0, we still can go through this function, because of end_of_chain check, also We need it to optimize link
|
||||
|
||||
uint8_t next_unitid, last_unitid;
|
||||
unsigned uoffs;
|
||||
|
||||
#if RAMINIT_SYSINFO == 0
|
||||
int reset_needed = 0;
|
||||
#endif
|
||||
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
||||
unsigned real_last_unitid;
|
||||
uint8_t real_last_pos;
|
||||
int ht_dev_num = 0;
|
||||
#endif
|
||||
|
||||
uoffs = PCI_HT_HOST_OFFS;
|
||||
next_unitid = 1;
|
||||
next_unitid = (offset_unitid) ? HT_CHAIN_UNITID_BASE:1;
|
||||
|
||||
do {
|
||||
uint32_t id;
|
||||
|
@ -391,11 +436,24 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
|
|||
ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
|
||||
/* Is this the end of the hypertransport chain? */
|
||||
if (ctrl & (1 << 6)) {
|
||||
goto end_of_chain;
|
||||
}
|
||||
|
||||
if (ctrl & ((1 << 4) | (1 << 8))) {
|
||||
/*
|
||||
* Either the link has failed, or we have
|
||||
* a CRC error.
|
||||
* Sometimes this can happen due to link
|
||||
* retrain, so lets knock it down and see
|
||||
* if its transient
|
||||
*/
|
||||
ctrl |= ((1 << 6) | (1 <<8)); // Link fail + Crc
|
||||
pci_write_config16(udev, upos + LINK_CTRL(uoffs), ctrl);
|
||||
ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
|
||||
if (ctrl & ((1 << 4) | (1 << 8))) {
|
||||
print_err("Detected error on Hypertransport Link\n");
|
||||
break;
|
||||
}
|
||||
/* Has the link failed */
|
||||
if (ctrl & (1 << 4)) {
|
||||
break;
|
||||
}
|
||||
} while((ctrl & (1 << 5)) == 0);
|
||||
|
||||
|
@ -413,7 +471,10 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
|
|||
|
||||
pos = ht_lookup_slave_capability(dev);
|
||||
if (!pos) {
|
||||
print_err("HT link capability not found\r\n");
|
||||
print_err("udev="); print_err_hex32(udev);
|
||||
print_err("\tupos="); print_err_hex32(upos);
|
||||
print_err("\tuoffs="); print_err_hex32(uoffs);
|
||||
print_err("\tHT link capability not found\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -441,6 +502,14 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
|
|||
|
||||
/* Compute the number of unitids consumed */
|
||||
count = (flags >> 5) & 0x1f;
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
if(offset_unitid) {
|
||||
real_last_unitid = next_unitid;
|
||||
real_last_pos = pos;
|
||||
ht_dev_num++;
|
||||
}
|
||||
#endif
|
||||
|
||||
next_unitid += count;
|
||||
|
||||
/* Find which side of the ht link we are on,
|
||||
|
@ -450,8 +519,21 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
|
|||
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
||||
offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
|
||||
|
||||
/* Setup the Hypertransport link */
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
/* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */
|
||||
{
|
||||
struct link_pair_st *link_pair = &sysinfo->link_pair[sysinfo->link_pair_num];
|
||||
link_pair->udev = udev;
|
||||
link_pair->upos = upos;
|
||||
link_pair->uoffs = uoffs;
|
||||
link_pair->dev = dev;
|
||||
link_pair->pos = pos;
|
||||
link_pair->offs = offs;
|
||||
sysinfo->link_pair_num++;
|
||||
}
|
||||
#else
|
||||
reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
|
||||
#endif
|
||||
|
||||
#if CK804_DEVN_BASE==0
|
||||
if(id == 0x005e10de) {
|
||||
|
@ -466,11 +548,52 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
|
|||
|
||||
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
|
||||
|
||||
end_of_chain: ;
|
||||
|
||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||
if(offset_unitid && (ht_dev_num>0) ) {
|
||||
uint16_t flags;
|
||||
int i;
|
||||
flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
||||
flags &= ~0x1f;
|
||||
flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
|
||||
pci_write_config16(PCI_DEV(bus, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags);
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
// Here need to change the dev in the array
|
||||
for(i=0;i<sysinfo->link_pair_num;i++)
|
||||
{
|
||||
struct link_pair_st *link_pair = &sysinfo->link_pair[i];
|
||||
if(link_pair->udev == PCI_DEV(bus, real_last_unitid, 0)) {
|
||||
link_pair->udev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
|
||||
continue;
|
||||
}
|
||||
if(link_pair->dev == PCI_DEV(bus, real_last_unitid, 0)) {
|
||||
link_pair->dev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RAMINIT_SYSINFO == 0
|
||||
return reset_needed;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
static void ht_setup_chain(device_t udev, unsigned upos, struct sys_info *sysinfo)
|
||||
#else
|
||||
static int ht_setup_chain(device_t udev, unsigned upos)
|
||||
#endif
|
||||
{
|
||||
unsigned offset_unitid = 0;
|
||||
#if HT_CHAIN_UNITID_BASE != 1
|
||||
offset_unitid = 1;
|
||||
#endif
|
||||
|
||||
/* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
|
||||
* On most boards this just happens. If a cpu has multiple
|
||||
* non Coherent links the appropriate bus registers for the
|
||||
|
@ -478,9 +601,17 @@ static int ht_setup_chain(device_t udev, unsigned upos)
|
|||
*/
|
||||
|
||||
/* Make certain the HT bus is not enumerated */
|
||||
ht_collapse_previous_enumeration(0);
|
||||
ht_collapse_previous_enumeration(0, 0);
|
||||
|
||||
return ht_setup_chainx(udev, upos, 0);
|
||||
#if HT_CHAIN_UNITID_BASE != 1
|
||||
offset_unitid = 1;
|
||||
#endif
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
ht_setup_chainx(udev, upos, 0, offset_unitid, sysinfo);
|
||||
#else
|
||||
return ht_setup_chainx(udev, upos, 0, offset_unitid);
|
||||
#endif
|
||||
}
|
||||
static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
|
||||
{
|
||||
|
@ -506,7 +637,7 @@ static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int optimize_link_in_coherent(uint8_t ht_c_num)
|
||||
static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
|
||||
{
|
||||
int reset_needed;
|
||||
uint8_t i;
|
||||
|
@ -541,20 +672,28 @@ static int optimize_link_in_coherent(uint8_t ht_c_num)
|
|||
return reset_needed;
|
||||
}
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
static void ht_setup_chains(uint8_t ht_c_num, struct sys_info *sysinfo)
|
||||
#else
|
||||
static int ht_setup_chains(uint8_t ht_c_num)
|
||||
#endif
|
||||
{
|
||||
/* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
|
||||
* On most boards this just happens. If a cpu has multiple
|
||||
* non Coherent links the appropriate bus registers for the
|
||||
* links needs to be programed to point at bus 0.
|
||||
*/
|
||||
int reset_needed;
|
||||
uint8_t upos;
|
||||
device_t udev;
|
||||
uint8_t i;
|
||||
|
||||
reset_needed = 0;
|
||||
#if RAMINIT_SYSINFO == 0
|
||||
int reset_needed = 0;
|
||||
#else
|
||||
sysinfo->link_pair_num = 0;
|
||||
#endif
|
||||
|
||||
// first one is SB Chain
|
||||
for (i = 0; i < ht_c_num; i++) {
|
||||
uint32_t reg;
|
||||
uint8_t devpos;
|
||||
|
@ -564,6 +703,7 @@ static int ht_setup_chains(uint8_t ht_c_num)
|
|||
#if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
|
||||
unsigned bus;
|
||||
#endif
|
||||
unsigned offset_unitid = 0;
|
||||
|
||||
reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
|
||||
|
||||
|
@ -577,31 +717,56 @@ static int ht_setup_chains(uint8_t ht_c_num)
|
|||
dword |= (reg & 0xffff0000)>>8;
|
||||
pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword);
|
||||
|
||||
|
||||
#if HT_CHAIN_UNITID_BASE != 1
|
||||
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
||||
if(i==0) // to check if it is sb ht chain
|
||||
#endif
|
||||
offset_unitid = 1;
|
||||
#endif
|
||||
|
||||
/* Make certain the HT bus is not enumerated */
|
||||
ht_collapse_previous_enumeration(busn);
|
||||
ht_collapse_previous_enumeration(busn, offset_unitid);
|
||||
|
||||
upos = ((reg & 0xf00)>>8) * 0x20 + 0x80;
|
||||
udev = PCI_DEV(0, devpos, 0);
|
||||
|
||||
reset_needed |= ht_setup_chainx(udev,upos,busn);
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
ht_setup_chainx(udev,upos,busn, offset_unitid, sysinfo); // all not
|
||||
#else
|
||||
reset_needed |= ht_setup_chainx(udev,upos,busn, offset_unitid); //all not
|
||||
#endif
|
||||
|
||||
#if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
|
||||
/* You can use use this in romcc, because there is function call in romcc, recursive will kill you */
|
||||
bus = busn; // we need 32 bit
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
scan_pci_bus(bus, sysinfo);
|
||||
#else
|
||||
reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
reset_needed |= optimize_link_in_coherent(ht_c_num);
|
||||
#if RAMINIT_SYSINFO == 0
|
||||
reset_needed |= optimize_link_read_pointers_chain(ht_c_num);
|
||||
|
||||
return reset_needed;
|
||||
}
|
||||
|
||||
#ifndef K8_ALLOCATE_IO_RANGE
|
||||
#define K8_ALLOCATE_IO_RANGE 0
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static inline unsigned get_nodes(void)
|
||||
{
|
||||
return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
|
||||
}
|
||||
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
static void ht_setup_chains_x(struct sys_info *sysinfo)
|
||||
#else
|
||||
static int ht_setup_chains_x(void)
|
||||
#endif
|
||||
{
|
||||
uint8_t nodeid;
|
||||
uint32_t reg;
|
||||
|
@ -613,10 +778,17 @@ static int ht_setup_chains_x(void)
|
|||
unsigned next_io_base;
|
||||
#endif
|
||||
|
||||
nodes = get_nodes();
|
||||
|
||||
/* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
|
||||
reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
|
||||
/* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */
|
||||
print_linkn_in("SBLink=", ((reg>>8) & 3) );
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
sysinfo->sblnk = (reg>>8) & 3;
|
||||
sysinfo->sbbusn = 0;
|
||||
sysinfo->nodes = nodes;
|
||||
#endif
|
||||
tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
|
||||
|
||||
|
@ -639,8 +811,6 @@ static int ht_setup_chains_x(void)
|
|||
pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
|
||||
}
|
||||
|
||||
nodes = ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
|
||||
|
||||
for(nodeid=0; nodeid<nodes; nodeid++) {
|
||||
device_t dev;
|
||||
uint8_t linkn;
|
||||
|
@ -671,7 +841,7 @@ static int ht_setup_chains_x(void)
|
|||
/* io range allocation */
|
||||
tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); //limit
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
|
||||
tempreg = 3 | ( 3<<4) | (next_io_base<<12); //base
|
||||
tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12); //base :ISA and VGA ?
|
||||
pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
|
||||
next_io_base += 0x3+0x1;
|
||||
#endif
|
||||
|
@ -717,6 +887,64 @@ static int ht_setup_chains_x(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
sysinfo->ht_c_num = i;
|
||||
ht_setup_chains(i, sysinfo);
|
||||
#else
|
||||
return ht_setup_chains(i);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
static int optimize_link_incoherent_ht(struct sys_info *sysinfo)
|
||||
{
|
||||
// We need to use recorded link pair info to optimize the link
|
||||
int i;
|
||||
int reset_needed = 0;
|
||||
|
||||
unsigned link_pair_num = sysinfo->link_pair_num;
|
||||
|
||||
for(i=0; i< link_pair_num; i++) {
|
||||
struct link_pair_st *link_pair= &sysinfo->link_pair[i];
|
||||
reset_needed |= ht_optimize_link(link_pair->udev, link_pair->upos, link_pair->uoffs, link_pair->dev, link_pair->pos, link_pair->offs);
|
||||
}
|
||||
|
||||
reset_needed |= optimize_link_read_pointers(sysinfo->ht_c_num);
|
||||
|
||||
return reset_needed;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned get_sblnk(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
/* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
|
||||
reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
|
||||
return ((reg>>8) & 3) ;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
#include <part/hard_reset.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <bitops.h>
|
||||
#include "./cpu_rev.c"
|
||||
#include <cpu/amd/model_fxx_rev.h>
|
||||
|
||||
#include "amdk8.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
2004.12 yhlu add dual core support
|
||||
2005.01 yhlu add support move apic before pci_domain in MB Config.lb
|
||||
2005.02 yhlu add e0 memory hole support
|
||||
2005.11 yhlu add put sb ht chain on bus 0
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
|
@ -96,16 +97,15 @@ static unsigned int amdk8_nodeid(device_t dev)
|
|||
return (dev->path.u.pci.devfn >> 3) - 0x18;
|
||||
}
|
||||
|
||||
static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
||||
static unsigned int amdk8_scan_chain(device_t dev, unsigned nodeid, unsigned link, unsigned sblink, unsigned int max, unsigned offset_unitid)
|
||||
{
|
||||
unsigned nodeid;
|
||||
unsigned link;
|
||||
nodeid = amdk8_nodeid(dev);
|
||||
#if 0
|
||||
printk_debug("%s amdk8_scan_chains max: %d starting...\n",
|
||||
dev_path(dev), max);
|
||||
#endif
|
||||
for(link = 0; link < dev->links; link++) {
|
||||
// I want to put sb chain in bus 0 can I?
|
||||
|
||||
|
||||
uint32_t link_type;
|
||||
uint32_t busses, config_busses;
|
||||
unsigned free_reg, config_reg;
|
||||
|
@ -114,13 +114,13 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
|||
link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
|
||||
} while(link_type & ConnectionPending);
|
||||
if (!(link_type & LinkConnected)) {
|
||||
continue;
|
||||
return max;
|
||||
}
|
||||
do {
|
||||
link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
|
||||
} while(!(link_type & InitComplete));
|
||||
if (!(link_type & NonCoherent)) {
|
||||
continue;
|
||||
return max;
|
||||
}
|
||||
/* See if there is an available configuration space mapping
|
||||
* register in function 1.
|
||||
|
@ -146,14 +146,21 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
|||
* register skip this bus
|
||||
*/
|
||||
if (config_reg > 0xec) {
|
||||
continue;
|
||||
return max;
|
||||
}
|
||||
|
||||
/* Set up the primary, secondary and subordinate bus numbers.
|
||||
* We have no idea how many busses are behind this bridge yet,
|
||||
* so we set the subordinate bus number to 0xff for the moment.
|
||||
*/
|
||||
#if K8_SB_HT_CHAIN_ON_BUS0 == 1
|
||||
if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
|
||||
dev->link[link].secondary = max;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
dev->link[link].secondary = ++max;
|
||||
|
||||
dev->link[link].subordinate = 0xff;
|
||||
|
||||
/* Read the existing primary/secondary/subordinate bus
|
||||
|
@ -188,7 +195,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
|||
/* Now we can scan all of the subordinate busses i.e. the
|
||||
* chain on the hypertranport link
|
||||
*/
|
||||
max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max);
|
||||
max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max, offset_unitid);
|
||||
|
||||
#if 0
|
||||
printk_debug("%s Hyper transport scan link: %d new max: %d\n",
|
||||
|
@ -211,6 +218,48 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
|||
printk_debug("%s Hypertransport scan link: %d done\n",
|
||||
dev_path(dev), link);
|
||||
#endif
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
||||
{
|
||||
unsigned nodeid;
|
||||
unsigned link;
|
||||
unsigned sblink = 0;
|
||||
unsigned offset_unitid = 0;
|
||||
nodeid = amdk8_nodeid(dev);
|
||||
|
||||
|
||||
#if 0
|
||||
printk_debug("%s amdk8_scan_chains max: %d starting...\n",
|
||||
dev_path(dev), max);
|
||||
#endif
|
||||
// I want to put sb chain in bus 0
|
||||
|
||||
if(nodeid==0) {
|
||||
sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
|
||||
#if K8_SB_HT_CHAIN_ON_BUS0 == 1
|
||||
#if HT_CHAIN_UNITID_BASE != 1
|
||||
offset_unitid = 1;
|
||||
#endif
|
||||
max = amdk8_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
|
||||
#endif
|
||||
}
|
||||
|
||||
for(link = 0; link < dev->links; link++) {
|
||||
#if K8_SB_HT_CHAIN_ON_BUS0 == 1
|
||||
if( (nodeid == 0) && (sblink == link) ) continue; //already done
|
||||
#endif
|
||||
offset_unitid = 0;
|
||||
#if HT_CHAIN_UNITID_BASE != 1
|
||||
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
||||
if((nodeid == 0) && (sblink == link))
|
||||
#endif
|
||||
offset_unitid = 1;
|
||||
#endif
|
||||
|
||||
max = amdk8_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
|
||||
}
|
||||
#if 0
|
||||
printk_debug("%s amdk8_scan_chains max: %d done\n",
|
||||
|
@ -219,6 +268,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
|||
return max;
|
||||
}
|
||||
|
||||
|
||||
static int reg_useable(unsigned reg,
|
||||
device_t goal_dev, unsigned goal_nodeid, unsigned goal_link)
|
||||
{
|
||||
|
@ -508,7 +558,6 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
|
|||
|
||||
/* release the temp resource */
|
||||
resource->flags = 0;
|
||||
|
||||
}
|
||||
|
||||
static void amdk8_set_resources(device_t dev)
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
|
||||
#ifndef RAMINIT_SYSINFO
|
||||
#define RAMINIT_SYSINFO 0
|
||||
#endif
|
||||
|
||||
static inline void print_debug_sdram_8(const char *strval, uint32_t val)
|
||||
{
|
||||
#if CONFIG_USE_INIT
|
||||
printk_debug("%s%02x\r\n", strval, val);
|
||||
#else
|
||||
print_debug(strval); print_debug_hex8(val); print_debug("\r\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void sdram_no_memory(void)
|
||||
{
|
||||
print_err("No memory!!\r\n");
|
||||
|
@ -7,31 +21,34 @@ void sdram_no_memory(void)
|
|||
}
|
||||
|
||||
/* Setup SDRAM */
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
void sdram_initialize(int controllers, const struct mem_controller *ctrl, void *sysinfo)
|
||||
#else
|
||||
void sdram_initialize(int controllers, const struct mem_controller *ctrl)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
/* Set the registers we can set once to reasonable values */
|
||||
for(i = 0; i < controllers; i++) {
|
||||
#if CONFIG_USE_INIT
|
||||
printk_debug("Ram1.%02x\r\n",i);
|
||||
print_debug_sdram_8("Ram1.",i);
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
sdram_set_registers(ctrl + i , sysinfo);
|
||||
#else
|
||||
print_debug("Ram1.");
|
||||
print_debug_hex8(i);
|
||||
print_debug("\r\n");
|
||||
#endif
|
||||
sdram_set_registers(ctrl + i);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Now setup those things we can auto detect */
|
||||
for(i = 0; i < controllers; i++) {
|
||||
#if CONFIG_USE_INIT
|
||||
printk_debug("Ram2.%02x\r\n",i);
|
||||
print_debug_sdram_8("Ram2.",i);
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
sdram_set_spd_registers(ctrl + i , sysinfo);
|
||||
#else
|
||||
print_debug("Ram2.");
|
||||
print_debug_hex8(i);
|
||||
print_debug("\r\n");
|
||||
#endif
|
||||
sdram_set_spd_registers(ctrl + i);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Now that everything is setup enable the SDRAM.
|
||||
|
@ -39,7 +56,12 @@ void sdram_initialize(int controllers, const struct mem_controller *ctrl)
|
|||
* we need to it by hand.
|
||||
*/
|
||||
print_debug("Ram3\r\n");
|
||||
|
||||
#if RAMINIT_SYSINFO == 1
|
||||
sdram_enable(controllers, ctrl, sysinfo);
|
||||
#else
|
||||
sdram_enable(controllers, ctrl);
|
||||
#endif
|
||||
|
||||
print_debug("Ram4\r\n");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* by yhlu 2005.10 */
|
||||
static void hard_reset(struct sys_info *sysinfo)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
/* Find the device */
|
||||
dev = PCI_DEV(sysinfo->sbbusn, sysinfo->sbdn+1, 3);
|
||||
|
||||
set_bios_reset();
|
||||
|
||||
/* enable cf9 */
|
||||
pci_write_config8(dev, 0x41, 0xf1);
|
||||
/* reset */
|
||||
outb(0x0e, 0x0cf9);
|
||||
}
|
||||
|
||||
static void enable_fid_change_on_sb(struct sys_info *sysinfo)
|
||||
{
|
||||
device_t dev;
|
||||
/* Find the device */
|
||||
dev = PCI_DEV(sysinfo->sbbusn, sysinfo->sbdn+1, 3);
|
||||
|
||||
pci_write_config8(dev, 0x74, 4);
|
||||
|
||||
/* set VFSMAF ( VID/FID System Management Action Field) to 2 */
|
||||
pci_write_config32(dev, 0x70, 2<<12);
|
||||
|
||||
}
|
||||
|
||||
static void soft_reset(struct sys_info *sysinfo)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
/* Find the device */
|
||||
dev = PCI_DEV(sysinfo->sbbusn, sysinfo->sbdn+1, 0);
|
||||
|
||||
set_bios_reset();
|
||||
pci_write_config8(dev, 0x47, 1);
|
||||
}
|
||||
|
||||
|
|
@ -916,7 +916,7 @@ class partobj:
|
|||
if ((slot < 0) or (slot > 0x1f)):
|
||||
fatal("Invalid device id")
|
||||
if ((function < 0) or (function > 7)):
|
||||
fatal("Invalid function")
|
||||
fatal("Invalid pci function %s" % function )
|
||||
self.set_path(".type=DEVICE_PATH_PCI,.u={.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}" % (slot, function))
|
||||
|
||||
def addpnppath(self, port, device):
|
||||
|
@ -939,12 +939,6 @@ class partobj:
|
|||
fatal("Invalid device")
|
||||
self.set_path(".type=DEVICE_PATH_APIC,.u={.apic={ .apic_id = 0x%x }}" % (apic_id))
|
||||
|
||||
def addcpupath(self, cpu_id):
|
||||
""" Add a relative path to a cpu device hanging off our parent """
|
||||
if ((cpu_id < 0) or (cpu_id > 255)):
|
||||
fatal("Invalid device")
|
||||
self.set_path(".type=DEVICE_PATH_CPU,.u={.cpu={ .id = 0x%x }}" % (cpu_id))
|
||||
|
||||
def addpci_domainpath(self, pci_domain):
|
||||
""" Add a pci_domain number to a chip """
|
||||
if ((pci_domain < 0) or (pci_domain > 0xffff)):
|
||||
|
@ -957,11 +951,11 @@ class partobj:
|
|||
fatal("Invalid apic cluster: %d is out of the range 0 to ff" % cluster)
|
||||
self.set_path(".type=DEVICE_PATH_APIC_CLUSTER,.u={.apic_cluster={ .cluster = 0x%x }}" % (cluster))
|
||||
|
||||
def addcpupath(self, id):
|
||||
def addcpupath(self, cpu_id):
|
||||
""" Add a relative path to a cpu device hanging off our parent """
|
||||
if ((id < 0) or (id > 255)):
|
||||
if ((cpu_id < 0) or (cpu_id > 255)):
|
||||
fatal("Invalid device")
|
||||
self.set_path(".type=DEVICE_PATH_CPU,.u={.cpu={ .id = 0x%x }}" % (id))
|
||||
self.set_path(".type=DEVICE_PATH_CPU,.u={.cpu={ .id = 0x%x }}" % (cpu_id))
|
||||
|
||||
|
||||
def addcpu_buspath(self, id):
|
||||
|
@ -2001,6 +1995,7 @@ def writeimagemakefile(image):
|
|||
|
||||
# main rule
|
||||
file.write("\nall: linuxbios.rom\n\n")
|
||||
file.write(".PHONY: all\n\n")
|
||||
#file.write("include cpuflags\n")
|
||||
# Putting "include cpuflags" in the Makefile has the problem that the
|
||||
# cpuflags file would be generated _after_ we want to include it.
|
||||
|
@ -2186,6 +2181,8 @@ def writemakefile(path):
|
|||
file.write(".PHONY: all clean")
|
||||
for i in romimages.keys():
|
||||
file.write(" %s-clean" % i)
|
||||
for i, o in romimages.items():
|
||||
file.write(" %s/linuxbios.rom" % o.getname())
|
||||
file.write("\n\n")
|
||||
|
||||
writemakefilefooter(file, makefilepath)
|
||||
|
|
Loading…
Reference in New Issue