support for FFDC-only isolation nodes in chip data
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
Change-Id: Ib457329d31a9f01eb6992e57b11d84c06a63e6e7
diff --git a/src/chip_data/hei_chip_data.cpp b/src/chip_data/hei_chip_data.cpp
index 0c61985..f5c588d 100644
--- a/src/chip_data/hei_chip_data.cpp
+++ b/src/chip_data/hei_chip_data.cpp
@@ -257,8 +257,10 @@
uint8_t numCapRegs, numIsoRules, numChildNodes;
io_stream >> nodeInst >> numCapRegs >> numIsoRules >> numChildNodes;
- // There must be at least one isolation rule defined.
- HEI_ASSERT(0 != numIsoRules);
+ // It is possible to have rules defined and no child nodes, However, if
+ // there are no rules defined (FFDC-only node), there should not be
+ // any child nodes defined.
+ HEI_ASSERT(0 != numIsoRules || 0 == numChildNodes);
// Allocate memory for this isolation node.
auto isoNode =
diff --git a/src/isolator/hei_isolation_node.cpp b/src/isolator/hei_isolation_node.cpp
index 6791d6f..5bcfff8 100644
--- a/src/isolator/hei_isolation_node.cpp
+++ b/src/isolator/hei_isolation_node.cpp
@@ -39,58 +39,66 @@
}
}
- // A rule for i_attnType must exist.
+ // Get the rule for this attention type.
auto rule_itr = iv_rules.find(i_attnType);
- HEI_ASSERT(iv_rules.end() != rule_itr);
- // Get the returned BitString for this rule.
- const BitString* bs = rule_itr->second->getBitString(i_chip);
-
- // Ensure this BitString is not longer than the maximum bit field.
- HEI_ASSERT(bs->getBitLen() <= (1 << (sizeof(BitPosition_t) * 8)));
-
- // Find all active bits for this rule.
- for (BitPosition_t bit = 0; bit < bs->getBitLen(); bit++)
+ // It is possible that a rule does not exist. The likely scenario is that
+ // this node is intended to only gather FFDC for a specific bit in the
+ // parent node.
+ if (iv_rules.end() != rule_itr)
{
- // Continue to the next bit if not active.
- if (!bs->isBitSet(bit))
- continue;
+ // Get the returned BitString for this rule.
+ const BitString* bs = rule_itr->second->getBitString(i_chip);
- // At least one active bit was found.
- o_activeAttn = true;
+ // Ensure this BitString is not longer than the maximum bit field.
+ HEI_ASSERT(bs->getBitLen() <= (1 << (sizeof(BitPosition_t) * 8)));
- // Determine if this attention originated from another register or if it
- // is a leaf in the isolation tree.
- auto child_itr = iv_children.find(bit);
- if (iv_children.end() != child_itr)
+ // Find all active bits for this rule.
+ for (BitPosition_t bit = 0; bit < bs->getBitLen(); bit++)
{
- // This bit was driven from an attention from another register.
- // Continue down the isolation tree to look for more attentions.
- bool attnFound =
- child_itr->second->analyze(i_chip, i_attnType, io_isoData);
- if (!attnFound)
+ // Continue to the next bit if not active.
+ if (!bs->isBitSet(bit))
+ continue;
+
+ // At least one active bit was found.
+ o_activeAttn = true;
+
+ // Determine if this attention originated from another register or
+ // if it is a leaf in the isolation tree.
+ auto child_itr = iv_children.find(bit);
+ if (iv_children.end() != child_itr)
{
- // Something went wrong. There should have been an active
- // attention. It's possible there is a bug in the Chip Data
- // File. Or, it is also possible some other piece of code is
- // clearing the attention before this code is able to analyze
- // it. Another possibility is that the hardware it not behaving
- // as expected. Since we really don't know what happened, we
- // should not assert. Instead, add this bit's signature to
- // io_isoData. If there are no other active attentions, the user
- // application could use this signature to help determine, and
- // circumvent, the isolation problem.
+ // This bit was driven from an attention from another register.
+ // Continue down the isolation tree to look for more attentions.
+ bool attnFound =
+ child_itr->second->analyze(i_chip, i_attnType, io_isoData);
+ if (!attnFound)
+ {
+ // It is possible the child node is only intended for FFDC.
+ // See comment near the check for a valid rule above.
+ // Otherwise, it is possible something went wrong. If there
+ // should have been an active attention, it's possible there
+ // is a bug in the Chip Data File. Or, it is also possible
+ // some other piece of code is clearing the attention before
+ // this code is able to analyze it. Another possibility is
+ // that the hardware it not behaving as expected. Since we
+ // really don't know what happened, we should not assert.
+ // Instead, add this bit's signature to io_isoData. If there
+ // are no other active attentions, the user application
+ // could use this signature to help determine, and
+ // circumvent, the isolation problem.
+ io_isoData.addSignature(
+ Signature{i_chip, iv_id, iv_instance, bit, i_attnType});
+ }
+ }
+ else
+ {
+ // We have reached a leaf in the isolation tree. Add this bit's
+ // signature to io_isoData.
io_isoData.addSignature(
Signature{i_chip, iv_id, iv_instance, bit, i_attnType});
}
}
- else
- {
- // We have reached a leaf in the isolation tree. Add this bit's
- // signature to io_isoData.
- io_isoData.addSignature(
- Signature{i_chip, iv_id, iv_instance, bit, i_attnType});
- }
}
// Analysis is complete on this node. So remove it from cv_isolationStack.
diff --git a/test/simulator/meson.build b/test/simulator/meson.build
index 590e381..1bcdc6a 100644
--- a/test/simulator/meson.build
+++ b/test/simulator/meson.build
@@ -8,6 +8,7 @@
# Test cases
test_src = [
'sample_test_case.cpp',
+ 'test_cases/exp20_foxhound7.cpp',
]
gtest = dependency('gtest', main : true, required : false, method : 'system')
@@ -18,5 +19,5 @@
executable('simulator', sim_src, test_src,
dependencies : gtest,
link_with : libhei_static,
- include_directories: incdir))
+ include_directories: [ incdir, '.' ]))
endif
diff --git a/test/simulator/simulator.cpp b/test/simulator/simulator.cpp
index 32eb31b..6bc3106 100644
--- a/test/simulator/simulator.cpp
+++ b/test/simulator/simulator.cpp
@@ -13,10 +13,10 @@
const std::map<SimulatorData::SimChipType, const char*>
SimulatorData::cv_chipPath = {
{SAMPLE, "../test/simulator/sample_data/sample.cdb"},
- {EXPLORER_11, "chip_data_explorer_11.cdb"},
- {EXPLORER_20, "chip_data_explorer_20.cdb"},
- {P10_10, "chip_data_p10_10.cdb"},
- {P10_20, "chip_data_p10_20.cdb"},
+ {EXPLORER_11, "xml/chip_data_explorer_11.cdb"},
+ {EXPLORER_20, "xml/chip_data_explorer_20.cdb"},
+ {P10_10, "xml/chip_data_p10_10.cdb"},
+ {P10_20, "xml/chip_data_p10_20.cdb"},
};
//------------------------------------------------------------------------------
diff --git a/test/simulator/test_cases/exp20_foxhound7.cpp b/test/simulator/test_cases/exp20_foxhound7.cpp
new file mode 100644
index 0000000..65a4966
--- /dev/null
+++ b/test/simulator/test_cases/exp20_foxhound7.cpp
@@ -0,0 +1,16 @@
+#include "simulator.hpp"
+
+START_TEST_CASE(exp20_foxhoundfatal)
+
+CHIP(ocmb0, EXPLORER_20)
+
+START_ITERATION
+
+REG_SCOM(ocmb0, 0x08040000, 0x1000000000000000) // OCMB_CHIPLET_CS_FIR
+REG_SCOM(ocmb0, 0x0804000a, 0x0000000001000000) // OCMB_LFIR
+
+EXP_SIG(ocmb0, 0xbdcd, 0, 39, UNIT_CS)
+
+END_ITERATION
+
+END_TEST_CASE
diff --git a/xml/.gitignore b/xml/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/xml/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/xml/chip_data_xml.md b/xml/chip_data_xml.md
index d7d839a..5052056 100644
--- a/xml/chip_data_xml.md
+++ b/xml/chip_data_xml.md
@@ -101,11 +101,13 @@
* Register length: 8 bytes
* Bit order: ascending (0-63, left to right)
-### 2.4) Element `<register>` (required 1 or more)
+### 2.4) Element `<register>` (conditionally optional)
-These provide a list of all registers required for isolation of this node. At
-a minimum, a `<register>` element must exist for each register referenced by
-the `<rule>` elements.
+These provide a list of all registers required for isolation of this node.
+
+At a minimum, a `<register>` element must exist for each register referenced by
+the `<capture_group>` or `<rule>` elements. Also, see the `<local_fir>` element
+for a possible shorthand definition.
#### 2.4.1) Attribute `name` (required)
@@ -187,13 +189,18 @@
number of instances represented by the the `node_inst` attribute of the
`<capture_group>` element.
-### 2.6) Element `<rule>` (required 1 or more)
+### 2.6) Element `<rule>` (conditionally optional)
A rule helps specify if an attention is being raised from a register and what
type of attention is being raised. A rule is constructed by a series of
expressions (see `<expr>` below). The result of the expressions will indicate
all active attentions for a rule.
+At least one `<rule>` must exist if any `<bit>` elements are defined. The
+`<rule>` elements are optional for nodes that are intended to only capture FFDC
+for a bit defined in the parent node. Also, see the `<local_fir>` element for a
+possible shorthand definition.
+
#### 2.6.1) Attribute `attn_type` (required)
The attention type for this rule. See appendix for supported values.
@@ -259,10 +266,13 @@
The length of the number is defined by the `reg_type` attribute of the root
`<attn_node>` element.
-### 2.7) Element `<bit>` (required 1 or more)
+### 2.7) Element `<bit>` (conditionally optional)
-These provide metadata for each bit in this node. There should be a `<bit>`
-element for each bit that could generate an attention.
+These provide metadata for each bit in this node.
+
+The `<bit>` elements should only be defined if there are `<rule>` elements
+defined and there should be a `<bit>` element for each bit in the rules that
+could generate an attention.
#### 2.7.1) Attribute `pos` (required)
diff --git a/xml/explorer/node_ocmb_lfir.xml b/xml/explorer/node_ocmb_lfir.xml
index 7cb4543..4c8c1a1 100644
--- a/xml/explorer/node_ocmb_lfir.xml
+++ b/xml/explorer/node_ocmb_lfir.xml
@@ -31,7 +31,14 @@
<bit pos="36" >DDR4 PHY fatal</bit>
<bit pos="37" >DDR4 PHY non fatal</bit>
<bit pos="38" >DDR4 PHY interrupt</bit>
- <bit pos="39:46">foxhound fatal</bit>
+ <bit pos="39" child_node="OCMB_LFIR_FFDC_FOXHOUND" node_inst="7">foxhound fatal lane 7</bit>
+ <bit pos="40" child_node="OCMB_LFIR_FFDC_FOXHOUND" node_inst="6">foxhound fatal lane 6</bit>
+ <bit pos="41" child_node="OCMB_LFIR_FFDC_FOXHOUND" node_inst="5">foxhound fatal lane 5</bit>
+ <bit pos="42" child_node="OCMB_LFIR_FFDC_FOXHOUND" node_inst="4">foxhound fatal lane 4</bit>
+ <bit pos="43" child_node="OCMB_LFIR_FFDC_FOXHOUND" node_inst="3">foxhound fatal lane 3</bit>
+ <bit pos="44" child_node="OCMB_LFIR_FFDC_FOXHOUND" node_inst="2">foxhound fatal lane 2</bit>
+ <bit pos="45" child_node="OCMB_LFIR_FFDC_FOXHOUND" node_inst="1">foxhound fatal lane 1</bit>
+ <bit pos="46" child_node="OCMB_LFIR_FFDC_FOXHOUND" node_inst="0">foxhound fatal lane 0</bit>
<bit pos="47:54">foxhound non fatal</bit>
<bit pos="55:62">foxhound serdes interrupt</bit>
<bit pos="63" >GIF2PCB parity error on FSM or Registers</bit>
diff --git a/xml/explorer/node_ocmb_lfir_ffdc_foxhound.xml b/xml/explorer/node_ocmb_lfir_ffdc_foxhound.xml
new file mode 100644
index 0000000..531c9ff
--- /dev/null
+++ b/xml/explorer/node_ocmb_lfir_ffdc_foxhound.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<attn_node name="OCMB_LFIR_FFDC_FOXHOUND" model_ec="EXPLORER_11,EXPLORER_20" reg_type="SCOM">
+
+ <!--
+ These registers are on the MicroChip side of Explorer and are not in
+ the SCOM def.
+ -->
+
+ <register name="ADSP_PCBI">
+ <instance reg_inst="0" addr="0x00200860" />
+ <instance reg_inst="1" addr="0x00201860" />
+ <instance reg_inst="2" addr="0x00202860" />
+ <instance reg_inst="3" addr="0x00203860" />
+ <instance reg_inst="4" addr="0x00204860" />
+ <instance reg_inst="5" addr="0x00205860" />
+ <instance reg_inst="6" addr="0x00206860" />
+ <instance reg_inst="7" addr="0x00207860" />
+ </register>
+
+ <register name="CSU_PCBI">
+ <instance reg_inst="0" addr="0x002000B0" />
+ <instance reg_inst="1" addr="0x002010B0" />
+ <instance reg_inst="2" addr="0x002020B0" />
+ <instance reg_inst="3" addr="0x002030B0" />
+ <instance reg_inst="4" addr="0x002040B0" />
+ <instance reg_inst="5" addr="0x002050B0" />
+ <instance reg_inst="6" addr="0x002060B0" />
+ <instance reg_inst="7" addr="0x002070B0" />
+ </register>
+
+ <capture_group node_inst="0:7">
+ <capture_register reg_name="ADSP_PCBI" reg_inst="0:7" />
+ <capture_register reg_name="CSU_PCBI" reg_inst="0:7" />
+ </capture_group>
+
+</attn_node>
+
diff --git a/xml/node.xsd b/xml/node.xsd
index 5edcb32..2bbe4ec 100644
--- a/xml/node.xsd
+++ b/xml/node.xsd
@@ -17,7 +17,7 @@
<xsd:element name="capture_group" type="capture_group" minOccurs="0"
maxOccurs="255"/>
<xsd:element name="rule" type="rule" minOccurs="0" maxOccurs="255"/>
- <xsd:element name="bit" type="bit" minOccurs="1" maxOccurs="255"/>
+ <xsd:element name="bit" type="bit" minOccurs="0" maxOccurs="255"/>
</xsd:sequence>
<xsd:attribute name="name" type="name_type" use="required"/>
diff --git a/xml/parse_chip_data_xml b/xml/parse_chip_data_xml
index 131ff56..b91de9d 100755
--- a/xml/parse_chip_data_xml
+++ b/xml/parse_chip_data_xml
@@ -552,12 +552,6 @@
{
my ( $node, $insts_data ) = @_;
- # There must be at least one rule entry.
- unless ( defined $node->{rule} and 0 < scalar @{$node->{rule}} )
- {
- FAIL( "Node $node->{name} does not contain at least one rule" );
- }
-
# There should be only one rule per attention type and node instance for
# this node.
my $rule_dups = {};
@@ -607,12 +601,6 @@
{
my ( $node, $sigs, $insts_data ) = @_;
- # There must be at least one bit entry.
- unless ( defined $node->{bit} and 0 < scalar @{$node->{bit}} )
- {
- FAIL( "Node $node->{name} does not contain at least one bit" );
- }
-
my @node_insts = sort keys %{$insts_data};
my $sz_insts = scalar @node_insts;
@@ -720,13 +708,27 @@
# Split the capture group information per node instance.
__normalizeCaptureGroup($node, $insts_data);
- # Split the rule information per node instance. The sorted instance list
- # will be used as indexes for the node_inst attribute of the <bit> elements.
- __normalizeRule($node, $insts_data);
+ my $is_rule = (defined $node->{rule} and 0 < scalar @{$node->{rule}}) ? 1 : 0;
+ my $is_bit = (defined $node->{bit} and 0 < scalar @{$node->{bit}}) ? 1 : 0;
- # Finally, collect the signature details and split the bit information per
- # node instance.
- __normalizeBit($node, $sigs, $insts_data);
+ # If a rule is defined, a bit must be defined as well. It is possible for
+ # neither to be defined (FFDC-only node).
+ if ( $is_rule and $is_bit )
+ {
+ # Split the rule information per node instance. The sorted instance list
+ # will be used as indexes for the node_inst attribute of the <bit>
+ # elements.
+ __normalizeRule($node, $insts_data);
+
+ # Finally, collect the signature details and split the bit information
+ # per node instance.
+ __normalizeBit($node, $sigs, $insts_data);
+ }
+ elsif ( $is_rule or $is_bit )
+ {
+ # One is defined and the other is not. This is an error.
+ FAIL("Node $node->{name} has a bit or rule defined and the other is not.");
+ }
# Now that we have all of the node data, collapse the instance data into
# a list.
@@ -1068,12 +1070,8 @@
my $num_cap_regs = (defined $i->{capture_group})
? scalar @{$i->{capture_group}} : 0;
- # At least one rule is required.
- my $num_rules = scalar @{$i->{rule}};
- unless ( 0 < $num_rules )
- {
- FAIL("No rule for $n->{name} $i->{node_inst}");
- }
+ # Rules may not exist for this node.
+ my $num_rules = (defined $i->{rule}) ? scalar @{$i->{rule}} : 0;
# Child nodes may not exist for this node.
my $num_bit = (defined $i->{bit}) ? scalar @{$i->{bit}} : 0;
@@ -1094,11 +1092,14 @@
}
}
- for my $r ( @{$i->{rule}} )
+ if ( 0 < $num_rules )
{
- # Register rule metadata
- __bin($fh, 1, $ATTN_TYPE->{$r->{attn_type}}->[0]);
- __printExpr($fh, $reg_size, $r->{expr});
+ for my $r ( @{$i->{rule}} )
+ {
+ # Register rule metadata
+ __bin($fh, 1, $ATTN_TYPE->{$r->{attn_type}}->[0]);
+ __printExpr($fh, $reg_size, $r->{expr});
+ }
}
if ( 0 < $num_bit )