- Apply 11_24_a_s1_core.diff from
https://openbios.org/roundup/linuxbios/issue24 - fix up for via epia-m git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2110 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
b7627bca65
commit
f622d598db
|
@ -7,6 +7,9 @@
|
|||
* ACPI FADT, FACS, and DSDT table support added by
|
||||
* Nick Barker <nick.barker9@btinternet.com>, and those portions
|
||||
* (C) Copyright 2004 Nick Barker
|
||||
*
|
||||
* Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
|
||||
* 2005.9 yhlu add SRAT relate
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -40,8 +43,10 @@ u8 acpi_checksum(u8 *table, u32 length)
|
|||
void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
|
||||
int entries_num = sizeof(rsdt->entry)/sizeof(rsdt->entry[0]);
|
||||
|
||||
for (i=0; i<entries_num; i++) {
|
||||
if(rsdt->entry[i]==0) {
|
||||
rsdt->entry[i]=(u32)table;
|
||||
/* fix length to stop kernel winging about invalid entries */
|
||||
|
@ -52,7 +57,7 @@ void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
|
|||
rsdt->header.checksum=acpi_checksum((u8 *)rsdt,
|
||||
rsdt->header.length);
|
||||
|
||||
printk_debug("ACPI: added table %d/8 Length now %d\n",i+1,rsdt->header.length);
|
||||
printk_debug("ACPI: added table %d/%d Length now %d\n",i+1, entries_num, rsdt->header.length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +138,7 @@ void acpi_create_madt(acpi_madt_t *madt)
|
|||
madt->lapic_addr= LOCAL_APIC_ADDR;
|
||||
madt->flags = 0x1; /* PCAT_COMPAT */
|
||||
|
||||
current = acpi_dump_apics(current);
|
||||
current = acpi_fill_madt(current);
|
||||
|
||||
/* recalculate length */
|
||||
header->length= current - (unsigned long)madt;
|
||||
|
@ -141,6 +146,63 @@ void acpi_create_madt(acpi_madt_t *madt)
|
|||
header->checksum = acpi_checksum((void *)madt, header->length);
|
||||
}
|
||||
|
||||
int acpi_create_srat_lapic(acpi_srat_lapic_t *lapic, u8 node, u8 apic)
|
||||
{
|
||||
lapic->type=0;
|
||||
lapic->length=sizeof(acpi_srat_lapic_t);
|
||||
lapic->flags=1;
|
||||
|
||||
lapic->proximity_domain_7_0 = node;
|
||||
lapic->apic_id=apic;
|
||||
|
||||
return(lapic->length);
|
||||
}
|
||||
|
||||
int acpi_create_srat_mem(acpi_srat_mem_t *mem, u8 node, u32 basek,u32 sizek, u32 flags)
|
||||
{
|
||||
mem->type=1;
|
||||
mem->length=sizeof(acpi_srat_mem_t);
|
||||
|
||||
mem->base_address_low = (basek<<10);
|
||||
mem->base_address_high = (basek>>(32-10));
|
||||
|
||||
mem->length_low = (sizek<<10);
|
||||
mem->length_high = (sizek>>(32-10));
|
||||
|
||||
mem->proximity_domain = node;
|
||||
|
||||
mem->flags = flags;
|
||||
|
||||
return(mem->length);
|
||||
}
|
||||
|
||||
void acpi_create_srat(acpi_srat_t *srat)
|
||||
{
|
||||
|
||||
acpi_header_t *header=&(srat->header);
|
||||
unsigned long current=(unsigned long)srat+sizeof(acpi_srat_t);
|
||||
|
||||
memset((void *)srat, 0, sizeof(acpi_srat_t));
|
||||
|
||||
/* fill out header fields */
|
||||
memcpy(header->signature, SRAT_NAME, 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, SRAT_TABLE, 8);
|
||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||
|
||||
header->length = sizeof(acpi_srat_t);
|
||||
header->revision = 1;
|
||||
|
||||
srat->resv = 0x1; /* BACK COMP */
|
||||
|
||||
current = acpi_fill_srat(current);
|
||||
|
||||
/* recalculate length */
|
||||
header->length= current - (unsigned long)srat;
|
||||
|
||||
header->checksum = acpi_checksum((void *)srat, header->length);
|
||||
}
|
||||
|
||||
void acpi_create_hpet(acpi_hpet_t *hpet)
|
||||
{
|
||||
#define HPET_ADDR 0xfed00000ULL
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
*
|
||||
* The ACPI table structs are based on the Linux kernel sources.
|
||||
*
|
||||
*/
|
||||
/* ACPI FADT & FACS added by Nick Barker <nick.barker9@btinternet.com>
|
||||
* ACPI FADT & FACS added by Nick Barker <nick.barker9@btinternet.com>
|
||||
* those parts (C) 2004 Nick Barker
|
||||
*
|
||||
* ACPI SRAT support 2005.9 yhlu add SRAT relate
|
||||
* Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
@ -28,10 +31,12 @@ typedef unsigned long long u64;
|
|||
#define RSDT_NAME "RSDT"
|
||||
#define HPET_NAME "HPET"
|
||||
#define MADT_NAME "APIC"
|
||||
#define SRAT_NAME "SRAT"
|
||||
|
||||
#define RSDT_TABLE "RSDT "
|
||||
#define HPET_TABLE "AMD64 "
|
||||
#define MADT_TABLE "MADT "
|
||||
#define SRAT_TABLE "SRAT "
|
||||
|
||||
#define OEM_ID "LXBIOS"
|
||||
#define ASLC "NONE"
|
||||
|
@ -79,13 +84,13 @@ typedef struct acpi_table_header /* ACPI common table header */
|
|||
/* RSDT */
|
||||
typedef struct acpi_rsdt {
|
||||
struct acpi_table_header header;
|
||||
u32 entry[8];
|
||||
u32 entry[5+ACPI_SSDTX_NUM]; /* HPET, FADT, SRAT, MADT(APIC), SSDT, SSDTX */
|
||||
} __attribute__ ((packed)) acpi_rsdt_t;
|
||||
|
||||
/* XSDT */
|
||||
typedef struct acpi_xsdt {
|
||||
struct acpi_table_header header;
|
||||
u64 entry[8];
|
||||
u64 entry[5+ACPI_SSDTX_NUM];
|
||||
} __attribute__ ((packed)) acpi_xsdt_t;
|
||||
|
||||
|
||||
|
@ -99,6 +104,43 @@ typedef struct acpi_hpet {
|
|||
u8 attributes;
|
||||
} __attribute__ ((packed)) acpi_hpet_t;
|
||||
|
||||
/* SRAT */
|
||||
typedef struct acpi_srat {
|
||||
struct acpi_table_header header;
|
||||
u32 resv;
|
||||
u64 resv1;
|
||||
/* followed by static resource allocation structure[n]*/
|
||||
} __attribute__ ((packed)) acpi_srat_t;
|
||||
|
||||
|
||||
typedef struct acpi_srat_lapic {
|
||||
u8 type;
|
||||
u8 length;
|
||||
u8 proximity_domain_7_0;
|
||||
u8 apic_id;
|
||||
u32 flags; /* enable bit 0 = 1, other bits reserved to 0 */
|
||||
u8 local_sapic_eid;
|
||||
u8 proximity_domain_31_8[3];
|
||||
u32 resv;
|
||||
} __attribute__ ((packed)) acpi_srat_lapic_t;
|
||||
|
||||
typedef struct acpi_srat_mem {
|
||||
u8 type;
|
||||
u8 length;
|
||||
u32 proximity_domain;
|
||||
u16 resv;
|
||||
u32 base_address_low;
|
||||
u32 base_address_high;
|
||||
u32 length_low;
|
||||
u32 length_high;
|
||||
u32 resv1;
|
||||
u32 flags; /* enable bit 0, hot pluggable bit 1; Non Volatile bit 2, other bits reserved */
|
||||
u32 resv2[2];
|
||||
} __attribute__ ((packed)) acpi_srat_mem_t;
|
||||
|
||||
|
||||
|
||||
/* MADT */
|
||||
typedef struct acpi_madt {
|
||||
struct acpi_table_header header;
|
||||
u32 lapic_addr;
|
||||
|
@ -152,6 +194,7 @@ typedef struct acpi_madt_irqoverride {
|
|||
u16 flags;
|
||||
} __attribute__ ((packed)) acpi_madt_irqoverride_t;
|
||||
|
||||
/* FADT */
|
||||
|
||||
typedef struct acpi_fadt {
|
||||
struct acpi_table_header header;
|
||||
|
@ -212,6 +255,7 @@ typedef struct acpi_fadt {
|
|||
struct acpi_gen_regaddr x_gpe1_blk;
|
||||
} __attribute__ ((packed)) acpi_fadt_t;
|
||||
|
||||
/* FACS */
|
||||
typedef struct acpi_facs {
|
||||
char signature[4];
|
||||
u32 length;
|
||||
|
@ -227,17 +271,35 @@ typedef struct acpi_facs {
|
|||
|
||||
/* These are implemented by the target port */
|
||||
unsigned long write_acpi_tables(unsigned long addr);
|
||||
unsigned long acpi_dump_apics(unsigned long current);
|
||||
|
||||
unsigned long acpi_fill_madt(unsigned long current);
|
||||
unsigned long acpi_fill_srat(unsigned long current);
|
||||
void acpi_create_fadt(acpi_fadt_t *fadt,acpi_facs_t *facs,void *dsdt);
|
||||
|
||||
/* These can be used by the target port */
|
||||
u8 acpi_checksum(u8 *table, u32 length);
|
||||
|
||||
void acpi_add_table(acpi_rsdt_t *rsdt, void *table);
|
||||
|
||||
int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic);
|
||||
int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr,u32 gsi_base);
|
||||
int acpi_create_madt_irqoverride(acpi_madt_irqoverride_t *irqoverride,
|
||||
u8 bus, u8 source, u32 gsirq, u16 flags);
|
||||
int acpi_create_madt_lapic_nmi(acpi_madt_lapic_nmi_t *lapic_nmi, u8 cpu,
|
||||
u16 flags, u8 lint);
|
||||
void acpi_create_madt(acpi_madt_t *madt);
|
||||
unsigned long acpi_create_madt_lapics(unsigned long current);
|
||||
unsigned long acpi_create_madt_lapic_nmis(unsigned long current, u16 flags, u8 lint);
|
||||
|
||||
|
||||
int acpi_create_srat_lapic(acpi_srat_lapic_t *lapic, u8 node, u8 apic);
|
||||
int acpi_create_srat_mem(acpi_srat_mem_t *mem, u8 node, u32 basek,u32 sizek, u32 flags);
|
||||
unsigned long acpi_create_srat_lapics(unsigned long current);
|
||||
void acpi_create_srat(acpi_srat_t *srat);
|
||||
|
||||
void acpi_create_hpet(acpi_hpet_t *hpet);
|
||||
|
||||
void acpi_create_facs(acpi_facs_t *facs);
|
||||
|
||||
void acpi_write_rsdt(acpi_rsdt_t *rsdt);
|
||||
void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt);
|
||||
|
||||
|
|
|
@ -778,6 +778,12 @@ define HAVE_ACPI_TABLES
|
|||
comment "Define to build ACPI tables"
|
||||
end
|
||||
|
||||
define ACPI_SSDTX_NUM
|
||||
default 0
|
||||
export always
|
||||
comment "extra ssdt num for PCI Device"
|
||||
end
|
||||
|
||||
define AGP_APERTURE_SIZE
|
||||
default none
|
||||
export used
|
||||
|
|
|
@ -49,10 +49,14 @@ void amd_sibling_init(device_t cpu, struct node_core_id id)
|
|||
cpu_path.type = DEVICE_PATH_APIC;
|
||||
cpu_path.u.apic.apic_id =
|
||||
(0x10 + i*0x10 + id.nodeid);
|
||||
|
||||
new = alloc_dev(cpu->bus, &cpu_path);
|
||||
if (!new) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new->path.u.apic.node_id = cpu->path.u.apic.node_id;
|
||||
new->path.u.apic.core_id = i;
|
||||
/* Report what I have done */
|
||||
printk_debug("CPU: %s %s\n",
|
||||
dev_path(new), new->enabled?"enabled":"disabled");
|
||||
|
|
|
@ -38,6 +38,8 @@ struct i2c_path
|
|||
struct apic_path
|
||||
{
|
||||
unsigned apic_id;
|
||||
unsigned node_id;
|
||||
unsigned core_id;
|
||||
};
|
||||
|
||||
struct apic_cluster_path
|
||||
|
|
|
@ -13,11 +13,16 @@
|
|||
|
||||
extern unsigned char AmlCode[];
|
||||
|
||||
unsigned long acpi_dump_apics(unsigned long current)
|
||||
unsigned long acpi_fill_madt(unsigned long current)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
unsigned long acpi_fill_srat(unsigned long current)
|
||||
{
|
||||
/* No NUMA, no SRAT */
|
||||
}
|
||||
|
||||
unsigned long write_acpi_tables(unsigned long start)
|
||||
{
|
||||
unsigned long current;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
uses CONFIG_CHIP_NAME
|
||||
uses AGP_APERTURE_SIZE
|
||||
uses HAVE_ACPI_TABLES
|
||||
|
||||
default AGP_APERTURE_SIZE=0x4000000
|
||||
|
||||
if CONFIG_CHIP_NAME
|
||||
|
@ -14,3 +16,9 @@ makerule raminit_test
|
|||
depends "$(TOP)/src/northbridge/amd/amdk8/raminit.c"
|
||||
action "$(HOSTCC) $(HOSTCFLAGS) $(CPUFLAGS) -Wno-unused-function -I$(TOP)/src/include -g $< -o $@"
|
||||
end
|
||||
|
||||
if HAVE_ACPI_TABLES
|
||||
object amdk8_acpi.o
|
||||
end
|
||||
|
||||
object get_sblk_pci1234.o
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*============================================================================
|
||||
Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
|
||||
This software and any related documentation (the "Materials") are the
|
||||
confidential proprietary information of AMD. Unless otherwise provided in a
|
||||
software agreement specifically licensing the Materials, the Materials are
|
||||
provided in confidence and may not be distributed, modified, or reproduced in
|
||||
whole or in part by any means.
|
||||
LIMITATION OF LIABILITY: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY
|
||||
EXPRESS OR IMPLIED WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO
|
||||
WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY
|
||||
PARTICULAR PURPOSE, OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR
|
||||
USAGE OF TRADE. IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY
|
||||
DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,
|
||||
BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR
|
||||
INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION
|
||||
OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
|
||||
LIMITATION MAY NOT APPLY TO YOU.
|
||||
AMD does not assume any responsibility for any errors which may appear in the
|
||||
Materials nor any responsibility to support or update the Materials. AMD
|
||||
retains the right to modify the Materials at any time, without notice, and is
|
||||
not obligated to provide such modified Materials to you.
|
||||
NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
|
||||
further information, software, technical information, know-how, or show-how
|
||||
available to you.
|
||||
U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with "RESTRICTED
|
||||
RIGHTS." Use, duplication, or disclosure by the Government is subject to the
|
||||
restrictions as set forth in FAR 52.227-14 and DFAR 252.227-7013, et seq., or
|
||||
its successor. Use of the Materials by the Government constitutes
|
||||
acknowledgement of AMD's proprietary rights in them.
|
||||
============================================================================*/
|
||||
// 2005.9 serengeti support
|
||||
// by yhlu
|
||||
//
|
||||
|
||||
/*
|
||||
* 2005.9 yhlu add madt lapic creat dynamically and SRAT related
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <string.h>
|
||||
#include <arch/acpi.h>
|
||||
#include <device/pci.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/amd/mtrr.h>
|
||||
|
||||
//it seems these function can be moved arch/i386/boot/acpi.c
|
||||
|
||||
unsigned long acpi_create_madt_lapics(unsigned long current)
|
||||
{
|
||||
device_t cpu;
|
||||
int cpu_index = 0;
|
||||
|
||||
for(cpu = all_devices; cpu; cpu = cpu->next) {
|
||||
if ((cpu->path.type != DEVICE_PATH_APIC) ||
|
||||
(cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!cpu->enabled) {
|
||||
continue;
|
||||
}
|
||||
current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, cpu_index, cpu->path.u.apic.apic_id);
|
||||
cpu_index++;
|
||||
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
unsigned long acpi_create_madt_lapic_nmis(unsigned long current, u16 flags, u8 lint)
|
||||
{
|
||||
device_t cpu;
|
||||
int cpu_index = 0;
|
||||
|
||||
for(cpu = all_devices; cpu; cpu = cpu->next) {
|
||||
if ((cpu->path.type != DEVICE_PATH_APIC) ||
|
||||
(cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!cpu->enabled) {
|
||||
continue;
|
||||
}
|
||||
current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, cpu_index, flags, lint);
|
||||
cpu_index++;
|
||||
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
unsigned long acpi_create_srat_lapics(unsigned long current)
|
||||
{
|
||||
device_t cpu;
|
||||
int cpu_index = 0;
|
||||
|
||||
for(cpu = all_devices; cpu; cpu = cpu->next) {
|
||||
if ((cpu->path.type != DEVICE_PATH_APIC) ||
|
||||
(cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!cpu->enabled) {
|
||||
continue;
|
||||
}
|
||||
printk_debug("SRAT: lapic cpu_index=%02x, node_id=%02x, apic_id=%02x\n", cpu_index, cpu->path.u.apic.node_id, cpu->path.u.apic.apic_id);
|
||||
current += acpi_create_srat_lapic((acpi_srat_lapic_t *)current, cpu->path.u.apic.node_id, cpu->path.u.apic.apic_id);
|
||||
cpu_index++;
|
||||
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
static unsigned long resk(uint64_t value)
|
||||
{
|
||||
unsigned long resultk;
|
||||
if (value < (1ULL << 42)) {
|
||||
resultk = value >> 10;
|
||||
}
|
||||
else {
|
||||
resultk = 0xffffffff;
|
||||
}
|
||||
return resultk;
|
||||
}
|
||||
|
||||
|
||||
struct acpi_srat_mem_state {
|
||||
unsigned long current;
|
||||
};
|
||||
|
||||
void set_srat_mem(void *gp, struct device *dev, struct resource *res)
|
||||
{
|
||||
struct acpi_srat_mem_state *state = gp;
|
||||
unsigned long basek, sizek;
|
||||
basek = resk(res->base);
|
||||
sizek = resk(res->size);
|
||||
|
||||
printk_debug("set_srat_mem: dev %s, res->index=%04x startk=%08x, sizek=%08x\n",
|
||||
dev_path(dev), res->index, basek, sizek);
|
||||
/*
|
||||
0-640K must be on node 0
|
||||
next range is from 1M---
|
||||
So will cut off before 1M in the mem range
|
||||
*/
|
||||
if((basek+sizek)<1024) return;
|
||||
|
||||
if(basek<1024) {
|
||||
sizek -= 1024 - basek;
|
||||
basek = 1024;
|
||||
}
|
||||
|
||||
state->current += acpi_create_srat_mem((acpi_srat_mem_t *)state->current, (res->index & 0xf), basek, sizek, 1); // need to figure out NV
|
||||
}
|
||||
|
||||
|
||||
unsigned long acpi_fill_srat(unsigned long current)
|
||||
{
|
||||
struct acpi_srat_mem_state srat_mem_state;
|
||||
|
||||
/* create all subtables for processors */
|
||||
current = acpi_create_srat_lapics(current);
|
||||
|
||||
/* create all subteble for memory range */
|
||||
|
||||
/* 0-640K must be on node 0 */
|
||||
current += acpi_create_srat_mem((acpi_srat_mem_t *)current, 0, 0, 640, 1);//enable
|
||||
#if 1
|
||||
srat_mem_state.current = current;
|
||||
search_global_resources(
|
||||
IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE,
|
||||
set_srat_mem, &srat_mem_state);
|
||||
|
||||
current = srat_mem_state.current;
|
||||
#endif
|
||||
return current;
|
||||
}
|
||||
//end
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
/*============================================================================
|
||||
Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
|
||||
This software and any related documentation (the "Materials") are the
|
||||
confidential proprietary information of AMD. Unless otherwise provided in a
|
||||
software agreement specifically licensing the Materials, the Materials are
|
||||
provided in confidence and may not be distributed, modified, or reproduced in
|
||||
whole or in part by any means.
|
||||
LIMITATION OF LIABILITY: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY
|
||||
EXPRESS OR IMPLIED WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO
|
||||
WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY
|
||||
PARTICULAR PURPOSE, OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR
|
||||
USAGE OF TRADE. IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY
|
||||
DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,
|
||||
BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR
|
||||
INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION
|
||||
OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
|
||||
LIMITATION MAY NOT APPLY TO YOU.
|
||||
AMD does not assume any responsibility for any errors which may appear in the
|
||||
Materials nor any responsibility to support or update the Materials. AMD
|
||||
retains the right to modify the Materials at any time, without notice, and is
|
||||
not obligated to provide such modified Materials to you.
|
||||
NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
|
||||
further information, software, technical information, know-how, or show-how
|
||||
available to you.
|
||||
U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with "RESTRICTED
|
||||
RIGHTS." Use, duplication, or disclosure by the Government is subject to the
|
||||
restrictions as set forth in FAR 52.227-14 and DFAR 252.227-7013, et seq., or
|
||||
its successor. Use of the Materials by the Government constitutes
|
||||
acknowledgement of AMD's proprietary rights in them.
|
||||
============================================================================*/
|
||||
// 2005.9 serengeti support
|
||||
// by yhlu
|
||||
// 2005.9 yhlu modify that to more dynamic for AMD Opteron Based MB
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#if 0
|
||||
unsigned node_link_to_bus(unsigned node, unsigned link)
|
||||
{
|
||||
device_t dev;
|
||||
unsigned reg;
|
||||
|
||||
dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
|
||||
if (!dev) {
|
||||
return 0;
|
||||
}
|
||||
for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
|
||||
uint32_t config_map;
|
||||
unsigned dst_node;
|
||||
unsigned dst_link;
|
||||
unsigned bus_base;
|
||||
config_map = pci_read_config32(dev, reg);
|
||||
if ((config_map & 3) != 3) {
|
||||
continue;
|
||||
}
|
||||
dst_node = (config_map >> 4) & 7;
|
||||
dst_link = (config_map >> 8) & 3;
|
||||
bus_base = (config_map >> 16) & 0xff;
|
||||
#if 0
|
||||
printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
|
||||
dst_node, dst_link, bus_base,
|
||||
reg, config_map);
|
||||
#endif
|
||||
if ((dst_node == node) && (dst_link == link))
|
||||
{
|
||||
return bus_base;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern unsigned pci1234[];
|
||||
extern unsigned hc_possible_num;
|
||||
extern unsigned sblk;
|
||||
|
||||
/* why we need pci1234 array
|
||||
final result for pci1234 will be
|
||||
pci1234[0] will record sblink and bus range
|
||||
pci1234[i] will record ht chain i.
|
||||
it will keep the sequence when some ht io card is not installed.
|
||||
|
||||
for Tyan S2885 the linxbios_ram will put 8151 chain (link 0) to 0xE0 reg, and 8131/8111 on 0xe4 reg, So we need to make sure the sb link
|
||||
will always on pci1234[0]
|
||||
for multi ht-io cards, if you don't install htio1, and only installed htio2, htio3, the htio will be on 0xe4, and 0xe8.
|
||||
but we want to leave pci1234[1] to htio1 (even it is disabled) , and let htio2 and htio3 still use pci1234[2] and pci1234[3]
|
||||
So we keep the sequence. ---- you need to preset the pci1234[1], pci1234[2], pci1234[3] for this purpose
|
||||
for example you need set
|
||||
unsigned pci1234[] = {
|
||||
0x0000ff0,
|
||||
0x0000f10, // HT IO 1 card always on node 1
|
||||
0x0000f20, // HT IO 2 card always on node 2
|
||||
0x0000f30 // HT IO 3 card always on node 3
|
||||
};
|
||||
|
||||
for 2p+htio(n1)+htio(n0_1)+htio(n1_1),2p+htio(n1)+2p+htio(n2)+htio(n3) : need pci1234[6]
|
||||
unsigned pci1234[] = {
|
||||
0x0000ff0,
|
||||
0x0000010, // HT IO 1 card always on node 1
|
||||
0x0000f00, // HT IO 2 card always on node 0
|
||||
0x0000110, // HT IO 3 card always on node 1
|
||||
0x0000f20, // HT IO 4 card always on node 2
|
||||
0x0000f30 // HT IO 5 card always on node 3
|
||||
};
|
||||
|
||||
for 4p+htio(n1)+htio(n2)+htio(n3),4p+htio(n1)+4p+htio(n6)+htio(n7) : need pci1234[6]
|
||||
unsigned pci1234[] = {
|
||||
0x0000ff0,
|
||||
0x0000f10, // HT IO 1 card always on node 1
|
||||
0x0000f20, // HT IO 2 card always on node 2
|
||||
0x0000f30, // HT IO 3 card always on node 3
|
||||
0x0000f60, // HT IO 4 card always on node 6
|
||||
0x0000f70 // HT IO 5 card always on node 7
|
||||
};
|
||||
|
||||
|
||||
for 2p+htio(n1)+htio(n0_1)+htio(n1_1), 2p+htio(n1)+2p+htio(n2)+htio(n3), 2p+htio(n1)+4p+htio(n4)+htio(n5), need pci1234[8]
|
||||
unsigned pci1234[] = {
|
||||
0x0000ff0,
|
||||
0x0000010, // HT IO 1 card always on node 1
|
||||
0x0000f00, // HT IO 2 card always on node 0
|
||||
0x0000110, // HT IO 3 card always on node 1
|
||||
0x0000f20, // HT IO 4 card always on node 2
|
||||
0x0000f30 // HT IO 5 card always on node 3
|
||||
0x0000f40, // HT IO 6 card always on node 4
|
||||
0x0000f50 // HT IO 7 card always on node 5
|
||||
};
|
||||
|
||||
|
||||
for 4p+htio(n1)+htio(n2)+htio(n3), 4p+htio(n1)+2p+htio(n4)+htio(n5), 4p+htio(n1)+4p+htio(n6)+htio(n7), need pci1234[8]
|
||||
unsigned pci1234[] = {
|
||||
0x0000ff0,
|
||||
0x0000f10, // HT IO 1 card always on node 1
|
||||
0x0000f20, // HT IO 2 card always on node 2
|
||||
0x0000f30, // HT IO 3 card always on node 3
|
||||
0x0000f40, // HT IO 4 card always on node 4
|
||||
0x0000f50 // HT IO 5 card always on node 5
|
||||
0x0000f60, // HT IO 6 card always on node 6
|
||||
0x0000f70 // HT IO 7 card always on node 7
|
||||
};
|
||||
|
||||
|
||||
So Max HC_POSSIBLE_NUM is 8
|
||||
|
||||
just put all the possible ht node/link to the list tp pci1234[] in get_bus_conf.c on MB dir
|
||||
|
||||
Also don't forget to increase the ACPI_SSDTX_NUM etc if you have too much SSDT
|
||||
|
||||
How about co-processor on socket 1 on 2 way system. or socket 2, and socket3 on 4 way system....? treat that as one hc too!
|
||||
|
||||
*/
|
||||
void get_sblk_pci1234(void)
|
||||
{
|
||||
|
||||
device_t dev;
|
||||
int i,j;
|
||||
uint32_t dword;
|
||||
|
||||
/* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
|
||||
dev = dev_find_slot(0, PCI_DEVFN(0x18,0));
|
||||
dword = pci_read_config32(dev, 0x64);
|
||||
sblk = (dword>>8) & 0x3;
|
||||
|
||||
dword &=0x0300;
|
||||
dword |= 1;
|
||||
pci1234[0] = dword;
|
||||
|
||||
/*about hardcode numbering for HT_IO support
|
||||
set the node_id and link_id that could have ht chain in the one array,
|
||||
then check if is enabled.... then update final value
|
||||
*/
|
||||
dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
|
||||
for(j=0;j<4;j++) {
|
||||
uint32_t dwordx;
|
||||
dwordx = pci_read_config32(dev, 0xe0+j*4);
|
||||
dwordx &=0xffff0ff1; //keep bus num, node_id, link_num, enable bits
|
||||
if((dwordx & 0xff1) == dword) { //SBLINK
|
||||
pci1234[0] = dwordx;
|
||||
continue;
|
||||
}
|
||||
if((dwordx & 1) == 1) {
|
||||
// We need to find out the number of HC
|
||||
// for exact match
|
||||
for(i=1;i<hc_possible_num;i++) {
|
||||
if((dwordx & 0xff0) == (pci1234[i] & 0xff0)) {
|
||||
pci1234[i] = dwordx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// for 0xff0 match or same node
|
||||
for(i=1;i<hc_possible_num;i++) {
|
||||
if((dwordx & 0xff0) == (dwordx & pci1234[i] & 0xff0)) {
|
||||
pci1234[i] = dwordx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i=1;i<hc_possible_num;i++) {
|
||||
if((pci1234[i] & 1) != 1) {
|
||||
pci1234[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -692,7 +692,7 @@ static void pci_domain_set_resources(device_t dev)
|
|||
/* Round mmio_basek to something the processor can support */
|
||||
mmio_basek &= ~((1 << 6) -1);
|
||||
|
||||
idx = 10;
|
||||
idx = 0x10;
|
||||
for(i = 0; i < 8; i++) {
|
||||
uint32_t base, limit;
|
||||
unsigned basek, limitk, sizek;
|
||||
|
@ -708,7 +708,8 @@ static void pci_domain_set_resources(device_t dev)
|
|||
|
||||
/* see if we need a hole from 0xa0000 to 0xbffff */
|
||||
if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
|
||||
ram_resource(dev, idx++, basek, ((8*64)+(8*16)) - basek);
|
||||
ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
|
||||
idx += 0x10;
|
||||
basek = (8*64)+(16*16);
|
||||
sizek = limitk - ((8*64)+(16*16));
|
||||
|
||||
|
@ -720,7 +721,8 @@ static void pci_domain_set_resources(device_t dev)
|
|||
if (basek < mmio_basek) {
|
||||
unsigned pre_sizek;
|
||||
pre_sizek = mmio_basek - basek;
|
||||
ram_resource(dev, idx++, basek, pre_sizek);
|
||||
ram_resource(dev, (idx | i), basek, pre_sizek);
|
||||
idx += 0x10;
|
||||
sizek -= pre_sizek;
|
||||
if(! is_cpu_pre_e0() ) {
|
||||
sizek += hoist_memory(mmio_basek,i);
|
||||
|
@ -735,7 +737,8 @@ static void pci_domain_set_resources(device_t dev)
|
|||
sizek -= (4*1024*1024 - mmio_basek);
|
||||
}
|
||||
}
|
||||
ram_resource(dev, idx++, basek, sizek);
|
||||
ram_resource(dev, (idx | i), basek, sizek);
|
||||
idx += 0x10;
|
||||
}
|
||||
assign_resources(&dev->link[0]);
|
||||
}
|
||||
|
@ -838,6 +841,8 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
|
|||
|
||||
/* Report what I have done */
|
||||
if (cpu) {
|
||||
cpu->path.u.apic.node_id = i;
|
||||
cpu->path.u.apic.core_id = 0;
|
||||
printk_debug("CPU: %s %s\n",
|
||||
dev_path(cpu), cpu->enabled?"enabled":"disabled");
|
||||
}
|
||||
|
|
|
@ -66,6 +66,10 @@ static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
|
|||
return do_smbus_write_byte(res->base, device, address, val);
|
||||
}
|
||||
|
||||
#if HAVE_ACPI_TABLES == 1
|
||||
unsigned pm_base;
|
||||
#endif
|
||||
|
||||
static void acpi_init(struct device *dev)
|
||||
{
|
||||
uint8_t byte;
|
||||
|
@ -129,6 +133,12 @@ static void acpi_init(struct device *dev)
|
|||
printk_debug("Throttling CPU %2d.%1.1d percent.\n",
|
||||
(on*12)+(on>>1),(on&1)*5);
|
||||
}
|
||||
|
||||
#if HAVE_ACPI_TABLES == 1
|
||||
pm_base = pci_read_config16(dev, 0x58) & 0xff00;
|
||||
printk_debug("pm_base: 0x%04x\n",pm_base);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void acpi_read_resources(device_t dev)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
driver amd8132_bridge.o
|
|
@ -0,0 +1,457 @@
|
|||
/*============================================================================
|
||||
Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
|
||||
This software and any related documentation (the "Materials") are the
|
||||
confidential proprietary information of AMD. Unless otherwise provided in a
|
||||
software agreement specifically licensing the Materials, the Materials are
|
||||
provided in confidence and may not be distributed, modified, or reproduced in
|
||||
whole or in part by any means.
|
||||
LIMITATION OF LIABILITY: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY
|
||||
EXPRESS OR IMPLIED WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO
|
||||
WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY
|
||||
PARTICULAR PURPOSE, OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR
|
||||
USAGE OF TRADE. IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY
|
||||
DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,
|
||||
BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR
|
||||
INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION
|
||||
OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
|
||||
LIMITATION MAY NOT APPLY TO YOU.
|
||||
AMD does not assume any responsibility for any errors which may appear in the
|
||||
Materials nor any responsibility to support or update the Materials. AMD
|
||||
retains the right to modify the Materials at any time, without notice, and is
|
||||
not obligated to provide such modified Materials to you.
|
||||
NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
|
||||
further information, software, technical information, know-how, or show-how
|
||||
available to you.
|
||||
U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with "RESTRICTED
|
||||
RIGHTS." Use, duplication, or disclosure by the Government is subject to the
|
||||
restrictions as set forth in FAR 52.227-14 and DFAR 252.227-7013, et seq., or
|
||||
its successor. Use of the Materials by the Government constitutes
|
||||
acknowledgement of AMD's proprietary rights in them.
|
||||
============================================================================*/
|
||||
//@DOC
|
||||
// in amd8132_bridge.c
|
||||
/*
|
||||
$1.0$
|
||||
*/
|
||||
// Description: amd 8132 support
|
||||
// by yhlu
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <device/pcix.h>
|
||||
|
||||
#define NMI_OFF 0
|
||||
|
||||
#define NPUML 0xD9 /* Non prefetchable upper memory limit */
|
||||
#define NPUMB 0xD8 /* Non prefetchable upper memory base */
|
||||
|
||||
static void amd8132_walk_children(struct bus *bus,
|
||||
void (*visit)(device_t dev, void *ptr), void *ptr)
|
||||
{
|
||||
device_t child;
|
||||
for(child = bus->children; child; child = child->sibling)
|
||||
{
|
||||
if (child->path.type != DEVICE_PATH_PCI) {
|
||||
continue;
|
||||
}
|
||||
if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
|
||||
amd8132_walk_children(&child->link[0], visit, ptr);
|
||||
}
|
||||
visit(child, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
struct amd8132_bus_info {
|
||||
unsigned sstatus;
|
||||
unsigned rev;
|
||||
int master_devices;
|
||||
int max_func;
|
||||
};
|
||||
|
||||
static void amd8132_count_dev(device_t dev, void *ptr)
|
||||
{
|
||||
struct amd8132_bus_info *info = ptr;
|
||||
/* Don't count pci bridges */
|
||||
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
|
||||
info->master_devices++;
|
||||
}
|
||||
if (PCI_FUNC(dev->path.u.pci.devfn) > info->max_func) {
|
||||
info->max_func = PCI_FUNC(dev->path.u.pci.devfn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void amd8132_pcix_tune_dev(device_t dev, void *ptr)
|
||||
{
|
||||
struct amd8132_bus_info *info = ptr;
|
||||
unsigned cap;
|
||||
unsigned status, cmd, orig_cmd;
|
||||
unsigned max_read, max_tran;
|
||||
int sibs;
|
||||
|
||||
if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) {
|
||||
return;
|
||||
}
|
||||
cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
|
||||
if (!cap) {
|
||||
return;
|
||||
}
|
||||
/* How many siblings does this device have? */
|
||||
sibs = info->master_devices - 1;
|
||||
|
||||
printk_debug("%s AMD8132 PCI-X tuning\n", dev_path(dev));
|
||||
status = pci_read_config32(dev, cap + PCI_X_STATUS);
|
||||
orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD);
|
||||
|
||||
max_read = (status & PCI_X_STATUS_MAX_READ) >> 21;
|
||||
max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23;
|
||||
|
||||
if (info->rev == 0x01) { // only a1 need it
|
||||
/* Errata #53 Limit the number of split transactions to avoid starvation */
|
||||
if (sibs >= 2) {
|
||||
/* At most 2 outstanding split transactions when we have
|
||||
* 3 or more bus master devices on the bus.
|
||||
*/
|
||||
if (max_tran > 1) {
|
||||
max_tran = 1;
|
||||
}
|
||||
}
|
||||
else if (sibs == 1) {
|
||||
/* At most 4 outstanding split transactions when we have
|
||||
* 2 bus master devices on the bus.
|
||||
*/
|
||||
if (max_tran > 3) {
|
||||
max_tran = 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* At most 8 outstanding split transactions when we have
|
||||
* only one bus master device on the bus.
|
||||
*/
|
||||
if (max_tran > 4) {
|
||||
max_tran = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) {
|
||||
cmd &= ~PCI_X_CMD_MAX_READ;
|
||||
cmd |= max_read << 2;
|
||||
}
|
||||
if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) {
|
||||
cmd &= ~PCI_X_CMD_MAX_SPLIT;
|
||||
cmd |= max_tran << 4;
|
||||
}
|
||||
|
||||
/* Don't attempt to handle PCI-X errors */
|
||||
cmd &= ~PCI_X_CMD_DPERR_E;
|
||||
if (orig_cmd != cmd) {
|
||||
pci_write_config16(dev, cap + PCI_X_CMD, cmd);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
static unsigned int amd8132_scan_bus(struct bus *bus,
|
||||
unsigned min_devfn, unsigned max_devfn, unsigned int max)
|
||||
{
|
||||
struct amd8132_bus_info info;
|
||||
unsigned pos;
|
||||
|
||||
|
||||
/* Find the children on the bus */
|
||||
max = pci_scan_bus(bus, min_devfn, max_devfn, max);
|
||||
|
||||
/* Find the revision of the 8132 */
|
||||
info.rev = pci_read_config8(bus->dev, PCI_CLASS_REVISION);
|
||||
|
||||
/* Find the pcix capability and get the secondary bus status */
|
||||
pos = pci_find_capability(bus->dev, PCI_CAP_ID_PCIX);
|
||||
info.sstatus = pci_read_config16(bus->dev, pos + PCI_X_SEC_STATUS);
|
||||
|
||||
/* Print the PCI-X bus speed */
|
||||
printk_debug("PCI: %02x: %s sstatus=%04x rev=%02x \n", bus->secondary, pcix_speed(info.sstatus), info.sstatus, info.rev);
|
||||
|
||||
|
||||
/* Examine the bus and find out how loaded it is */
|
||||
info.max_func = 0;
|
||||
info.master_devices = 0;
|
||||
amd8132_walk_children(bus, amd8132_count_dev, &info);
|
||||
|
||||
#if 0
|
||||
/* Disable the bus if there are no devices on it
|
||||
*/
|
||||
if (!bus->children)
|
||||
{
|
||||
unsigned pcix_misc;
|
||||
/* Disable all of my children */
|
||||
disable_children(bus);
|
||||
|
||||
/* Remember the device is disabled */
|
||||
bus->dev->enabled = 0;
|
||||
|
||||
/* Disable the PCI-X clocks */
|
||||
pcix_misc = pci_read_config32(bus->dev, 0x40);
|
||||
pcix_misc &= ~(0x1f << 16);
|
||||
pci_write_config32(bus->dev, 0x40, pcix_misc);
|
||||
|
||||
return max;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we are in conventional PCI mode nothing more is necessary.
|
||||
*/
|
||||
if (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
|
||||
return max;
|
||||
}
|
||||
|
||||
/* Tune the devices on the bus */
|
||||
amd8132_walk_children(bus, amd8132_pcix_tune_dev, &info);
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static unsigned int amd8132_scan_bridge(device_t dev, unsigned int max)
|
||||
{
|
||||
return do_pci_scan_bridge(dev, max, amd8132_scan_bus);
|
||||
}
|
||||
|
||||
|
||||
static void amd8132_pcix_init(device_t dev)
|
||||
{
|
||||
uint32_t dword;
|
||||
uint8_t byte;
|
||||
unsigned chip_rev;
|
||||
|
||||
/* Find the revision of the 8132 */
|
||||
chip_rev = pci_read_config8(dev, PCI_CLASS_REVISION);
|
||||
|
||||
/* Enable memory write and invalidate ??? */
|
||||
dword = pci_read_config32(dev, 0x04);
|
||||
dword |= 0x10;
|
||||
dword &= ~(1<<6); // PERSP Parity Error Response
|
||||
pci_write_config32(dev, 0x04, dword);
|
||||
|
||||
if (chip_rev == 0x01) {
|
||||
/* Errata #37 */
|
||||
byte = pci_read_config8(dev, 0x0c);
|
||||
if(byte == 0x08 )
|
||||
pci_write_config8(dev, 0x0c, 0x10);
|
||||
|
||||
#if 0
|
||||
/* Errata #59*/
|
||||
dword = pci_read_config32(dev, 0x40);
|
||||
dword &= ~(1<<31);
|
||||
pci_write_config32(dev, 0x40, dword);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Set up error reporting, enable all */
|
||||
/* system error enable */
|
||||
dword = pci_read_config32(dev, 0x04);
|
||||
dword |= (1<<8);
|
||||
pci_write_config32(dev, 0x04, dword);
|
||||
|
||||
/* system and error parity enable */
|
||||
dword = pci_read_config32(dev, 0x3c);
|
||||
dword |= (3<<16);
|
||||
pci_write_config32(dev, 0x3c, dword);
|
||||
|
||||
dword = pci_read_config32(dev, 0x40);
|
||||
// dword &= ~(1<<31); /* WriteChainEnable */
|
||||
dword |= (1<<31);
|
||||
dword |= (1<<7);// must set to 1
|
||||
dword |= (3<<21); //PCIErrorSerrDisable
|
||||
pci_write_config32(dev, 0x40, dword);
|
||||
|
||||
/* EXTARB = 1, COMPAT = 0 */
|
||||
dword = pci_read_config32(dev, 0x48);
|
||||
dword |= (1<<3);
|
||||
dword &= ~(1<<0);
|
||||
dword |= (1<<15); //CLEARPCILOG_L
|
||||
dword |= (1<<19); //PERR FATAL Enable
|
||||
dword |= (1<<22); // SERR FATAL Enable
|
||||
dword |= (1<<23); // LPMARBENABLE
|
||||
dword |= (0x61<<24); //LPMARBCOUNT
|
||||
pci_write_config32(dev, 0x48, dword);
|
||||
|
||||
dword = pci_read_config32(dev, 0x4c);
|
||||
dword |= (1<<6); //intial prefetch for memory read line request
|
||||
dword |= (1<<9); //continuous prefetch Enable for memory read line request
|
||||
pci_write_config32(dev, 0x4c, dword);
|
||||
|
||||
|
||||
/* Disable Single-Bit-Error Correction [30] = 0 */
|
||||
dword = pci_read_config32(dev, 0x70);
|
||||
dword &= ~(1<<30);
|
||||
pci_write_config32(dev, 0x70, dword);
|
||||
|
||||
//link
|
||||
dword = pci_read_config32(dev, 0xd4);
|
||||
dword |= (0x5c<<16);
|
||||
pci_write_config32(dev, 0xd4, dword);
|
||||
|
||||
/* TxSlack0 [16:17] = 0, RxHwLookahdEn0 [18] = 1, TxSlack1 [24:25] = 0, RxHwLookahdEn1 [26] = 1 */
|
||||
dword = pci_read_config32(dev, 0xdc);
|
||||
dword |= (1<<1) | (1<<4); // stream disable 1 to 0 , DBLINSRATE
|
||||
dword |= (1<<18)|(1<<26);
|
||||
dword &= ~((3<<16)|(3<<24));
|
||||
pci_write_config32(dev, 0xdc, dword);
|
||||
|
||||
/* Set up CRC flood enable */
|
||||
dword = pci_read_config32(dev, 0xc0);
|
||||
if(dword) { /* do device A only */
|
||||
#if 0
|
||||
dword = pci_read_config32(dev, 0xc4);
|
||||
dword |= (1<<1);
|
||||
pci_write_config32(dev, 0xc4, dword);
|
||||
dword = pci_read_config32(dev, 0xc8);
|
||||
dword |= (1<<1);
|
||||
pci_write_config32(dev, 0xc8, dword);
|
||||
#endif
|
||||
|
||||
if (chip_rev == 0x11) {
|
||||
/* [18] Clock Gate Enable = 1 */
|
||||
dword = pci_read_config32(dev, 0xf0);
|
||||
dword |= 0x00040008;
|
||||
pci_write_config32(dev, 0xf0, dword);
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#define BRIDGE_40_BIT_SUPPORT 0
|
||||
#if BRIDGE_40_BIT_SUPPORT
|
||||
static void bridge_read_resources(struct device *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
pci_bus_read_resources(dev);
|
||||
res = find_resource(dev, PCI_MEMORY_BASE);
|
||||
if (res) {
|
||||
res->limit = 0xffffffffffULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void bridge_set_resources(struct device *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
res = find_resource(dev, PCI_MEMORY_BASE);
|
||||
if (res) {
|
||||
resource_t base, end;
|
||||
/* set the memory range */
|
||||
dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
|
||||
res->flags |= IORESOURCE_STORED;
|
||||
compute_allocate_resource(&dev->link[0], res,
|
||||
IORESOURCE_MEM | IORESOURCE_PREFETCH,
|
||||
IORESOURCE_MEM);
|
||||
base = res->base;
|
||||
end = resource_end(res);
|
||||
pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
|
||||
pci_write_config8(dev, NPUML, (base >> 32) & 0xff);
|
||||
pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
|
||||
pci_write_config8(dev, NPUMB, (end >> 32) & 0xff);
|
||||
|
||||
report_resource_stored(dev, res, "");
|
||||
}
|
||||
pci_dev_set_resources(dev);
|
||||
}
|
||||
#endif /* BRIDGE_40_BIT_SUPPORT */
|
||||
|
||||
static struct device_operations pcix_ops = {
|
||||
#if BRIDGE_40_BIT_SUPPORT
|
||||
.read_resources = bridge_read_resources,
|
||||
.set_resources = bridge_set_resources,
|
||||
#else
|
||||
.read_resources = pci_bus_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
#endif
|
||||
.enable_resources = pci_bus_enable_resources,
|
||||
.init = amd8132_pcix_init,
|
||||
.scan_bus = amd8132_scan_bridge,
|
||||
.reset_bus = pci_bus_reset,
|
||||
};
|
||||
|
||||
static struct pci_driver pcix_driver __pci_driver = {
|
||||
.ops = &pcix_ops,
|
||||
.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = 0x7458,
|
||||
};
|
||||
|
||||
static void ioapic_enable(device_t dev)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = pci_read_config32(dev, 0x44);
|
||||
if (dev->enabled) {
|
||||
value |= ((1 << 1) | (1 << 0));
|
||||
} else {
|
||||
value &= ~((1 << 1) | (1 << 0));
|
||||
}
|
||||
pci_write_config32(dev, 0x44, value);
|
||||
}
|
||||
static void amd8132_ioapic_init(device_t dev)
|
||||
{
|
||||
uint32_t dword;
|
||||
unsigned chip_rev;
|
||||
|
||||
/* Find the revision of the 8132 */
|
||||
chip_rev = pci_read_config8(dev, PCI_CLASS_REVISION);
|
||||
|
||||
if (chip_rev == 0x01) {
|
||||
#if 0
|
||||
/* Errata #43 */
|
||||
dword = pci_read_config32(dev, 0xc8);
|
||||
dword |= (0x3<<23);
|
||||
pci_write_config32(dev, 0xc8, dword);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( (chip_rev == 0x11) ||(chip_rev == 0x12) ) {
|
||||
//for b1 b2
|
||||
/* Errata #73 */
|
||||
dword = pci_read_config32(dev, 0x80);
|
||||
dword |= (0x1f<<5);
|
||||
pci_write_config32(dev, 0x80, dword);
|
||||
dword = pci_read_config32(dev, 0x88);
|
||||
dword |= (0x1f<<5);
|
||||
pci_write_config32(dev, 0x88, dword);
|
||||
|
||||
/* Errata #74 */
|
||||
dword = pci_read_config32(dev, 0x7c);
|
||||
dword &= ~(0x3<<30);
|
||||
dword |= (0x01<<30);
|
||||
pci_write_config32(dev, 0x7c, dword);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static struct pci_operations pci_ops_pci_dev = {
|
||||
.set_subsystem = pci_dev_set_subsystem,
|
||||
};
|
||||
static struct device_operations ioapic_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = amd8132_ioapic_init,
|
||||
.scan_bus = 0,
|
||||
.enable = ioapic_enable,
|
||||
.ops_pci = &pci_ops_pci_dev,
|
||||
};
|
||||
|
||||
static struct pci_driver ioapic_driver __pci_driver = {
|
||||
.ops = &ioapic_ops,
|
||||
.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = 0x7459,
|
||||
|
||||
};
|
|
@ -0,0 +1,43 @@
|
|||
# abuild config file for EPIA-M
|
||||
|
||||
target via_epia-m
|
||||
mainboard via/epia-m
|
||||
|
||||
option MAXIMUM_CONSOLE_LOGLEVEL=8
|
||||
option DEFAULT_CONSOLE_LOGLEVEL=8
|
||||
option CONFIG_CONSOLE_SERIAL8250=1
|
||||
|
||||
option ROM_SIZE=524288
|
||||
|
||||
|
||||
option HAVE_OPTION_TABLE=1
|
||||
option CONFIG_ROM_STREAM=1
|
||||
option HAVE_FALLBACK_BOOT=1
|
||||
|
||||
###
|
||||
### Compute the location and size of where this firmware image
|
||||
### (linuxBIOS plus bootloader) will live in the boot rom chip.
|
||||
###
|
||||
option FALLBACK_SIZE=131072
|
||||
|
||||
## LinuxBIOS C code runs at this location in RAM
|
||||
option _RAMBASE=0x00004000
|
||||
|
||||
#
|
||||
# Via EPIA M
|
||||
#
|
||||
romimage "normal"
|
||||
option USE_FALLBACK_IMAGE=0
|
||||
option ROM_IMAGE_SIZE=0x10000
|
||||
option LINUXBIOS_EXTRA_VERSION=".0-Normal"
|
||||
payload /dev/null
|
||||
end
|
||||
|
||||
romimage "fallback"
|
||||
option USE_FALLBACK_IMAGE=1
|
||||
option ROM_IMAGE_SIZE=0x10000
|
||||
option LINUXBIOS_EXTRA_VERSION=".0-Fallback"
|
||||
payload /dev/null
|
||||
end
|
||||
|
||||
buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
|
Loading…
Reference in New Issue