GicV2::readDistributor(ContextID ctx, Addr daddr, size_t resp_sz)
{
if (GICD_IGROUPR.contains(daddr)) {
- return 0; // unimplemented; RAZ (read as zero)
+ uint32_t ix = (daddr - GICD_IGROUPR.start()) >> 2;
+ assert(ix < 32);
+ return getIntGroup(ctx, ix);
}
if (GICD_ISENABLER.contains(daddr)) {
size_t data_sz)
{
if (GICD_IGROUPR.contains(daddr)) {
- return; // unimplemented; WI (writes ignored)
+ uint32_t ix = (daddr - GICD_IGROUPR.start()) >> 2;
+ assert(ix < 32);
+ getIntGroup(ctx, ix) |= data;
+ return;
}
if (GICD_ISENABLER.contains(daddr)) {
SERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
SERIALIZE_ARRAY(pendingInt, INT_BITS_MAX-1);
SERIALIZE_ARRAY(activeInt, INT_BITS_MAX-1);
+ SERIALIZE_ARRAY(intGroup, INT_BITS_MAX-1);
SERIALIZE_ARRAY(iccrpr, CPU_MAX);
SERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
SERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
SERIALIZE_SCALAR(intEnabled);
SERIALIZE_SCALAR(pendingInt);
SERIALIZE_SCALAR(activeInt);
+ SERIALIZE_SCALAR(intGroup);
SERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
}
UNSERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
UNSERIALIZE_ARRAY(pendingInt, INT_BITS_MAX-1);
UNSERIALIZE_ARRAY(activeInt, INT_BITS_MAX-1);
+ UNSERIALIZE_ARRAY(intGroup, INT_BITS_MAX-1);
UNSERIALIZE_ARRAY(iccrpr, CPU_MAX);
UNSERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
UNSERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
UNSERIALIZE_SCALAR(intEnabled);
UNSERIALIZE_SCALAR(pendingInt);
UNSERIALIZE_SCALAR(activeInt);
+ UNSERIALIZE_SCALAR(intGroup);
UNSERIALIZE_ARRAY(intPriority, SGI_MAX + PPI_MAX);
}
* interrupt active bits for first 32 interrupts, 1b per interrupt */
uint32_t activeInt;
+ /** GICD_IGROUPR0
+ * interrupt group bits for first 32 interrupts, 1b per interrupt */
+ uint32_t intGroup;
+
/** GICD_IPRIORITYR{0..7}
* interrupt priority for SGIs and PPIs */
uint8_t intPriority[SGI_MAX + PPI_MAX];
void unserialize(CheckpointIn &cp) override;
BankedRegs() :
- intEnabled(0), pendingInt(0), activeInt(0), intPriority {0}
+ intEnabled(0), pendingInt(0), activeInt(0),
+ intGroup(0), intPriority {0}
{}
};
std::vector<BankedRegs*> bankedRegs;
}
}
+ /** GICD_IGROUPR{1..31}
+ * interrupt group bits for global interrupts
+ * 1b per interrupt, 32 bits per word, 31 words */
+ uint32_t intGroup[INT_BITS_MAX-1];
+
+ uint32_t& getIntGroup(ContextID ctx, uint32_t ix) {
+ assert(ix < INT_BITS_MAX);
+ if (ix == 0) {
+ return getBankedRegs(ctx).intGroup;
+ } else {
+ return intGroup[ix - 1];
+ }
+ }
+
/** read only running priority register, 1 per cpu*/
uint32_t iccrpr[CPU_MAX];