dev: update LupIO-IPI device to latest specs

The specs for the LupIO-IPI device were recently updated. Instead of
providing a single IPI value for each processor, the device now provides
32 individual IPI bits that can be masked and set.

Update device accordingly in gem5.

Change-Id: Ia47cd1c70e073686bc2009d546c80edb0ad58711
Signed-off-by: Joël Porquet-Lupine <joel@porquet.org>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/61530
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Joël Porquet-Lupine
2022-07-20 15:25:15 -07:00
committed by Joël Porquet-Lupine
parent 0800c060d8
commit 1c6f57cd6d
2 changed files with 61 additions and 16 deletions

View File

@@ -42,23 +42,49 @@ LupioIPI::LupioIPI(const Params &params) :
intType(params.int_type),
nThread(params.num_threads)
{
word.resize(nThread, 0);
mask.resize(nThread, 0);
pending.resize(nThread, 0);
DPRINTF(LupioIPI, "LupioIPI initalized--number of CPUs: %d\n", nThread);
}
void
LupioIPI::lupioIPIUpdateIRQ()
{
for (int cpu = 0; cpu < nThread; cpu++) {
auto tc = system->threads[cpu];
if (mask[cpu] & pending[cpu]) {
tc->getCpuPtr()->postInterrupt(tc->threadId(), intType, 0);
} else {
tc->getCpuPtr()->clearInterrupt(tc->threadId(), intType, 0);
}
}
}
uint64_t
LupioIPI::lupioIPIRead(uint8_t addr, int size)
{
int cpu = addr >> 2;
uint32_t r = 0;
// Reading automatically lowers corresponding IRQ
r = word[cpu];
auto tc = system->threads[cpu];
tc->getCpuPtr()->clearInterrupt(tc->threadId(), intType, 0);
// Also reset value after reading
word[cpu] = 0;
int cpu = addr / LUPIO_IPI_MAX;
int reg = addr % LUPIO_IPI_MAX;
switch (reg) {
case LUPIO_IPI_MASK:
r = mask[cpu];
DPRINTF(LupioIPI, "Read IPI_MASK[%d]: %#x\n", cpu, r);
break;
case LUPIO_IPI_PEND:
r = pending[cpu];
DPRINTF(LupioIPI, "Read IPI_PEND[%d]: %#x\n", cpu, r);
break;
default:
panic("Unexpected read to LupioIPI device at address %#llx!",
addr);
break;
}
return r;
}
@@ -66,15 +92,28 @@ LupioIPI::lupioIPIRead(uint8_t addr, int size)
void
LupioIPI::lupioIPIWrite(uint8_t addr, uint64_t val64, int size)
{
int cpu = addr >> 2;;
uint32_t val = val64;
word[cpu] = val;
int cpu = addr / LUPIO_IPI_MAX;
int reg = addr % LUPIO_IPI_MAX;
// Raise IRQ
auto tc = system->threads[cpu];
switch (reg) {
case LUPIO_IPI_MASK:
mask[cpu] = val;
DPRINTF(LupioIPI, "Write IPI_MASK[%d]: %#x\n", cpu, mask[cpu]);
lupioIPIUpdateIRQ();
break;
case LUPIO_IPI_PEND:
pending[cpu] = val;
DPRINTF(LupioIPI, "Write IPI_PEND[%d]: %#x\n", cpu, pending[cpu]);
lupioIPIUpdateIRQ();
break;
tc->getCpuPtr()->postInterrupt(tc->threadId(), intType, 0);
default:
panic("Unexpected write to LupioIPI device at address %#llx!",
addr);
break;
}
}
Tick

View File

@@ -52,10 +52,11 @@ class LupioIPI : public BasicPioDevice
// Register map
enum
{
LUPIO_IPI_WORD,
LUPIO_IPI_MASK = 0x0,
LUPIO_IPI_PEND = 0x4,
// Max offset
LUPIO_IPI_MAX,
LUPIO_IPI_MAX = 0x8,
};
uint32_t nThread;
@@ -63,7 +64,8 @@ class LupioIPI : public BasicPioDevice
* Set of registers corresponding to each CPU for sending
* inter-processor interrupts
*/
std::vector<uint32_t> word;
std::vector<uint32_t> mask;
std::vector<uint32_t> pending;
/**
* Function to return the value in the word register of the corresponding
@@ -75,6 +77,10 @@ class LupioIPI : public BasicPioDevice
* raise the IRQ
*/
void lupioIPIWrite(const uint8_t addr, uint64_t val64, int size);
/**
* Function to post and clear interrupts
**/
void lupioIPIUpdateIRQ();
public:
PARAMS(LupioIPI);