diff --git a/10.02_devices/2_src/cpu.cpp b/10.02_devices/2_src/cpu.cpp index e8c57d4..4ea0e9a 100644 --- a/10.02_devices/2_src/cpu.cpp +++ b/10.02_devices/2_src/cpu.cpp @@ -66,7 +66,7 @@ void unibone_logdump(void) { // called before opcode fetch of next instruction // This is the point in time were INTR requests are checked and GRANTed // (PRU implementation may limit NPR GRANTs also to this time) -void unibone_on_before_instruction(void) { +void unibone_grant_interrupts(void) { // after that the CPU should check for received INTR vectors // in its microcode service() step.c // allow PRU do to produce GRANT for device requests diff --git a/10.02_devices/2_src/cpu20/ka11.c b/10.02_devices/2_src/cpu20/ka11.c index d0b6b6f..ab75319 100644 --- a/10.02_devices/2_src/cpu20/ka11.c +++ b/10.02_devices/2_src/cpu20/ka11.c @@ -3,7 +3,7 @@ #include "gpios.hpp" // ARM_DEBUG_PIN* -void unibone_on_before_instruction(void) ; +void unibone_grant_interrupts(void) ; int unibone_dato(unsigned addr, unsigned data); int unibone_datob(unsigned addr, unsigned data); int unibone_dati(unsigned addr, unsigned *data); @@ -553,9 +553,7 @@ step(KA11 *cpu) /* Operate */ switch(cpu->ir & 7){ case 0: TR(HALT); cpu->state = STATE_HALTED; return; - case 1: TR(WAIT); -printf("WAIT\n") ; - cpu->state = STATE_WAITING; return; + case 1: TR(WAIT); cpu->state = STATE_WAITING; return; case 2: TR(RTI); BA = SP; POP; IN(PC); BA = SP; POP; IN(PSW); @@ -644,6 +642,8 @@ ka11_setintr(KA11 *cpu, unsigned vec) cpu->external_intr = true; cpu->external_intrvec = vec; trace("INTR vec=%03o\n", vec) ; + if (cpu->state == STATE_WAITING) // atomically + cpu->state = STATE_RUNNING ; pthread_mutex_unlock(&cpu->mutex) ; } @@ -671,11 +671,15 @@ be: void ka11_condstep(KA11 *cpu) { + if(cpu->state == STATE_RUNNING || cpu->state == STATE_WAITING) + // GRANT Interrupts before opcode fetch, or when CPU is on WAIT + unibone_grant_interrupts() ; + if((cpu->state == STATE_RUNNING) || (cpu->state == STATE_WAITING && cpu->traps)){ cpu->state = STATE_RUNNING; + // external_intr WAIT handled atomically in ka11_setintr() ! - unibone_on_before_instruction() ; svc(cpu, cpu->bus); step(cpu); }