diff options
Diffstat (limited to 'src/usr/hwpf/hwp/mc_config/mss_eff_config/opt_memmap.C')
-rw-r--r-- | src/usr/hwpf/hwp/mc_config/mss_eff_config/opt_memmap.C | 823 |
1 files changed, 142 insertions, 681 deletions
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/opt_memmap.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/opt_memmap.C index 4dc08f9fd..4071fb920 100644 --- a/src/usr/hwpf/hwp/mc_config/mss_eff_config/opt_memmap.C +++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/opt_memmap.C @@ -20,15 +20,37 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: opt_memmap.C,v 1.8 2013/05/06 15:15:36 jmcgill Exp $ +// $Id: opt_memmap.C,v 1.14 2013/08/29 21:13:47 jmcgill Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/opt_memmap.C,v $ //------------------------------------------------------------------------------ +// *| +// *! (C) Copyright International Business Machines Corp. 2011 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *| +// *! TITLE : opt_memmap.C +// *! DESCRIPTION : Layout non-mirrored/mirrored address map (FAPI) +// *! +// *! OWNER NAME : Joe McGill Email: jmcgill@us.ibm.com +// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com +// *! BACKUP NAME : Van Lee Email: vanlee@us.ibm.com +// *! +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ // CHANGE HISTORY: //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- +// 1.14 | thi | 08/29/13| Init variable to avoid HB compiler error. +// 1.13 | jmcgill | 08/29/13| Remove use of reverse iter (HB doesn't support) +// 1.12 | jmcgill | 07/10/13| Update to match new attributes, selective +// | | | aligment policy changes +// 1.11 | jmcgill | 06/11/13| Update for alternate BAR support (mirrored) +// 1.10 | jmcgill | 05/24/13| Updates for alternate BAR support +// 1.9 | jmcgill | 05/23/13| Address FW review issues // 1.8 | jmcgill | 04/28/13| Add HTM/OCC memory allocation, fix namespace // 1.7 | jmcgill | 04/20/13| Rewrite to add additional sorting capabilities // | | | desired for exercisor mirroring testing @@ -48,25 +70,24 @@ // after mss_eff_grouping() // // 1) Call opt_memmap() with i_init = true -// - Each proc's ATTR_PROC_MEM_BASE attribute is set to 0 -// - Each proc's ATTR_PROC_MIRROR_BASE attribute is set to 512TB +// - Each proc's ATTR_PROC_MEM_BASE attribute is set to 0 (512TB for flipped +// alignment) +// - Each proc's ATTR_PROC_MIRROR_BASE attribute is set to 512TB (0 for +// flipped alignment, 8TB for selective alignment) // // This provides a basis for mss_eff_grouping() to stack all on-chip // groups. // // 2) mss_eff_grouping() call -// - The HWP updates each proc's ATTR_PROC_MEM_BASES and ATTR_PROC_MEM_SIZES +// - The HWP updates each proc's ATTR_PROC_[MEM|MIRROR]_[BASES|SIZES] // attributes based on the address regions allocated for installed memory // behind each proc -// - ATTR_MSS_MCS_GROUP_32 encapsulates the properties of each group formed. +// - ATTR_PROC_[MEM|MIRROR]_[BASES|SIZES]_ACK are updated to reflect +// the stackable size of each on chip memory region // // 3) Call opt_memmap() with i_init = false -// - Consume mss_eff_grouping() attributes for each proc -// - Align the per-chip non-mirrored and mirrored stacks on each proc to -// a common origin (0) -// - Associate non-mirrored and mirrored partner groups -// - Resize groups & re-stack if producing selective mirrored config -// - Get "effective stackable" size of non-mirrored/mirrored regions +// - Consume mss_eff_grouping() attributes for each proc to determine +// "effective stackable" size of non-mirrored/mirrored regions // on each proc // - Stack procs based on their effective size and desired placement // policy @@ -76,13 +97,15 @@ // -------- ------------- ------------ -------- // NORMAL nm 0TB 512TB // FLIPPED m 512TB 0TB -// SELECTIVE nm+m 0TB 0TB +// SELECTIVE nm+m 0TB 8TB +// +// - Write ATTR_PROC_[MEM|MIRROR]_BASE attributes to their final +// value +// +// 4) mss_eff_grouping() call +// - Second run will produce properly aligned output attributes based +// on final per-chip base address attributes determine in prior step // -// - Rewrite all attributes produced by mss_eff_grouping to reflect -// chip placement -// - Satisfy requests for HTM/OCC memory reservations on each chip -// (HTM requests will alter ATTR_PROC_MEM_SIZES/ATTR_PROC_MIRROR_SIZES, -// as these must reflect the true usable memory allocated for PHYP) //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ @@ -124,40 +147,25 @@ inline uint64_t PowerOf2Roundedup(uint64_t i_number) } -// class to represent group of memory controllers -// shadows attribute data from mss_eff_grouping procedure -class MemGroup +// class to represent memory region +// filled by attribute data from mss_eff_grouping procedure +class MemRegion { public: - // group type (mirrored/non-mirrored) - enum group_type { nm = 0, m = 8 }; + // region type (mirrored/non-mirrored) + enum group_type { nm = 0, m = 1 }; - // group type + // region type group_type iv_group_type; - // group ID, 1st dimension index to MSS_MCS_GROUP_32[] - uint8_t iv_group_id; - // group ID of partner group - uint8_t iv_partner_group_id; - - // group parameters - uint64_t iv_size_per_mcs; - uint8_t iv_group_size; - uint64_t iv_size; - uint64_t iv_base; - uint8_t iv_mcs_member_ids[OPT_MEMMAP_MAX_NM_REGIONS]; - bool iv_use_alt; - uint64_t iv_size_alt; - uint64_t iv_base_alt; - uint64_t iv_biggest_mba; - // memory allocation state - // portion of size which will be exposed to exerciser/PHYP - uint64_t iv_size_exposed; + // region parameters + uint64_t iv_base; + uint64_t iv_size; // comparison operator for sort - bool operator < (MemGroup rhs) const + bool operator < (MemRegion rhs) const { bool l_lt = true; if (iv_base > rhs.iv_base || @@ -168,136 +176,16 @@ public: return l_lt; } - // adjust base address of group (by negative offset) - void decBase(const uint64_t& offset) - { - iv_base -= offset; - if (iv_use_alt) - { - iv_base_alt -= offset; - } - } - - // adjust base address of group (positive offset) - void incBase(const uint64_t& offset) - { - iv_base += offset; - if (iv_use_alt) - { - iv_base_alt += offset; - } - } - - // halve size of group - // assumes no allocations have been made - void halveSize() - { - iv_size /= 2; - iv_size_per_mcs /= 2; - iv_size_exposed /= 2; - - if (iv_use_alt) - { - iv_size_alt /= 2; - } - - iv_biggest_mba /= 2; - } - - // construct from attribute data array - MemGroup(group_type group_type, uint8_t group_id, uint32_t (*group_data)[OPT_MEMMAP_GROUP_32_DIM2]) - { - iv_group_type = group_type; - iv_group_id = group_id; - iv_partner_group_id = 0xFF; - - // consume data from attributes - iv_size_per_mcs = (uint64_t) (group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_MCS_SIZE_INDEX]) * OPT_MEMMAP_GB; - iv_group_size = (uint8_t) (group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_MCS_IN_GROUP_INDEX]); - iv_size = (uint64_t) (group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_SIZE_INDEX]) * OPT_MEMMAP_GB; - iv_base = (uint64_t) (group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_BASE_INDEX]) * OPT_MEMMAP_GB; - for (uint8_t i = OPT_MEMMAP_GROUP_32_MEMBERS_START_INDEX; - i <= OPT_MEMMAP_GROUP_32_MEMBERS_END_INDEX; - i++) - { - if (i < (OPT_MEMMAP_GROUP_32_MEMBERS_START_INDEX + iv_group_size)) - { - iv_mcs_member_ids[i-OPT_MEMMAP_GROUP_32_MEMBERS_START_INDEX] = (uint8_t) (group_data[iv_group_type+iv_group_id][i]); - } - else - { - iv_mcs_member_ids[i-OPT_MEMMAP_GROUP_32_MEMBERS_START_INDEX] = 0xFF; - } - } - - iv_use_alt = group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_ALT_VALID_INDEX]?(true):(false); - iv_size_alt = (uint64_t) (group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_ALT_SIZE_INDEX]) * OPT_MEMMAP_GB; - iv_base_alt = (uint64_t) (group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_ALT_BASE_INDEX]) * OPT_MEMMAP_GB; - iv_biggest_mba = (uint64_t) (group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_LARGEST_MBA_INDEX]) * OPT_MEMMAP_GB; - - // mark all size as exposed - iv_size_exposed = iv_size; - } + // constructor + MemRegion(MemRegion::group_type type, uint64_t base, uint64_t size) : + iv_group_type(type), iv_base(base), iv_size(size) {} // debug function - void dumpGroup() + void dump() { - FAPI_DBG("Group %d [ %s ]", iv_group_id, (iv_group_type == nm)?("nm"):("m")); + FAPI_DBG("Region [ %s ]", (iv_group_type == nm)?("nm"):("m")); FAPI_DBG(" Base: %016llX", iv_base); FAPI_DBG(" Size: %016llX", iv_size); - FAPI_DBG(" MCs: %d [ %016llX ]", iv_group_size, iv_size_per_mcs); - for (uint8_t i = 0; i < iv_group_size; i++) - { - FAPI_DBG(" : %d", iv_mcs_member_ids[i]); - } - FAPI_DBG(" Alt: %s", (iv_use_alt)?("true"):("false")); - FAPI_DBG(" ABase: %016llX", iv_base_alt); - FAPI_DBG(" ASize: %016llX", iv_size_alt); - FAPI_DBG(" Big MBA: %016llX", iv_biggest_mba); - } - - // flush back to attribute data array - void flushAttributes(uint64_t chip_bases[], uint64_t chip_sizes[], uint32_t (*group_data)[OPT_MEMMAP_GROUP_32_DIM2]) - { - // chip size/range attribute arrays expect addresses in B - chip_bases[iv_group_id] = iv_base; - chip_sizes[iv_group_id] = iv_size_exposed; - - // group attribute arrays expect addresses in GB - group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_MCS_SIZE_INDEX] = (uint32_t) ((iv_size_per_mcs) / OPT_MEMMAP_GB); - group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_MCS_IN_GROUP_INDEX] = iv_group_size; - group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_SIZE_INDEX] = (uint32_t) ((iv_size) / OPT_MEMMAP_GB); - group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_BASE_INDEX] = (uint32_t) ((iv_base) / OPT_MEMMAP_GB); - - for (uint8_t i = OPT_MEMMAP_GROUP_32_MEMBERS_START_INDEX; - i <= OPT_MEMMAP_GROUP_32_MEMBERS_END_INDEX; - i++) - { - group_data[iv_group_type+iv_group_id][i] = iv_mcs_member_ids[i-OPT_MEMMAP_GROUP_32_MEMBERS_START_INDEX]; - - } - - group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_ALT_VALID_INDEX] = (iv_use_alt)?(1):(0); - group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_ALT_SIZE_INDEX] = (uint32_t) ((iv_size_alt) / OPT_MEMMAP_GB); - group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_ALT_BASE_INDEX] = (uint32_t) ((iv_base_alt) / OPT_MEMMAP_GB); - group_data[iv_group_type+iv_group_id][OPT_MEMMAP_GROUP_32_LARGEST_MBA_INDEX] = (uint32_t) ((iv_biggest_mba) / OPT_MEMMAP_GB); - } - - // memory allocation function - // returns true if request can be wholly satisfied by this group, - // false otherwise - bool allocate(uint64_t size_req) - { - if (size_req <= iv_size_exposed) - { - iv_size_exposed -= size_req; - return true; - } - else - { - iv_size_exposed = 0; - return false; - } } }; @@ -307,10 +195,6 @@ class ProcChipMemmap { public: - static const uint8_t PROC_CHIP_MEMMAP_NUM_ALLOCATIONS = 2; - static const uint8_t PROC_CHIP_MEMMAP_HTM_ALLOC_INDEX = 0; - static const uint8_t PROC_CHIP_MEMMAP_OCC_ALLOC_INDEX = 1; - // pointer to processor chip target Target *iv_target; // mirroring policy @@ -321,19 +205,15 @@ public: uint8_t iv_node_id; uint8_t iv_chip_id; - // chip non-mirrored base, effective size, and member groups + // chip non-mirrored base, effective size, and member regions uint64_t iv_nm_base; uint64_t iv_nm_eff_size; - std::vector<MemGroup> iv_nm_groups; + std::vector<MemRegion> iv_nm_regions; - // chip mirrored base, effective size, and member groups + // chip mirrored base, effective size, and member regions uint64_t iv_m_base; uint64_t iv_m_eff_size; - std::vector<MemGroup> iv_m_groups; - - // base/size for allocated memory areas - uint64_t iv_alloc_size[PROC_CHIP_MEMMAP_NUM_ALLOCATIONS]; - uint64_t iv_alloc_base[PROC_CHIP_MEMMAP_NUM_ALLOCATIONS]; + std::vector<MemRegion> iv_m_regions; // comparison operator for sort // sort in increasing size, and decreasing proc position @@ -347,8 +227,10 @@ public: // compute effective size based on mirror policy // sort by non-mirrored size - if ((iv_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) && - (rhs.iv_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL)) + if (((iv_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) && + (rhs.iv_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL)) || + ((iv_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE) && + (rhs.iv_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE))) { l_this_eff_size = iv_nm_eff_size; l_rhs_eff_size = rhs.iv_nm_eff_size; @@ -360,14 +242,6 @@ public: l_this_eff_size = iv_m_eff_size; l_rhs_eff_size = rhs.iv_m_eff_size; } - // sort by sum of non-mirrored/mirrored sizes - else if ((iv_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE) && - (rhs.iv_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE)) - { - l_this_eff_size = PowerOf2Roundedup(iv_nm_eff_size + iv_m_eff_size); - l_rhs_eff_size = PowerOf2Roundedup(rhs.iv_nm_eff_size + rhs.iv_m_eff_size); - } - // perform sort comparison if (l_this_eff_size > l_rhs_eff_size || (l_this_eff_size == l_rhs_eff_size && iv_pos < rhs.iv_pos)) @@ -389,7 +263,6 @@ public: uint64_t l_nm_sizes[OPT_MEMMAP_MAX_NM_REGIONS]; uint64_t l_m_bases[OPT_MEMMAP_MAX_M_REGIONS]; uint64_t l_m_sizes[OPT_MEMMAP_MAX_M_REGIONS]; - uint32_t l_mss_mcs_group_32[OPT_MEMMAP_GROUP_32_DIM1][OPT_MEMMAP_GROUP_32_DIM2]; do { @@ -413,7 +286,7 @@ public: } iv_pos = ((4*iv_node_id)+iv_chip_id); - // retrieve base address for each chip, align to common origin + // retrieve base address for each chip rc = FAPI_ATTR_GET(ATTR_PROC_MEM_BASE, iv_target, iv_nm_base); @@ -422,14 +295,6 @@ public: FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MEM_BASE)"); break; } - if (iv_nm_base != OPT_MEMMAP_BASE_ORIGIN) - { - const uint64_t& ADDR = iv_nm_base; - FAPI_ERR("Unexpected value returned for ATTR_PROC_MEM_BASE (=%016llX)", - iv_nm_base); - FAPI_SET_HWP_ERROR(rc, RC_OPT_MEMMAP_MEM_BASE_ERR); - break; - } rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASE, iv_target, @@ -439,63 +304,44 @@ public: FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MIRROR_BASE)"); break; } - if (iv_m_base != OPT_MEMMAP_OFFSET_ORIGIN) - { - const uint64_t& ADDR = iv_m_base; - FAPI_ERR("Unexpected value returned for ATTR_PROC_MIRROR_BASE (=%016llX)", - iv_m_base); - FAPI_SET_HWP_ERROR(rc, RC_OPT_MEMMAP_MIRROR_BASE_ERR); - break; - } - iv_m_base -= OPT_MEMMAP_OFFSET_ORIGIN; // retrieve regions (bases and sizes) computed by mss_eff_grouping - rc = FAPI_ATTR_GET(ATTR_PROC_MEM_BASES, + rc = FAPI_ATTR_GET(ATTR_PROC_MEM_BASES_ACK, iv_target, l_nm_bases); if (!rc.ok()) { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MEM_BASES)"); + FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MEM_BASES_ACK)"); break; } - rc = FAPI_ATTR_GET(ATTR_PROC_MEM_SIZES, + rc = FAPI_ATTR_GET(ATTR_PROC_MEM_SIZES_ACK, iv_target, l_nm_sizes); if (!rc.ok()) { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MEM_SIZES)"); + FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MEM_SIZES_ACK)"); break; } - rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASES, + rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASES_ACK, iv_target, l_m_bases); if (!rc.ok()) { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MIRROR_BASES)"); + FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MIRROR_BASES_ACK)"); break; } - rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_SIZES, + rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_SIZES_ACK, iv_target, l_m_sizes); if (!rc.ok()) { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MIRROR_SIZES)"); - break; - } - - // retrieve data structure describing groups formed by mss_eff_grouping - rc = FAPI_ATTR_GET(ATTR_MSS_MCS_GROUP_32, - iv_target, - l_mss_mcs_group_32); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_MSS_MCS_GROUP_32)"); + FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_MIRROR_SIZES_ACK)"); break; } - // populate non-mirrored groups + // populate non-mirrored regions FAPI_INF("Chip n%d:p%d", iv_node_id, iv_chip_id); for (uint8_t i = 0; i < OPT_MEMMAP_MAX_NM_REGIONS; i++) { @@ -503,176 +349,45 @@ public: { FAPI_INF(" l_nm_bases[%d] = %016llX", i, l_nm_bases[i]); FAPI_INF(" l_nm_sizes[%d] = %016llX", i, l_nm_sizes[i]); - MemGroup g(MemGroup::nm, i, l_mss_mcs_group_32); - if ((l_nm_bases[i] != g.iv_base) || - (l_nm_sizes[i] != g.iv_size)) - { - const uint8_t& GROUP = i; - const uint64_t& MEM_BASES = l_nm_bases[i]; - const uint64_t& MEM_SIZES = l_nm_sizes[i]; - const uint64_t& GROUP_BASE = g.iv_base; - const uint64_t& GROUP_SIZE = g.iv_size; - FAPI_ERR("Inconsistent non-mirrored group content"); - FAPI_SET_HWP_ERROR(rc, - RC_OPT_MEMMAP_NON_MIRROR_GROUP_ERR); - break; - } - iv_nm_groups.push_back(g); + MemRegion r(MemRegion::nm, l_nm_bases[i], l_nm_sizes[i]); + iv_nm_regions.push_back(r); } } - if (!rc.ok()) - { - break; - } - // populate mirrored groups + // populate mirrored regions for (uint8_t i = 0; i < OPT_MEMMAP_MAX_M_REGIONS; i++) { if (l_m_sizes[i] != 0) { // align to common origin - l_m_bases[i] -= OPT_MEMMAP_OFFSET_ORIGIN; FAPI_INF(" l_m_bases[%d] = %016llX", i, l_m_bases[i]); FAPI_INF(" l_m_sizes[%d] = %016llX", i, l_m_sizes[i]); - MemGroup g(MemGroup::m, i, l_mss_mcs_group_32); - // align to common origin - g.decBase(OPT_MEMMAP_OFFSET_ORIGIN); - if ((l_m_bases[i] != g.iv_base) || - (l_m_sizes[i] != g.iv_size)) - { - const uint8_t& GROUP = i; - const uint64_t& MIRROR_BASES = l_m_bases[i]; - const uint64_t& MIRROR_SIZES = l_m_sizes[i]; - const uint64_t& GROUP_BASE = g.iv_base; - const uint64_t& GROUP_SIZE = g.iv_size; - FAPI_ERR("Inconsistent mirrored group content"); - FAPI_SET_HWP_ERROR(rc, - RC_OPT_MEMMAP_MIRROR_GROUP_ERR); - break; - } - iv_m_groups.push_back(g); - } - } - if (!rc.ok()) - { - break; - } - - // dump configuration for non-mirrored groups - for (uint8_t i = 0; i < iv_nm_groups.size(); i++) - { - iv_nm_groups[i].dumpGroup(); - } - // link mirrored group with their non-mirrored partner - for (uint8_t i = 0; i < iv_m_groups.size(); i++) - { - // loop through all non-mirrored groups - // until a match is found - bool match = false; - for (uint8_t j = 0; (j < iv_nm_groups.size()) && (!match); j++) - { - // sizes match? - match = ((iv_m_groups[i].iv_group_id == - iv_nm_groups[j].iv_group_id) && - (iv_m_groups[i].iv_size == - (iv_nm_groups[j].iv_size / 2))); - if (match) - { - // set MCS unit parameters for mirrored group - for (uint8_t k = 0; k < OPT_MEMMAP_MAX_NM_REGIONS; k++) - { - iv_m_groups[i].iv_mcs_member_ids[k] = - iv_nm_groups[j].iv_mcs_member_ids[k]; - } - iv_m_groups[i].iv_group_size = - iv_nm_groups[j].iv_group_size; - iv_m_groups[i].iv_size_per_mcs = - iv_m_groups[i].iv_size / - iv_m_groups[i].iv_group_size; - - // link groups - iv_m_groups[i].iv_partner_group_id = iv_nm_groups[j].iv_group_id; - iv_nm_groups[j].iv_partner_group_id = iv_m_groups[i].iv_group_id; - } - } - // valid mirrored group, but couldn't find non-mirrored partner - if (!match) - { - const uint8_t& GROUP = i; - FAPI_ERR("Unable to find non-mirrored group partner for mirrored group!"); - FAPI_SET_HWP_ERROR(rc, RC_OPT_MEMMAP_GROUP_PARTNER_ERR); - break; - } - // dump configuration for mirrored group - iv_m_groups[i].dumpGroup(); - } - if (!rc.ok()) - { - break; - } - - // compress/re-stack groups for the selective mirror configuration - if (iv_mirror_policy == - ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE) - { - for (uint8_t i = 0; i < iv_nm_groups.size(); i++) - { - // only multi-member groups (with a mirrrored partner) will - // change in size - if ((iv_nm_groups[i].iv_group_size != 1) && - (iv_nm_groups[i].iv_partner_group_id != 0xFF)) - { - iv_nm_groups[i].halveSize(); - for (uint8_t j = 0; j < iv_m_groups.size(); j++) - { - if (iv_nm_groups[i].iv_partner_group_id == - iv_m_groups[j].iv_group_id) - { - iv_m_groups[j].halveSize(); - } - } - } - } - - // realign each group to origin - for (uint8_t i = 0; i < iv_nm_groups.size(); i++) - { - iv_nm_groups[i].decBase(iv_nm_groups[i].iv_base); - } - for (uint8_t i = 0; i < iv_m_groups.size(); i++) - { - iv_m_groups[i].decBase(iv_m_groups[i].iv_base); - } - - // re-stack set of groups, largest->smallest - uint64_t l_nm_group_base = OPT_MEMMAP_BASE_ORIGIN; - std::sort(iv_nm_groups.begin(), iv_nm_groups.end()); - for (uint8_t i = iv_nm_groups.size(); i != 0; --i) - { - iv_nm_groups[i-1].incBase(l_nm_group_base); - l_nm_group_base += iv_nm_groups[i-1].iv_size; - } - - uint64_t l_m_group_base = OPT_MEMMAP_BASE_ORIGIN; - std::sort(iv_m_groups.begin(), iv_m_groups.end()); - for (uint8_t i = iv_m_groups.size(); i != 0; --i) - { - iv_m_groups[i-1].incBase(l_m_group_base); - l_m_group_base += iv_m_groups[i-1].iv_size; + MemRegion r(MemRegion::m, l_m_bases[i], l_m_sizes[i]); + iv_m_regions.push_back(r); } } // sort regions for effective size calculations - std::sort(iv_nm_groups.begin(), iv_nm_groups.end()); - std::sort(iv_m_groups.begin(), iv_m_groups.end()); + std::sort(iv_nm_regions.begin(), iv_nm_regions.end()); + std::sort(iv_m_regions.begin(), iv_m_regions.end()); // compute effective size of chip address space // this is simply the end address of the last region in // each stack (rounded up to a power of 2) - if (iv_nm_groups.size() != 0) + if (iv_nm_regions.size() != 0) { - iv_nm_eff_size = iv_nm_groups[iv_nm_groups.size()-1].iv_base; - iv_nm_eff_size += iv_nm_groups[iv_nm_groups.size()-1].iv_size; + if (iv_nm_base != iv_nm_regions[0].iv_base) + { + const uint64_t& ADDR = iv_nm_base; + FAPI_ERR("Unexpected value returned for ATTR_PROC_MEM_BASE (=%016llX)", + iv_nm_base); + FAPI_SET_HWP_ERROR(rc, RC_OPT_MEMMAP_MEM_BASE_ERR); + break; + } + + iv_nm_eff_size = iv_nm_regions[iv_nm_regions.size()-1].iv_base - + iv_nm_regions[0].iv_base; + iv_nm_eff_size += iv_nm_regions[iv_nm_regions.size()-1].iv_size; iv_nm_eff_size = PowerOf2Roundedup(iv_nm_eff_size); } else @@ -681,10 +396,20 @@ public: } FAPI_INF(" nm_eff_size = %016llX", iv_nm_eff_size); - if (iv_m_groups.size() != 0) + if (iv_m_regions.size() != 0) { - iv_m_eff_size = iv_m_groups[iv_m_groups.size()-1].iv_base; - iv_m_eff_size += iv_m_groups[iv_m_groups.size()-1].iv_size; + if (iv_m_base != iv_m_regions[0].iv_base) + { + const uint64_t& ADDR = iv_m_base; + FAPI_ERR("Unexpected value returned for ATTR_PROC_MIRROR_BASE (=%016llX)", + iv_m_base); + FAPI_SET_HWP_ERROR(rc, RC_OPT_MEMMAP_MIRROR_BASE_ERR); + break; + } + + iv_m_eff_size = iv_m_regions[iv_m_regions.size()-1].iv_base - + iv_m_regions[0].iv_base; + iv_m_eff_size += iv_m_regions[iv_m_regions.size()-1].iv_size; iv_m_eff_size = PowerOf2Roundedup(iv_m_eff_size); } else @@ -693,239 +418,30 @@ public: } FAPI_INF(" m_eff_size = %016llX", iv_m_eff_size); - // retrieve request for HTM/OCC address space - rc = FAPI_ATTR_GET(ATTR_PROC_HTM_BAR_SIZE, - iv_target, - iv_alloc_size[PROC_CHIP_MEMMAP_HTM_ALLOC_INDEX]); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_HTM_BAR_SIZE)"); - break; - } - - rc = FAPI_ATTR_GET(ATTR_PROC_OCC_SANDBOX_SIZE, - iv_target, - iv_alloc_size[PROC_CHIP_MEMMAP_OCC_ALLOC_INDEX]); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_GET (ATTR_PROC_OCC_SANDBOX_SIZE)"); - break; - } } while(0); return rc; } // establish new non-mirrored base address for this chip - // and adjust all groups to track void setNMBase(const uint64_t& base) { iv_nm_base = base; - for (uint8_t i = 0; i < iv_nm_groups.size(); ++i) - { - iv_nm_groups[i].incBase(base); - } } // establish new mirrored base address for this chip - // and adjust all groups to track void setMBase(const uint64_t& base) { iv_m_base = base; - for (uint8_t i = 0; i < iv_m_groups.size(); ++i) - { - iv_m_groups[i].incBase(base); - } } - // allocate HTM/OCC memory requests for this chip - ReturnCode allocate() - { - ReturnCode rc; - - // groups have already been sorted for stacking - // build ordered list of groups to consider in service of - // allocation requests, based on mirroring mode - std::vector<MemGroup*> alloc_groups; - - do - { - if (iv_mirror_policy == - ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE) - { - // mirrored groups occupy highest address space, - // then non-mirrored, all are independent - alloc_groups.resize(iv_m_groups.size()+ - iv_nm_groups.size()); - for (uint8_t i = 0; i < iv_m_groups.size(); i++) - { - alloc_groups[iv_m_groups.size()-1-i] = &(iv_m_groups[i]); - } - for (uint8_t i = 0; i < iv_nm_groups.size(); i++) - { - alloc_groups[iv_m_groups.size()+iv_nm_groups.size()-1-i] = &(iv_nm_groups[i]); - } - } - else if (iv_mirror_policy == - ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_FLIPPED) - { - // perform allocation in mirrored space, - // adjust non-mirrored partner group - alloc_groups.resize(iv_m_groups.size()); - for (uint8_t i = 0; i < iv_m_groups.size(); i++) - { - alloc_groups[iv_m_groups.size()-1-i] = &(iv_m_groups[i]); - } - } - else - { - // perform allocation in non-mirrored space, - // adjust mirrored partner group - alloc_groups.resize(iv_nm_groups.size()); - for (uint8_t i = 0; i < iv_nm_groups.size(); i++) - { - alloc_groups[iv_nm_groups.size()-1-i] = &(iv_nm_groups[i]); - } - } - - // perform allocations - for (uint8_t r = 0; - (r < PROC_CHIP_MEMMAP_NUM_ALLOCATIONS) && rc.ok(); - r++) - { - uint64_t alloc_size_req = iv_alloc_size[r]; - iv_alloc_base[r] = 0; - - if (alloc_size_req != 0) - { - bool alloc_done = false; - for (uint8_t i = 0; - (i < alloc_groups.size()) && !alloc_done; - i++) - { - FAPI_DBG("Searching group %d for allocation %d (remaining size: %016llX)", - i, r, alloc_size_req); - // allocate from primary group - alloc_done = alloc_groups[i]->allocate(alloc_size_req); - // take allocation from partner group as well - if (iv_mirror_policy == - ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_FLIPPED) - { - FAPI_DBG("Registering allocation with partner non-mirrored group"); - for (uint8_t j = 0; j < iv_nm_groups.size(); j++) - { - if (alloc_groups[i]->iv_partner_group_id == - iv_nm_groups[j].iv_group_id) - { - (void) iv_nm_groups[j].allocate( - alloc_size_req * 2); - } - } - } - else if (iv_mirror_policy == - ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) - { - if (alloc_groups[i]->iv_partner_group_id != 0xFF) - { - FAPI_DBG("Registering allocation with partner mirrored group"); - for (uint8_t j = 0; j < iv_m_groups.size(); j++) - { - if (alloc_groups[i]->iv_partner_group_id == - iv_m_groups[j].iv_group_id) - { - (void) iv_m_groups[j].allocate( - alloc_size_req / 2); - } - } - } - } - // if allocation is not completely satisfied, compute - // size request for next iteration - if (!alloc_done) - { - alloc_size_req -= alloc_groups[i]->iv_size_exposed; - } - else - { - iv_alloc_base[r] = alloc_groups[i]->iv_base + - alloc_groups[i]->iv_size_exposed; - } - } - if (!alloc_done) - { - const uint8_t& ALLOC_INDEX = r; - FAPI_ERR("Unable to satisfy %s memory request, size requested exceeds available memory!", - (r == 0)?("HTM"):("OCC")); - FAPI_SET_HWP_ERROR(rc, RC_OPT_MEMMAP_ALLOC_ERR); - break; - } - } - } - } while(0); - - return rc; - } - - // flush group state back to attributes + // flush state back to attributes ReturnCode flushAttributes() { ReturnCode rc; - uint64_t l_mem_bases[OPT_MEMMAP_MAX_NM_REGIONS]; - uint64_t l_mem_sizes[OPT_MEMMAP_MAX_NM_REGIONS]; - uint64_t l_mirror_bases[OPT_MEMMAP_MAX_M_REGIONS]; - uint64_t l_mirror_sizes[OPT_MEMMAP_MAX_M_REGIONS]; - uint32_t l_mss_mcs_group_32[OPT_MEMMAP_GROUP_32_DIM1][OPT_MEMMAP_GROUP_32_DIM2]; do { - // init attribute arrays - for (uint8_t i = 0; i < OPT_MEMMAP_MAX_NM_REGIONS; i++) - { - l_mem_bases[i] = 0; - l_mem_sizes[i] = 0; - } - for (uint8_t i = 0; i < OPT_MEMMAP_MAX_M_REGIONS ; i++) - { - l_mirror_bases[i] = 0; - l_mirror_sizes[i] = 0; - } - for (uint8_t i = 0; i < OPT_MEMMAP_GROUP_32_DIM1; i++) - { - - for (uint8_t j = OPT_MEMMAP_GROUP_32_MCS_SIZE_INDEX; - j <= OPT_MEMMAP_GROUP_32_BASE_INDEX; - j++) - { - l_mss_mcs_group_32[i][j] = 0; - } - for (uint8_t j = OPT_MEMMAP_GROUP_32_MEMBERS_START_INDEX; - j <= OPT_MEMMAP_GROUP_32_MEMBERS_END_INDEX; - j++) - { - l_mss_mcs_group_32[i][j] = 0xFF; - } - for (uint8_t j = OPT_MEMMAP_GROUP_32_ALT_VALID_INDEX; - j <= OPT_MEMMAP_GROUP_32_LARGEST_MBA_INDEX; - j++) - { - l_mss_mcs_group_32[i][j] = 0; - } - } - - // flush attribute data for each group - for (uint8_t i = 0; i < iv_nm_groups.size(); i++) - { - iv_nm_groups[i].flushAttributes(l_mem_bases, - l_mem_sizes, - l_mss_mcs_group_32); - } - for (uint8_t i = 0; i < iv_m_groups.size(); i++) - { - iv_m_groups[i].flushAttributes(l_mirror_bases, - l_mirror_sizes, - l_mss_mcs_group_32); - } - // set base addresses rc = FAPI_ATTR_SET(ATTR_PROC_MEM_BASE, iv_target, @@ -945,74 +461,7 @@ public: break; } - // set non-mirrored region attributes - rc = FAPI_ATTR_SET(ATTR_PROC_MEM_BASES, - iv_target, - l_mem_bases); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_PROC_MEM_BASES)"); - break; - } - - rc = FAPI_ATTR_SET(ATTR_PROC_MEM_SIZES, - iv_target, - l_mem_sizes); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_PROC_MEM_BASES)"); - break; - } - - // set mirrored region attributes - rc = FAPI_ATTR_SET(ATTR_PROC_MIRROR_BASES, - iv_target, - l_mirror_bases); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_PROC_MIRROR_BASES)"); - break; - } - - rc = FAPI_ATTR_SET(ATTR_PROC_MIRROR_SIZES, - iv_target, - l_mirror_sizes); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_PROC_MIRROR_BASES)"); - break; - } - - // set group definition attributes - rc = FAPI_ATTR_SET(ATTR_MSS_MCS_GROUP_32, - iv_target, - l_mss_mcs_group_32); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_MSS_MCS_GROUP_32)"); - break; - } - - // set HTM/OCC allocation attributes - rc = FAPI_ATTR_SET(ATTR_PROC_HTM_BAR_BASE_ADDR, - iv_target, - iv_alloc_base[PROC_CHIP_MEMMAP_HTM_ALLOC_INDEX]); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_PROC_HTM_BAR_BASE_ADDR)"); - break; - } - - rc = FAPI_ATTR_SET(ATTR_PROC_OCC_SANDBOX_BASE_ADDR, - iv_target, - iv_alloc_base[PROC_CHIP_MEMMAP_OCC_ALLOC_INDEX]); - if (!rc.ok()) - { - FAPI_ERR("Error from FAPI_ATTR_SET (ATTR_PROC_OCC_SANDBOX_BASE_ADDR)"); - break; - } } while(0); - return rc; } }; @@ -1049,7 +498,28 @@ ReturnCode opt_memmap(std::vector<fapi::Target> & i_procs, bool i_init) l_iter != i_procs.end(); ++l_iter) { - uint64_t mem_base = OPT_MEMMAP_BASE_ORIGIN; + uint64_t mem_base; + uint64_t mirror_base; + + if (l_mirror_policy == + ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) + { + mem_base = OPT_MEMMAP_BASE_ORIGIN; + mirror_base = OPT_MEMMAP_OFFSET_ORIGIN; + } + else if (l_mirror_policy == + ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_FLIPPED) + { + mem_base = OPT_MEMMAP_OFFSET_ORIGIN; + mirror_base = OPT_MEMMAP_BASE_ORIGIN; + } + else if (l_mirror_policy == + ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE) + { + mem_base = OPT_MEMMAP_BASE_ORIGIN; + mirror_base = OPT_MEMMAP_SELECTIVE_ORIGIN; + } + rc = FAPI_ATTR_SET(ATTR_PROC_MEM_BASE, &(*l_iter), mem_base); @@ -1059,7 +529,6 @@ ReturnCode opt_memmap(std::vector<fapi::Target> & i_procs, bool i_init) break; } - uint64_t mirror_base = OPT_MEMMAP_OFFSET_ORIGIN; rc = FAPI_ATTR_SET(ATTR_PROC_MIRROR_BASE, &(*l_iter), mirror_base); @@ -1075,7 +544,7 @@ ReturnCode opt_memmap(std::vector<fapi::Target> & i_procs, bool i_init) } } // second pass of execution - // reorder chips based on their effective size + // reorder chips based on their effective stackable size else { // loop across all chips in system, consume results of @@ -1102,8 +571,8 @@ ReturnCode opt_memmap(std::vector<fapi::Target> & i_procs, bool i_init) std::sort(l_system_memmap.begin(), l_system_memmap.end()); // establish base for alignment of mirrored/non-mirrored regions - uint64_t l_m_base_curr; - uint64_t l_nm_base_curr; + uint64_t l_m_base_curr = 0; + uint64_t l_nm_base_curr = 0; if (l_mirror_policy == ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) { @@ -1118,17 +587,18 @@ ReturnCode opt_memmap(std::vector<fapi::Target> & i_procs, bool i_init) l_nm_base_curr = OPT_MEMMAP_OFFSET_ORIGIN; l_m_base_curr = OPT_MEMMAP_BASE_ORIGIN; } - else + else if (l_mirror_policy == + ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE) { - // start at zero, mirrored region will stack on top - // of non-mirrored address space, handle offset in loop l_nm_base_curr = OPT_MEMMAP_BASE_ORIGIN; - l_m_base_curr = OPT_MEMMAP_BASE_ORIGIN; + l_m_base_curr = OPT_MEMMAP_SELECTIVE_ORIGIN; } // walk through chips, from largest->smallest effective size & // assign base addresses for each group - for (uint8_t i = l_system_memmap.size(); i != 0; --i) + for (uint8_t i = l_system_memmap.size(); + i != 0; + --i) { FAPI_DBG("Stacking chip n%d:p%d (eff nm size = %lld GB, eff m size = %lld GB)...", l_system_memmap[i-1].iv_node_id, @@ -1160,20 +630,11 @@ ReturnCode opt_memmap(std::vector<fapi::Target> & i_procs, bool i_init) l_nm_base_curr += l_system_memmap[i-1].iv_nm_eff_size; l_m_base_curr += l_system_memmap[i-1].iv_m_eff_size; } - else - { - l_nm_base_curr += PowerOf2Roundedup( - l_system_memmap[i-1].iv_nm_eff_size + - l_system_memmap[i-1].iv_m_eff_size); - l_m_base_curr = l_nm_base_curr; - } - - // allocate HTM/OCC memory requests for this chip - rc = l_system_memmap[i-1].allocate(); - if (!rc.ok()) + else if (l_mirror_policy == + ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_SELECTIVE) { - FAPI_ERR("Error from allocate"); - break; + l_nm_base_curr += l_system_memmap[i-1].iv_nm_eff_size; + l_m_base_curr += l_system_memmap[i-1].iv_nm_eff_size / 2; } // flush attributes for this chip |