diff options
author | Timothy Pearson <tpearson@raptorengineeringinc.com> | 2015-10-16 13:51:51 -0500 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2015-11-02 23:45:19 +0100 |
commit | 730a043fb6cb4dd3cb5af8f8640365727b598648 (patch) | |
tree | 59afe45caca1a8e1682939c7e44e95344104533e /src/cpu/amd/quadcore/quadcore_id.c | |
parent | d150006c4a4584bc9933c2d8ff580a54c4f0cc2a (diff) |
cpu/amd: Add initial AMD Family 15h support
TEST: Booted ASUS KGPE-D16 with single Opteron 6380
* Unbuffered DDR3 DIMMs tested and working
* Suspend to RAM (S3) tested and working
Change-Id: Idffd2ce36ce183fbfa087e5ba69a9148f084b45e
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: http://review.coreboot.org/11966
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/cpu/amd/quadcore/quadcore_id.c')
-rw-r--r-- | src/cpu/amd/quadcore/quadcore_id.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/src/cpu/amd/quadcore/quadcore_id.c b/src/cpu/amd/quadcore/quadcore_id.c index cd62a60a5b..acfdb4967a 100644 --- a/src/cpu/amd/quadcore/quadcore_id.c +++ b/src/cpu/amd/quadcore/quadcore_id.c @@ -39,9 +39,12 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54) { struct node_core_id id; uint8_t apicid; + uint8_t fam15h = 0; uint8_t rev_gte_d = 0; uint8_t dual_node = 0; uint32_t f3xe8; + uint32_t family; + uint32_t model; #ifdef __PRE_RAM__ f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8); @@ -49,7 +52,17 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54) f3xe8 = pci_read_config32(get_node_pci(0, 3), 0xe8); #endif - if (cpuid_eax(0x80000001) >= 0x8) + family = model = cpuid_eax(0x80000001); + model = ((model & 0xf0000) >> 12) | ((model & 0xf0) >> 4); + family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8); + + if (family >= 0x6f) { + /* Family 15h or later */ + fam15h = 1; + nb_cfg_54 = 1; + } + + if ((model >= 0x8) || fam15h) /* Revision D or later */ rev_gte_d = 1; @@ -63,7 +76,13 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54) */ apicid = (cpuid_ebx(1) >> 24) & 0xff; if( nb_cfg_54) { - if (rev_gte_d && dual_node) { + if (fam15h && dual_node) { + id.coreid = apicid & 0x1f; + id.nodeid = (apicid & 0x60) >> 5; + } else if (fam15h && !dual_node) { + id.coreid = apicid & 0xf; + id.nodeid = (apicid & 0x70) >> 4; + } else if (rev_gte_d && dual_node) { id.coreid = apicid & 0xf; id.nodeid = (apicid & 0x30) >> 4; } else if (rev_gte_d && !dual_node) { @@ -86,7 +105,25 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54) } } - if (rev_gte_d && dual_node) { + if (fam15h && dual_node) { + /* Coreboot expects each separate processor die to be on a different nodeid. + * Since the code above returns nodeid 0 even on internal node 1 some fixup is needed... + */ + uint32_t f5x84; + uint8_t core_count; + +#ifdef __PRE_RAM__ + f5x84 = pci_read_config32(NODE_PCI(0, 5), 0x84); +#else + f5x84 = pci_read_config32(get_node_pci(0, 5), 0x84); +#endif + core_count = (f5x84 & 0xff) + 1; + id.nodeid = id.nodeid * 2; + if (id.coreid >= core_count) { + id.nodeid += 1; + id.coreid = id.coreid - core_count; + } + } else if (rev_gte_d && dual_node) { /* Coreboot expects each separate processor die to be on a different nodeid. * Since the code above returns nodeid 0 even on internal node 1 some fixup is needed... */ |