mirror of
https://github.com/livingcomputermuseum/UniBone.git
synced 2026-03-29 10:55:55 +00:00
First successful iNTR on emulated CPU20
This commit is contained in:
@@ -237,9 +237,8 @@ bool unibusadapter_c::register_device(unibusdevice_c& device) {
|
||||
if (cpu) {
|
||||
assert(the_cpu == NULL); // only one allowed!
|
||||
the_cpu = cpu;
|
||||
// TODO: PRU code debuggen
|
||||
//mailbox->cpu_enable = 1 ;
|
||||
//mailbox_execute(ARM2PRU_CPU_ENABLE) ;
|
||||
mailbox->cpu_enable = 1 ;
|
||||
mailbox_execute(ARM2PRU_CPU_ENABLE) ;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -765,14 +764,21 @@ void unibusadapter_c::cpu_DATA_transfer(dma_request_c& dma_request, uint8_t unib
|
||||
|
||||
// do the transfer. Wait until concurrent device DMA/INTR complete
|
||||
do {
|
||||
while (mailbox->arbitrator.device_BBSY)
|
||||
timeout.wait_us(100);
|
||||
while (mailbox->arbitrator.device_BBSY) {
|
||||
timeout.wait_us(10);
|
||||
// This blocks the CPU thread.
|
||||
// Device threads continue and are waiting for End of DMA/INTR
|
||||
// PRU performs DMA/INTR) and master_arbitrator clears device_BBSY.
|
||||
// PRU cpu logic responds as INTR_slave
|
||||
}
|
||||
mailbox->arbitrator.cpu_BBSY = true; // mark as "initiated by CPU, not by device"
|
||||
success = mailbox_execute(ARM2PRU_DMA);
|
||||
// a device may have acquired the bus concurrently,
|
||||
// then ARM2PRU_DMA is answered with an error
|
||||
// then ARM2PRU_DMA is answered with error PRU2ARM_DMA_CPU_TRANSFER_BLOCKED.
|
||||
// infinite time may have passed after that check above
|
||||
} while (!success);
|
||||
|
||||
|
||||
// wait for PRU complete event, no clear why that double lock() is working anyhow!
|
||||
pthread_mutex_lock(&cpu_data_transfer_request->complete_mutex);
|
||||
// DMA() is blocking: Wait for request to finish.
|
||||
@@ -1068,7 +1074,6 @@ void unibusadapter_c::worker(unsigned instance) {
|
||||
bool dclo_falling_edge = false;
|
||||
bool aclo_raising_edge = false;
|
||||
bool aclo_falling_edge = false;
|
||||
// DEBUG("mailbox->events: mask=0x%x", mailbox->events.eventmask);
|
||||
if (!EVENT_IS_ACKED(*mailbox, init)) {
|
||||
any_event = true;
|
||||
// robust: any change in ACLO/DCL=INIT updates state of all 3.
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
other GRANTS
|
||||
- monitoring INIT and AC_LO/DC_LO
|
||||
- watching fpr AMR2PRU commands
|
||||
2. "BBSYWAIT": UNibone got PRIORITY GRAMT, has set SACK and released BR/NPR
|
||||
2. "BBSYWAIT": UniBone got PRIORITY GRAMT, has set SACK and released BR/NPR
|
||||
waits for current BUS master to relaeasy BBSY (ony DATI/DATO cycle max)
|
||||
- SACK active: no GRANT forward necessary, no arbitration necessary
|
||||
- INIT is monitored by DMA statemachine: no DC_LO/INIT monitoring necessary
|
||||
@@ -219,7 +219,7 @@ void main(void) {
|
||||
} else {
|
||||
// Emulated device: raise request for emulated or physical Arbitrator.
|
||||
// request DMA, arbitrator must've been selected with ARM2PRU_ARB_MODE_*
|
||||
sm_arb.request_mask |= PRIORITY_ARBITRATION_BIT_NP;
|
||||
sm_arb.device_request_mask |= PRIORITY_ARBITRATION_BIT_NP;
|
||||
// sm_arb_worker() evaluates this,extern Arbitrator raises Grant, excution starts in future loop
|
||||
// end of DMA is signaled to ARM with signal
|
||||
|
||||
@@ -238,7 +238,7 @@ void main(void) {
|
||||
// request INTR, arbitrator must've been selected with ARM2PRU_ARB_MODE_*
|
||||
// start one INTR cycle. May be raised in midst of slave cycle
|
||||
// by ARM, if access to "active" register triggers INTR.
|
||||
sm_arb.request_mask |= mailbox.intr.priority_arbitration_bit;
|
||||
sm_arb.device_request_mask |= mailbox.intr.priority_arbitration_bit;
|
||||
// sm_arb_worker() evaluates this, extern Arbitrator raises Grant,
|
||||
// vector of GRANted level is transfered with statemachine sm_intr_master
|
||||
|
||||
@@ -254,7 +254,7 @@ void main(void) {
|
||||
case ARM2PRU_INTR_CANCEL:
|
||||
// cancels one or more INTR requests. If already Granted, the GRANT is forwarded,
|
||||
// and canceled by reaching a "SACK turnaround terminator" or "No SACK TIMEOUT" in the arbitrator.
|
||||
sm_arb.request_mask &= ~mailbox.intr.priority_arbitration_bit;
|
||||
sm_arb.device_request_mask &= ~mailbox.intr.priority_arbitration_bit;
|
||||
// no completion event, could interfer with other INTRs?
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // done
|
||||
break;
|
||||
|
||||
@@ -99,7 +99,7 @@ statemachine_arbitration_t sm_arb;
|
||||
void sm_arb_reset() {
|
||||
// cleanup: clear all REQUESTS and SACK
|
||||
buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK | BIT(5), 0);
|
||||
sm_arb.request_mask = 0;
|
||||
sm_arb.device_request_mask = 0;
|
||||
sm_arb.bbsy_wait_grant_mask = 0;
|
||||
|
||||
sm_arb.arbitrator_grant_mask = 0;
|
||||
@@ -123,13 +123,56 @@ uint8_t sm_arb_worker_none() {
|
||||
;
|
||||
|
||||
// ignore BR* INTR requests, only ack DMA.
|
||||
if (sm_arb.request_mask & PRIORITY_ARBITRATION_BIT_NP) {
|
||||
sm_arb.request_mask &= ~PRIORITY_ARBITRATION_BIT_NP;
|
||||
if (sm_arb.device_request_mask & PRIORITY_ARBITRATION_BIT_NP) {
|
||||
sm_arb.device_request_mask &= ~PRIORITY_ARBITRATION_BIT_NP;
|
||||
return PRIORITY_ARBITRATION_BIT_NP;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper:
|
||||
Wait for GRANTs requested by emulated devices,
|
||||
then raise SACK,
|
||||
then wait for BBSY deasserted.
|
||||
Calling this is only 2*5 ns extra.
|
||||
"grant_mask": all GRANT lines received from physical or emulated CPU.
|
||||
result: 0 if busy, else bitmask with one bit set for GRANTed and SACKEd request.
|
||||
*/
|
||||
static uint8_t sm_arb_worker_device_grant_sack_bbsy(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;
|
||||
if (grant_mask) {
|
||||
// one of our requests was granted:
|
||||
// set SACK
|
||||
// AND simultaneously clear granted requests BR*/NPR
|
||||
// BIT(5): SACK mask and level
|
||||
buslatches_setbits(1, (PRIORITY_ARBITRATION_BIT_MASK & sm_arb.device_request_mask) | BIT(5),
|
||||
~grant_mask | BIT(5))
|
||||
;
|
||||
|
||||
// clear granted requests internally
|
||||
sm_arb.device_request_mask &= ~grant_mask;
|
||||
// UNIBUS DATA section is indepedent: MSYN, SSYN, BBSY may still be active.
|
||||
// -> DMA and INTR statemachine must wait for BBSY.
|
||||
|
||||
// Arbitrator should remove GRANT now. Data section on Bus still BBSY
|
||||
sm_arb.bbsy_wait_grant_mask = grant_mask; // next is State 2: wait for BBSY clear
|
||||
}
|
||||
return 0; // no GRANT for us, or wait for BBSY
|
||||
} else {
|
||||
// State 2: wait for BBSY to clear
|
||||
if (buslatches_getbyte(1) & BIT(6))
|
||||
return 0; // BBSY still set
|
||||
grant_mask = sm_arb.bbsy_wait_grant_mask;
|
||||
sm_arb.bbsy_wait_grant_mask = 0; // Next State is 1
|
||||
|
||||
return grant_mask; // signal what request we got granted.
|
||||
}
|
||||
}
|
||||
|
||||
/* worker_client:
|
||||
Issue request to extern Arbitrator (PDP-11 CPU).
|
||||
Watch for GRANTs on the bus signal lines, then raise SACK.
|
||||
@@ -139,52 +182,25 @@ uint8_t sm_arb_worker_none() {
|
||||
But it guarantees caller may now issue an DMA or INTR.
|
||||
*/
|
||||
uint8_t sm_arb_worker_client() {
|
||||
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.request_mask)
|
||||
buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.device_request_mask)
|
||||
;
|
||||
|
||||
// read GRANT IN lines from CPU (Arbitrator). Only one at a time may be active
|
||||
// read GRANT IN lines from CPU (Arbitrator).
|
||||
// Only one at a time may be active, else arbitrator malfucntion.
|
||||
// Arbitrator asserts SACK is inactive
|
||||
// latch[0]: BG signals are inverted, "get" is non-inverting: bit = active signal.
|
||||
// "set" is inverting!
|
||||
grant_mask = buslatches_getbyte(0) & PRIORITY_ARBITRATION_BIT_MASK; // read GRANT IN
|
||||
uint8_t 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
|
||||
buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK & ~sm_arb.request_mask, ~grant_mask)
|
||||
buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK & ~sm_arb.device_request_mask, ~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.request_mask;
|
||||
if (grant_mask) {
|
||||
// one of our requests was granted:
|
||||
// set SACK
|
||||
// AND simultaneously Clear granted requests BR*/NPR
|
||||
// BIT(5): SACK mask and level
|
||||
buslatches_setbits(1, (PRIORITY_ARBITRATION_BIT_MASK & sm_arb.request_mask) | BIT(5),
|
||||
~grant_mask | BIT(5))
|
||||
;
|
||||
|
||||
// clear granted requests internally
|
||||
sm_arb.request_mask &= ~grant_mask;
|
||||
// Arbitrator should remove GRANT now. Data section on Bus still BBSY
|
||||
sm_arb.bbsy_wait_grant_mask = grant_mask; // next is State 2: wait for BBSY clear
|
||||
}
|
||||
return 0; // no GRANT for us, or wait for BBSY
|
||||
} else {
|
||||
// wait for BBSY to clear
|
||||
if (buslatches_getbyte(1) & BIT(6))
|
||||
return 0; // BBSY still set
|
||||
grant_mask = sm_arb.bbsy_wait_grant_mask;
|
||||
sm_arb.bbsy_wait_grant_mask = 0; // Next State is 1
|
||||
|
||||
return grant_mask; // signal what request we got granted.
|
||||
}
|
||||
// UNIBUS DATA section is indepedent: MSYN, SSYN, BBSY may still be active.
|
||||
// -> DMA and INTR statemachine must wait for BBSY.
|
||||
// GRANT forwarding complete,
|
||||
// handle GRANT/SACK/BBSY for emulated devices
|
||||
return sm_arb_worker_device_grant_sack_bbsy(grant_mask);
|
||||
}
|
||||
|
||||
/* "worker_master"
|
||||
@@ -198,28 +214,38 @@ uint8_t sm_arb_worker_client() {
|
||||
- GRANT BR* in descending priority, when CPU execution level allows .
|
||||
- Cancel GRANT, if no device responds with SACK within timeout period
|
||||
*/
|
||||
|
||||
#if 0
|
||||
// decode set of requests lines to highest INTR level
|
||||
// BR4 = 0x01 -> 4, BR5 = 0x02 -> 5, etc.
|
||||
// Index only PRIORITY_ARBITRATION_INTR_MASK, [0] invalid.
|
||||
static const uint8_t requests_2_highests_intr[16] = { //
|
||||
static uint8_t requests_2_highests_intr[16] = { //
|
||||
/*0000*/9, /*0001*/4, /*0010*/5, /*0011*/5,
|
||||
/*0100*/6, /*0101*/6, /*0110*/6, /*0111*/6,
|
||||
/*1000*/7, /*1001*/7, /*1010*/7, /*0011*/7,
|
||||
/*1100*/7, /*1101*/7, /*1110*/7, /*0111*/7 };
|
||||
/*1000*/7, /*1001*/7, /*1010*/7, /*1011*/7,
|
||||
/*1100*/7, /*1101*/7, /*1110*/7, /*1111*/7 };
|
||||
#endif
|
||||
|
||||
uint8_t sm_arb_worker_master() {
|
||||
/******* arbitrator logic *********/
|
||||
uint8_t intr_request_mask;
|
||||
uint8_t latch1val = buslatches_getbyte(1);
|
||||
|
||||
// monitor BBSY
|
||||
if (!(latch1val & BIT(5)) && !(latch1val & BIT(6))) {
|
||||
// neither SACK nor BBSY: bus is not used by device.
|
||||
// exclude "SACK and NOT BBSY": device has not yet raised BBSY
|
||||
mailbox.arbitrator.device_BBSY = false ;
|
||||
}
|
||||
|
||||
|
||||
if (latch1val & BIT(5)) {
|
||||
// SACK set by a device
|
||||
// priority arbitration disabled, remove GRANT.
|
||||
sm_arb.arbitrator_grant_mask = 0;
|
||||
|
||||
// CPU looses now access to UNIBUS after current cycle
|
||||
mailbox.arbitrator.device_BBSY = 1; // DATA section used by device now
|
||||
mailbox.arbitrator.device_BBSY = true; // DATA section used by device now
|
||||
//NONO: BBSY ! No SACK for parts of DMA cycle .
|
||||
|
||||
timeout_cleanup(TIMEOUT_SACK);
|
||||
} else if (latch1val & PRIORITY_ARBITRATION_BIT_NP) {
|
||||
@@ -229,76 +255,52 @@ uint8_t sm_arb_worker_master() {
|
||||
sm_arb.arbitrator_grant_mask = PRIORITY_ARBITRATION_BIT_NP;
|
||||
timeout_set(TIMEOUT_SACK, MILLISECS(ARB_MASTER_SACK_TIMOUT_MS));
|
||||
}
|
||||
} else if ((intr_request_mask = latch1val & PRIORITY_ARBITRATION_INTR_MASK)) {
|
||||
} else if ((intr_request_mask = (latch1val & PRIORITY_ARBITRATION_INTR_MASK))) {
|
||||
// device BR4,BR5,BR6 or BR7
|
||||
if (sm_arb.arbitrator_grant_mask == 0) {
|
||||
// no 2nd device's request may modify GRANT before 1st device acks with SACK
|
||||
// GRANT request depending on CPU priority level
|
||||
// find highest request line
|
||||
uint8_t requested_intr_level = requests_2_highests_intr[intr_request_mask];
|
||||
|
||||
// find level # of highest request in bitmask
|
||||
// lmbd() = LeftMostBitDetect(0x01)-> 0 (0x03) -> 1, (0x07) -> 2, 0x0f -> 3
|
||||
// BR4 = 0x01 -> 4, BR5 = 0x02 -> 5, etc.
|
||||
uint8_t requested_intr_level = __lmbd(intr_request_mask,1) + 4 ;
|
||||
// compare against cpu run level 4..7
|
||||
// but do not GRANT anything if emulated CPU did not fetch new PSW yet,
|
||||
// then cpu_priority_level is invalid
|
||||
if (requested_intr_level > mailbox.arbitrator.cpu_priority_level
|
||||
&& requested_intr_level != CPU_PRIORITY_LEVEL_FETCHING) {
|
||||
if (requested_intr_level > mailbox.arbitrator.cpu_priority_level //
|
||||
&& requested_intr_level != CPU_PRIORITY_LEVEL_FETCHING) {
|
||||
// GRANT request, set GRANT line:
|
||||
// BG4 is signal bit maskl 0x01, etc ...
|
||||
// BG4 is signal bit mask 0x01, 0x02, etc ...
|
||||
//requested_intr_level = 4 ;
|
||||
sm_arb.arbitrator_grant_mask = BIT(requested_intr_level - 4);
|
||||
// 320 ns ???
|
||||
timeout_set(TIMEOUT_SACK, MILLISECS(ARB_MASTER_SACK_TIMOUT_MS));
|
||||
}
|
||||
}
|
||||
} else if (sm_arb.arbitrator_grant_mask && timeout_reached(TIMEOUT_SACK)) {
|
||||
// no SACK, no requests, but GRANTs: SACK timeout?
|
||||
sm_arb.arbitrator_grant_mask = 0;
|
||||
mailbox.arbitrator.device_BBSY = 0; // started by SACK, but UNIBUS DATA section not used by device
|
||||
mailbox.arbitrator.device_BBSY = false; // started by SACK, but UNIBUS DATA section not used by device
|
||||
timeout_cleanup(TIMEOUT_SACK);
|
||||
}
|
||||
// put the single BR/NPR GRANT onto BUS lines. BGOUT inverted.
|
||||
buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK, ~sm_arb.arbitrator_grant_mask ) ;
|
||||
|
||||
|
||||
/***** client device logic *****/
|
||||
|
||||
// Always update UNIBUS BR/NPR lines, are ORed with requests from other devices.
|
||||
buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.request_mask)
|
||||
buslatches_setbits(1, PRIORITY_ARBITRATION_BIT_MASK, sm_arb.device_request_mask)
|
||||
;
|
||||
|
||||
// read GRANT IN lines from CPU (Arbitrator). Only one at a time may be active
|
||||
// Arbitrator asserts SACK is inactive
|
||||
uint8_t grant_mask = sm_arb.arbitrator_grant_mask;
|
||||
// forward GRANTs not requested by UniBone devices to other cards on neighbor slots
|
||||
buslatches_setbits(0, PRIORITY_ARBITRATION_BIT_MASK & ~sm_arb.request_mask, ~grant_mask)
|
||||
;
|
||||
// Do not forward GRANT IN to GRANT OUT: we, the arbitrator, do not have GRANT IN.
|
||||
|
||||
// GRANTs for UniBone internal devices are not visible on UNIBUS
|
||||
// (emualted GRANT OUT - GRANT IN connections)
|
||||
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.request_mask;
|
||||
if (grant_mask) {
|
||||
// one of our requests was granted:
|
||||
// set SACK
|
||||
// AND simultaneously Clear granted requests BR*/NPR
|
||||
// BIT(5): SACK mask and level
|
||||
buslatches_setbits(1, (PRIORITY_ARBITRATION_BIT_MASK & sm_arb.request_mask) | BIT(5),
|
||||
~grant_mask | BIT(5))
|
||||
;
|
||||
|
||||
// clear granted requests internally
|
||||
sm_arb.request_mask &= ~grant_mask;
|
||||
// Arbitrator should remove GRANT now. Data section on Bus still BBSY
|
||||
sm_arb.bbsy_wait_grant_mask = grant_mask; // next is State 2: wait for BBSY clear
|
||||
}
|
||||
return 0; // no GRANT for us, or wait for BBSY
|
||||
} else {
|
||||
// wait for BBSY to clear
|
||||
if (buslatches_getbyte(1) & BIT(6))
|
||||
return 0; // BBSY still set
|
||||
grant_mask = sm_arb.bbsy_wait_grant_mask;
|
||||
sm_arb.bbsy_wait_grant_mask = 0; // Next State is 1
|
||||
|
||||
return grant_mask; // signal what request we got granted.
|
||||
}
|
||||
// UNIBUS DATA section is indepedent: MSYN, SSYN, BBSY may still be active.
|
||||
// -> DMA and INTR statemachine must wait for BBSY.
|
||||
// Arbitration master stuff complete,
|
||||
// handle GRANT/SACK/BBSY for emulated devices
|
||||
return sm_arb_worker_device_grant_sack_bbsy(sm_arb.arbitrator_grant_mask);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ typedef struct {
|
||||
// There are 5 request/grant signals (BR4,5,6,7 and NPR).
|
||||
// These are encoded as bitmask fitting the buslatch[0] or[1]
|
||||
// BR/NPR lines = set of _PRIORITY_ARBITRATION_BIT_*
|
||||
uint8_t request_mask;
|
||||
uint8_t device_request_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
|
||||
@@ -53,7 +53,7 @@ typedef struct {
|
||||
// only used wif working as Arbitrator/Interupt Fielding Processor
|
||||
uint8_t ifs_priority_level; // priority level of Interrupt Fielding processor (CPU)
|
||||
|
||||
uint8_t arbitrator_grant_mask; // GRANT line set by master
|
||||
uint8_t arbitrator_grant_mask; // single GRANT line set by master
|
||||
|
||||
} statemachine_arbitration_t;
|
||||
|
||||
|
||||
@@ -83,6 +83,10 @@ statemachine_state_func sm_data_slave_start() {
|
||||
// addr8..15 = latch[3]
|
||||
// addr 16,17 = latch[4].0,1
|
||||
addr = latch2val | ((uint32_t) latch3val << 8) | ((uint32_t) (latch4val & 3) << 16);
|
||||
//if (addr == 0777546) // LTC
|
||||
// PRU_DEBUG_PIN0(1) ; // trigger to LA.
|
||||
|
||||
|
||||
|
||||
// make bool of a17..a13. iopage, if a17..a13 all 1's
|
||||
// iopage = ((latch3val & 0xe0) | (latch4val & 3)) == 0xe3;
|
||||
|
||||
@@ -333,7 +333,7 @@ static statemachine_state_func sm_dma_state_99() {
|
||||
|
||||
// device or cpu cycle ended: now CPU may become UNIBUS master again
|
||||
mailbox.events.dma.cpu_transfer = mailbox.arbitrator.cpu_BBSY ;
|
||||
mailbox.arbitrator.device_BBSY = false;
|
||||
// device_BBSY monitored by sm_arbitration (physical devices).
|
||||
mailbox.arbitrator.cpu_BBSY = false;
|
||||
|
||||
// SACK already de-asserted at wordcount==1
|
||||
|
||||
@@ -98,7 +98,7 @@ static statemachine_state_func sm_intr_master_state_2() {
|
||||
// deassert BBSY
|
||||
buslatches_setbits(1, BIT(6), 0);
|
||||
// device cycle ended: now CPU may become UNIBUS master again
|
||||
mailbox.arbitrator.device_BBSY = false ;
|
||||
// device_BBSY monitored by sm_arbitration (physical devices).
|
||||
|
||||
// SACK already removed
|
||||
|
||||
|
||||
@@ -47,11 +47,11 @@ statemachine_intr_slave_t sm_intr_slave;
|
||||
// forwards
|
||||
static statemachine_state_func sm_intr_slave_state_1(void);
|
||||
|
||||
// Wait for BBSY deasserted, then assert, SACK already held asserted
|
||||
// WAIT for INTR.
|
||||
// Master holds BBSY and SACK
|
||||
statemachine_state_func sm_intr_slave_start() {
|
||||
// WAIT for INTR
|
||||
if ((buslatches_getbyte(7) & BIT(0)) == 0)
|
||||
return NULL ; // still idle
|
||||
return NULL ; // INTR still deasserted
|
||||
// device has put vector onto DATA lines, fetch after 150ns
|
||||
__delay_cycles(NANOSECS(150));
|
||||
uint8_t latch5val = buslatches_getbyte(5) ;// DATA[0..7] = latch[5]
|
||||
@@ -65,7 +65,11 @@ statemachine_state_func sm_intr_slave_start() {
|
||||
|
||||
// signal ARM, wait for event to be processed
|
||||
mailbox.events.intr_slave.vector = (uint16_t) latch6val << 8 | latch5val ;
|
||||
|
||||
EVENT_SIGNAL(mailbox,intr_slave) ; // signal to ARM
|
||||
|
||||
PRU2ARM_INTERRUPT ;
|
||||
PRU_DEBUG_PIN0(1);
|
||||
// wait until ARM acked
|
||||
return (statemachine_state_func) &sm_intr_slave_state_1;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ void do_event_initializationsignals() {
|
||||
uint8_t bus_cur = buslatches_getbyte(7) & 0x38; // now sampled
|
||||
|
||||
if (bus_cur & INITIALIZATIONSIGNAL_INIT) {
|
||||
sm_arb.request_mask = 0 ; // INIT clears all PRIORITY request signals
|
||||
sm_arb.device_request_mask = 0 ; // INIT clears all PRIORITY request signals
|
||||
// SACK cleared later on end of INTR/DMA transaction
|
||||
}
|
||||
|
||||
|
||||
@@ -123,9 +123,9 @@ typedef struct {
|
||||
|
||||
// data for bus arbitrator
|
||||
typedef struct {
|
||||
// arbitrator.device_BBSY indicates a device wants or has acquired the UNIBUS
|
||||
// cpu DATA transfer must be delayed until == 00
|
||||
// set by arbitration logic
|
||||
// arbitrator.device_BBSY indicates a device wants or has acquired the UNIBUS.
|
||||
// cpu DATA transfer must be delayed until device_BBSY == 0
|
||||
// set when arbitration logic detects SACK!
|
||||
uint8_t device_BBSY;
|
||||
|
||||
// Command by ARM on DMA start: DATA transfer as CPU, else as device
|
||||
|
||||
@@ -106,8 +106,10 @@ void cpu_c::worker(unsigned instance) {
|
||||
if (runmode.value != (ka11.state != 0))
|
||||
ka11.state = runmode.value;
|
||||
ka11_condstep(&ka11);
|
||||
if (runmode.value != (ka11.state != 0))
|
||||
if (runmode.value != (ka11.state != 0)) {
|
||||
runmode.value = ka11.state != 0;
|
||||
printf("CPU HALT at %06o.\n", ka11.r[7]) ;
|
||||
}
|
||||
|
||||
// serialize asynchronous power events
|
||||
if (runmode.value) {
|
||||
|
||||
Reference in New Issue
Block a user