diff options
author | Timothy Pearson <tpearson@raptorengineeringinc.com> | 2015-09-05 17:50:29 -0500 |
---|---|---|
committer | Jonathan A. Kollasch <jakllsch@kollasch.net> | 2015-10-24 21:33:07 +0200 |
commit | 1c4508e77c32e2db7ecba49fe92159242d831f56 (patch) | |
tree | d2b88b87c525a24b02455850245858202016df11 /src/cpu/amd/quadcore | |
parent | 1fec04b47e3ebcde3a1b34b81120e3b83c88f323 (diff) |
cpu/amd: Add initial support for AMD Socket G34 processors
Change-Id: Iccd034f32c26513edd52ca3a11a30f61c362682d
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: http://review.coreboot.org/11940
Reviewed-by: Edward O'Callaghan <edward.ocallaghan@koparo.com>
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
Diffstat (limited to 'src/cpu/amd/quadcore')
-rw-r--r-- | src/cpu/amd/quadcore/quadcore_id.c | 77 |
1 files changed, 58 insertions, 19 deletions
diff --git a/src/cpu/amd/quadcore/quadcore_id.c b/src/cpu/amd/quadcore/quadcore_id.c index cf45196cf1..c5921dee7f 100644 --- a/src/cpu/amd/quadcore/quadcore_id.c +++ b/src/cpu/amd/quadcore/quadcore_id.c @@ -1,6 +1,7 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering * Copyright (C) 2007 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify @@ -37,33 +38,71 @@ u32 get_initial_apicid(void) return ((cpuid_ebx(1) >> 24) & 0xff); } -//called by amd_siblings too -#define CORE_ID_BIT 2 -#define NODE_ID_BIT 6 +/* Called by amd_siblings (ramstage) as well */ struct node_core_id get_node_core_id(u32 nb_cfg_54) { struct node_core_id id; - u32 core_id_bits; + uint8_t apicid; + uint8_t rev_gte_d = 0; + uint8_t dual_node = 0; + uint32_t f3xe8; - u32 ApicIdCoreIdSize = (cpuid_ecx(0x80000008)>>12 & 0xf); - if(ApicIdCoreIdSize) { - core_id_bits = ApicIdCoreIdSize; - } else { - core_id_bits = CORE_ID_BIT; //quad core - } +#ifdef __PRE_RAM__ + f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8); +#else + f3xe8 = pci_read_config32(get_node_pci(0, 3), 0xe8); +#endif + + if (cpuid_eax(0x80000001) >= 0x8) + /* Revision D or later */ + rev_gte_d = 1; - // get the apicid via cpuid(1) ebx[31:24] + if (rev_gte_d) + /* Check for dual node capability */ + if (f3xe8 & 0x20000000) + dual_node = 1; + + /* Get the apicid via cpuid(1) ebx[31:24] + * The apicid format varies based on processor revision + */ + apicid = (cpuid_ebx(1) >> 24) & 0xff; if( nb_cfg_54) { - // when NB_CFG[54] is set, nodeid = ebx[31:26], coreid = ebx[25:24] - id.coreid = (cpuid_ebx(1) >> 24) & 0xff; - id.nodeid = (id.coreid>>core_id_bits); - id.coreid &= ((1<<core_id_bits)-1); + if (rev_gte_d && dual_node) { + id.coreid = apicid & 0xf; + id.nodeid = (apicid & 0x30) >> 4; + } else if (rev_gte_d && !dual_node) { + id.coreid = apicid & 0x7; + id.nodeid = (apicid & 0x38) >> 3; + } else { + id.coreid = apicid & 0x3; + id.nodeid = (apicid & 0x1c) >> 2; + } } else { - // when NB_CFG[54] is clear, nodeid = ebx[29:24], coreid = ebx[31:30] - id.nodeid = (cpuid_ebx(1) >> 24) & 0xff; - id.coreid = (id.nodeid>>NODE_ID_BIT); - id.nodeid &= ((1<<NODE_ID_BIT)-1); + if (rev_gte_d && dual_node) { + id.coreid = (apicid & 0xf0) >> 4; + id.nodeid = apicid & 0x3; + } else if (rev_gte_d && !dual_node) { + id.coreid = (apicid & 0xe0) >> 5; + id.nodeid = apicid & 0x7; + } else { + id.coreid = (apicid & 0x60) >> 5; + id.nodeid = apicid & 0x7; + } } + + 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... + */ + uint8_t core_count = (((f3xe8 & 0x00008000) >> 13) | ((f3xe8 & 0x00003000) >> 12)) + 1; + + id.nodeid = id.nodeid * 2; + if (id.coreid >= core_count) { + id.nodeid += 1; + id.coreid = id.coreid - core_count; + } + } + return id; } |