mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
Initial SPARC SMP support (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1694 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
b9788fc4c4
commit
ba3c64fb47
12 changed files with 196 additions and 54 deletions
|
@ -53,6 +53,7 @@ typedef struct SLAVIO_INTCTLState {
|
|||
#ifdef DEBUG_IRQ_COUNT
|
||||
uint64_t irq_count[32];
|
||||
#endif
|
||||
CPUState *cpu_envs[MAX_CPUS];
|
||||
} SLAVIO_INTCTLState;
|
||||
|
||||
#define INTCTL_MAXADDR 0xf
|
||||
|
@ -96,6 +97,7 @@ static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint
|
|||
case 2: // set softint
|
||||
val &= 0xfffe0000;
|
||||
s->intreg_pending[cpu] |= val;
|
||||
slavio_check_interrupts(s);
|
||||
DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
|
||||
break;
|
||||
default:
|
||||
|
@ -216,7 +218,7 @@ static void slavio_check_interrupts(void *opaque)
|
|||
CPUState *env;
|
||||
SLAVIO_INTCTLState *s = opaque;
|
||||
uint32_t pending = s->intregm_pending;
|
||||
unsigned int i, max = 0;
|
||||
unsigned int i, j, max = 0;
|
||||
|
||||
pending &= ~s->intregm_disabled;
|
||||
|
||||
|
@ -227,20 +229,52 @@ static void slavio_check_interrupts(void *opaque)
|
|||
max = intbit_to_level[i];
|
||||
}
|
||||
}
|
||||
env = first_cpu;
|
||||
if (env->interrupt_index == 0) {
|
||||
DPRINTF("Triggered pil %d\n", max);
|
||||
env = s->cpu_envs[s->target_cpu];
|
||||
if (!env) {
|
||||
DPRINTF("No CPU %d, not triggered (pending %x)\n", s->target_cpu, pending);
|
||||
}
|
||||
else {
|
||||
if (env->halted)
|
||||
env->halted = 0;
|
||||
if (env->interrupt_index == 0) {
|
||||
DPRINTF("Triggered CPU %d pil %d\n", s->target_cpu, max);
|
||||
#ifdef DEBUG_IRQ_COUNT
|
||||
s->irq_count[max]++;
|
||||
s->irq_count[max]++;
|
||||
#endif
|
||||
env->interrupt_index = TT_EXTINT | max;
|
||||
cpu_interrupt(env, CPU_INTERRUPT_HARD);
|
||||
env->interrupt_index = TT_EXTINT | max;
|
||||
cpu_interrupt(env, CPU_INTERRUPT_HARD);
|
||||
}
|
||||
else
|
||||
DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index);
|
||||
}
|
||||
else
|
||||
DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index);
|
||||
}
|
||||
else
|
||||
DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled);
|
||||
|
||||
for (i = 0; i < MAX_CPUS; i++) {
|
||||
max = 0;
|
||||
env = s->cpu_envs[i];
|
||||
if (!env)
|
||||
continue;
|
||||
for (j = 17; j < 32; j++) {
|
||||
if (s->intreg_pending[i] & (1 << j)) {
|
||||
if (max < j - 16)
|
||||
max = j - 16;
|
||||
}
|
||||
}
|
||||
if (max > 0) {
|
||||
if (env->halted)
|
||||
env->halted = 0;
|
||||
if (env->interrupt_index == 0) {
|
||||
DPRINTF("Triggered softint %d for cpu %d (pending %x)\n", max, i, pending);
|
||||
#ifdef DEBUG_IRQ_COUNT
|
||||
s->irq_count[max]++;
|
||||
#endif
|
||||
env->interrupt_index = TT_EXTINT | max;
|
||||
cpu_interrupt(env, CPU_INTERRUPT_HARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -251,7 +285,7 @@ void slavio_pic_set_irq(void *opaque, int irq, int level)
|
|||
{
|
||||
SLAVIO_INTCTLState *s = opaque;
|
||||
|
||||
DPRINTF("Set irq %d level %d\n", irq, level);
|
||||
DPRINTF("Set cpu %d irq %d level %d\n", s->target_cpu, irq, level);
|
||||
if (irq < 32) {
|
||||
uint32_t mask = 1 << irq;
|
||||
uint32_t pil = intbit_to_level[irq];
|
||||
|
@ -269,6 +303,29 @@ void slavio_pic_set_irq(void *opaque, int irq, int level)
|
|||
slavio_check_interrupts(s);
|
||||
}
|
||||
|
||||
void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu)
|
||||
{
|
||||
SLAVIO_INTCTLState *s = opaque;
|
||||
|
||||
DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level);
|
||||
if (cpu == (unsigned int)-1) {
|
||||
slavio_pic_set_irq(opaque, irq, level);
|
||||
return;
|
||||
}
|
||||
if (irq < 32) {
|
||||
uint32_t pil = intbit_to_level[irq];
|
||||
if (pil > 0) {
|
||||
if (level) {
|
||||
s->intreg_pending[cpu] |= 1 << pil;
|
||||
}
|
||||
else {
|
||||
s->intreg_pending[cpu] &= ~(1 << pil);
|
||||
}
|
||||
}
|
||||
}
|
||||
slavio_check_interrupts(s);
|
||||
}
|
||||
|
||||
static void slavio_intctl_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
SLAVIO_INTCTLState *s = opaque;
|
||||
|
@ -312,6 +369,12 @@ static void slavio_intctl_reset(void *opaque)
|
|||
s->target_cpu = 0;
|
||||
}
|
||||
|
||||
void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env)
|
||||
{
|
||||
SLAVIO_INTCTLState *s = opaque;
|
||||
s->cpu_envs[cpu] = env;
|
||||
}
|
||||
|
||||
void *slavio_intctl_init(uint32_t addr, uint32_t addrg)
|
||||
{
|
||||
int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue