|
40 | 40 | #include <vpd/mvpdenums.H>
|
41 | 41 | #include <stdio.h>
|
42 | 42 | #include <sys/mm.h>
|
| 43 | +#include <sys/misc.h> |
43 | 44 |
|
44 | 45 | #include <pnor/pnorif.H>
|
45 | 46 |
|
@@ -75,6 +76,7 @@ RegisterHWASFunctions registerHWASFunctions;
|
75 | 76 |
|
76 | 77 | using namespace TARGETING;
|
77 | 78 |
|
| 79 | + |
78 | 80 | //******************************************************************************
|
79 | 81 | // platReadIDEC function
|
80 | 82 | //******************************************************************************
|
@@ -696,28 +698,194 @@ void markTargetChanged(TARGETING::TargetHandle_t i_target)
|
696 | 698 | // platCheckMinimumHardware()
|
697 | 699 | //******************************************************************************
|
698 | 700 | void platCheckMinimumHardware(uint32_t & io_plid,
|
699 |
| - const TARGETING::ConstTargetHandle_t i_node, |
700 |
| - bool *o_bootable) |
| 701 | + const TARGETING::ConstTargetHandle_t i_node, |
| 702 | + bool *o_bootable) |
701 | 703 | {
|
702 |
| - //errlHndl_t l_errl = NULL; |
703 |
| - |
704 |
| - // nothing to do yet... |
705 |
| - |
706 |
| - // if you add something here, don't forget to |
707 |
| - // add a procedure callout |
708 |
| - //l_errl->addProcedureCallout( EPUB_PRC_FIND_DECONFIGURED_PART, |
709 |
| - // SRCI_PRIORITY_HIGH); |
710 |
| - |
711 |
| - // and update the common plid |
712 |
| - //if (io_plid != 0) |
713 |
| - //{ |
714 |
| - // l_errl->plid(io_plid) ; |
715 |
| - //} |
716 |
| - //else |
717 |
| - //{ |
718 |
| - // io_plid = l_errl->plid(); |
719 |
| - //} |
| 704 | + errlHndl_t l_errl = NULL; |
| 705 | + |
| 706 | + Target* l_pMasterProcChip = NULL; |
| 707 | + targetService().masterProcChipTargetHandle(l_pMasterProcChip); |
| 708 | + |
| 709 | + // NVDIMM only supported on Nimbus |
| 710 | + ATTR_MODEL_type l_model = l_pMasterProcChip->getAttr<ATTR_MODEL>(); |
| 711 | + if (l_model == MODEL_NIMBUS) |
| 712 | + { |
| 713 | + l_errl = checkForHbOnNvdimm(); |
| 714 | + if (l_errl) |
| 715 | + { |
| 716 | + HWAS_ERR("platCheckMinimumHardware::checkForHbOnNvdimm() failed."); |
| 717 | + |
| 718 | + if(o_bootable) |
| 719 | + { |
| 720 | + *o_bootable = false; |
| 721 | + } |
| 722 | + |
| 723 | + // Add procedure callout, update common plid, commit |
| 724 | + hwasErrorAddProcedureCallout(l_errl, |
| 725 | + EPUB_PRC_FIND_DECONFIGURED_PART, |
| 726 | + SRCI_PRIORITY_HIGH); |
| 727 | + hwasErrorUpdatePlid(l_errl, io_plid); |
| 728 | + errlCommit(l_errl, HWAS_COMP_ID); |
| 729 | + } |
| 730 | + } |
| 731 | + |
720 | 732 | }
|
721 | 733 |
|
| 734 | +//****************************************************************************** |
| 735 | +// checkForHbOnNvdimm() |
| 736 | +//****************************************************************************** |
| 737 | +errlHndl_t checkForHbOnNvdimm(void) |
| 738 | +{ |
| 739 | + errlHndl_t l_errl = nullptr; |
| 740 | + |
| 741 | + do |
| 742 | + { |
| 743 | + HWAS_DBG("Check if HB is running on a proc with only NVDIMMs."); |
| 744 | + |
| 745 | + // Get all functional proc chip targets |
| 746 | + TargetHandleList l_procList; |
| 747 | + getAllChips(l_procList, TARGETING::TYPE_PROC); |
| 748 | + assert(l_procList.size() != 0, "Empty proc list returned!"); |
| 749 | + |
| 750 | + // Use the hrmor to find which proc HB is running on |
| 751 | + const auto l_hbHrmor = cpu_spr_value(CPU_SPR_HRMOR); |
| 752 | + |
| 753 | + // Use the MemBases and MemSizes to find which group |
| 754 | + // includes the hrmor |
| 755 | + ATTR_PROC_MEM_BASES_type l_memBases = {0}; |
| 756 | + ATTR_PROC_MEM_SIZES_type l_memSizes = {0}; |
| 757 | + size_t l_numGroups = sizeof(ATTR_PROC_MEM_SIZES_type)/sizeof(uint64_t); |
| 758 | + |
| 759 | + // checkMinimumHardware may be called before the groups are set up |
| 760 | + // If the MemSizes are all zero the groups are not set up yet |
| 761 | + // Break out of the check |
| 762 | + bool l_memSizesAllZero = true; |
| 763 | + |
| 764 | + // Save the HB proc target and group number |
| 765 | + Target *l_hbProc = nullptr; |
| 766 | + uint32_t l_hbGroup = 0; |
| 767 | + |
| 768 | + for (auto l_pProc : l_procList) |
| 769 | + { |
| 770 | + // Get the memory group ranges under this proc |
| 771 | + assert(l_pProc->tryGetAttr<ATTR_PROC_MEM_BASES>(l_memBases), |
| 772 | + "Unable to get ATTR_PROC_MEM_BASES attribute"); |
| 773 | + assert(l_pProc->tryGetAttr<ATTR_PROC_MEM_SIZES>(l_memSizes), |
| 774 | + "Unable to get ATTR_PROC_MEM_SIZES attribute"); |
| 775 | + |
| 776 | + |
| 777 | + for (size_t l_grp=0; l_grp < l_numGroups; l_grp++) |
| 778 | + { |
| 779 | + // Non-zero size means that there is memory present |
| 780 | + if (l_memSizes[l_grp]) |
| 781 | + { |
| 782 | + l_memSizesAllZero = false; |
| 783 | + // Check if hrmor is in this group's memory range |
| 784 | + if ( (l_hbHrmor >= l_memBases[l_grp]) && |
| 785 | + (l_hbHrmor < (l_memBases[l_grp] + |
| 786 | + l_memSizes[l_grp])) ) |
| 787 | + { |
| 788 | + l_hbProc = l_pProc; |
| 789 | + l_hbGroup = l_grp; |
| 790 | + break; |
| 791 | + } |
| 792 | + } |
| 793 | + } |
| 794 | + if (l_hbProc != nullptr) |
| 795 | + { |
| 796 | + break; |
| 797 | + } |
| 798 | + } |
| 799 | + |
| 800 | + if (l_memSizesAllZero) |
| 801 | + { |
| 802 | + break; |
| 803 | + } |
| 804 | + |
| 805 | + if (l_hbProc != nullptr) |
| 806 | + { |
| 807 | + // Found the proc/group HB is running in, now check the dimms |
| 808 | + // If we find a regular dimm then we assume that is where |
| 809 | + // HB is running |
| 810 | + bool l_foundNonNvdimm = false; |
| 811 | + |
| 812 | + // Get the array of mcas/group from the attribute |
| 813 | + // The attr contains 8 8-bit entries, one entry per group |
| 814 | + // The bits specify which mcas are included in the group |
| 815 | + ATTR_MSS_MEM_MC_IN_GROUP_type l_memMcGroup = {0}; |
| 816 | + assert(l_hbProc->tryGetAttr<ATTR_MSS_MEM_MC_IN_GROUP>(l_memMcGroup), |
| 817 | + "Unable to get ATTR_MSS_MEM_MC_IN_GROUP attribute"); |
| 818 | + |
| 819 | + // Get list of mcas under this proc |
| 820 | + TargetHandleList l_mcaList; |
| 821 | + getChildAffinityTargets( l_mcaList, |
| 822 | + l_hbProc, |
| 823 | + CLASS_UNIT, |
| 824 | + TYPE_MCA ); |
| 825 | + |
| 826 | + // Loop through the mcas on this proc |
| 827 | + for (const auto & l_mcaTarget : l_mcaList) |
| 828 | + { |
| 829 | + // Get the chip unit for this mca |
| 830 | + ATTR_CHIP_UNIT_type l_mcaUnit = 0; |
| 831 | + l_mcaUnit = l_mcaTarget->getAttr<ATTR_CHIP_UNIT>(); |
| 832 | + |
| 833 | + // Check if this mca is included in the hb memory group |
| 834 | + const uint8_t l_mcMask = 0x80; |
| 835 | + if (l_memMcGroup[l_hbGroup] & (l_mcMask >> l_mcaUnit)) |
| 836 | + { |
| 837 | + // Get the list of dimms under this mca |
| 838 | + TargetHandleList l_dimmList; |
| 839 | + getChildAffinityTargets( l_dimmList, |
| 840 | + l_mcaTarget, |
| 841 | + CLASS_NA, |
| 842 | + TYPE_DIMM ); |
| 843 | + for (const auto & l_dimmTarget : l_dimmList) |
| 844 | + { |
| 845 | + if (!isNVDIMM(l_dimmTarget)) |
| 846 | + { |
| 847 | + // Found a regular dimm, exit |
| 848 | + l_foundNonNvdimm = true; |
| 849 | + break; |
| 850 | + } |
| 851 | + } |
| 852 | + } |
| 853 | + if (l_foundNonNvdimm) |
| 854 | + { |
| 855 | + break; |
| 856 | + } |
| 857 | + } |
| 858 | + |
| 859 | + // If only nvdimms then error |
| 860 | + if (!l_foundNonNvdimm) |
| 861 | + { |
| 862 | + HWAS_ERR("checkForHbOnNvdimm: HB is running on a proc with only NVDIMMS."); |
| 863 | + /*@ |
| 864 | + * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE |
| 865 | + * @moduleid HWAS::MOD_CHECK_HB_NVDIMM |
| 866 | + * @reasoncode HWAS::RC_HB_PROC_ONLY_NVDIMM |
| 867 | + * @userdata1 Hostboot Proc Target HUID |
| 868 | + * @userdata2 Hostboot Memory Group |
| 869 | + * @devdesc Hostboot running on proc with only NVDIMMs |
| 870 | + * @custdesc Insufficient DIMM resources |
| 871 | + */ |
| 872 | + l_errl = new ERRORLOG::ErrlEntry( |
| 873 | + ERRORLOG::ERRL_SEV_UNRECOVERABLE, |
| 874 | + HWAS::MOD_CHECK_HB_NVDIMM, |
| 875 | + HWAS::RC_HB_PROC_ONLY_NVDIMM, |
| 876 | + get_huid(l_hbProc), |
| 877 | + l_hbGroup); |
| 878 | + } |
| 879 | + } |
| 880 | + else |
| 881 | + { |
| 882 | + // Should never get here, would be caught elsewhere |
| 883 | + HWAS_ERR("checkForHbOnNvdimm: HB execution proc not found."); |
| 884 | + } |
| 885 | + |
| 886 | + } while(0); |
| 887 | + |
| 888 | + return l_errl; |
| 889 | +} |
722 | 890 |
|
723 | 891 | } // namespace HWAS
|
0 commit comments