diff --git a/10.01_base/2_src/pru1/pru1_main_unibus.c b/10.01_base/2_src/pru1/pru1_main_unibus.c index 09d5fab..43ac8ab 100644 --- a/10.01_base/2_src/pru1/pru1_main_unibus.c +++ b/10.01_base/2_src/pru1/pru1_main_unibus.c @@ -159,9 +159,11 @@ void main(void) { // "set" is inverting! cpu_grant_mask = buslatches_getbyte(0) & PRIORITY_ARBITRATION_BIT_MASK; // read GRANT IN // forward un-requested GRANT IN to GRANT OUT for other cards on neighbor slots - uint8_t grant_out_mask = cpu_grant_mask & ~sm_arb.device_request_mask ; - buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK, ~grant_out_mask) - ; + sm_arb.device_forwarded_grant_mask = cpu_grant_mask + & ~sm_arb.device_request_signalled_mask; + buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK, ~sm_arb.device_forwarded_grant_mask) + ; + // "A device may not accept a grant (assert SACK) after it passes the grant" } // handle GRANT/SACK/BBSY for emulated devices uint8_t granted_request = sm_device_arb_worker(cpu_grant_mask); // devices process GRANT @@ -293,7 +295,7 @@ void main(void) { mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done break; case ARM2PRU_BUSLATCH_SET: { // set a mux register - // and read back + // and read back // don't feed "volatile" vars into buslatch_macros !!! uint8_t reg_sel = mailbox.buslatch.addr & 7; uint8_t bitmask = mailbox.buslatch.bitmask; diff --git a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c index 3c55511..2c009d6 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c +++ b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.c @@ -100,8 +100,11 @@ void sm_arb_reset() { // cleanup: clear all REQUESTS and SACK buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK | BIT(5), 0); sm_arb.device_request_mask = 0; + sm_arb.device_forwarded_grant_mask = 0; + sm_arb.device_request_signalled_mask = 0; + sm_arb.bbsy_wait_grant_mask = 0; - sm_arb.cpu_request = 0 ; + sm_arb.cpu_request = 0; sm_arb.arbitrator_grant_mask = 0; timeout_cleanup(TIMEOUT_SACK); } @@ -171,6 +174,8 @@ uint8_t sm_arb_worker_device(uint8_t grant_mask) { // Always update UNIBUS BR/NPR lines, are ORed with requests from other devices. buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.device_request_mask) ; + // now relevant for GRANt forwarding + sm_arb.device_request_signalled_mask = sm_arb.device_request_mask; // read GRANT IN lines from CPU (Arbitrator). // Only one nit ion cpu_grant_mask at a time may be active, else arbitrator malfunction. @@ -179,7 +184,8 @@ uint8_t sm_arb_worker_device(uint8_t grant_mask) { if (sm_arb.bbsy_wait_grant_mask == 0) { // State 1: Wait For GRANT: // process the requested grant for an open requests. - grant_mask &= sm_arb.device_request_mask; + // "A device may not accept a grant (assert SACK) after it passes the grant" + grant_mask &= (sm_arb.device_request_mask & ~sm_arb.device_forwarded_grant_mask); if (grant_mask) { // one of our requests was granted: // set SACK diff --git a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h index 5f0c927..3d74666 100644 --- a/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h +++ b/10.01_base/2_src/pru1/pru1_statemachine_arbitration.h @@ -42,6 +42,12 @@ typedef struct { // BR/NPR lines = set of _PRIORITY_ARBITRATION_BIT_* uint8_t device_request_mask; + // device_request_mask when actually on BR/NR lines + uint8_t device_request_signalled_mask; + + // forwarded to GRANT OUT, not accepted as response to device_request_signalled_mask + uint8_t device_forwarded_grant_mask; + // sm_arb has 2 states: State 1 "Wait for GRANT" and State 2 "wait for BBSY" // When arbitrator GRANts a request, we set SACK, GRAMT is cleared and we wait // for BBSY clear. @@ -51,11 +57,11 @@ typedef struct { /*** master ****/ // CPU is requesting memory access via PRU2ARM_DMA/mailbox.dma - uint8_t cpu_request ; - + uint8_t cpu_request; + uint8_t arbitrator_grant_mask; // single GRANT line set by master - // uint8_t dummy[3] ; + uint8_t dummy[2]; // make it dword-sized } statemachine_arbitration_t;