mirror of
https://github.com/livingcomputermuseum/UniBone.git
synced 2026-04-28 04:46:19 +00:00
Cleanup incomplete commits
This commit is contained in:
@@ -204,7 +204,7 @@ bool memoryimage_c::load_addr_value_text(const char *fname) {
|
||||
|
||||
fin = fopen(fname, "r");
|
||||
if (!fin) {
|
||||
printf("%s\n", fileErrorText("Error opening file %s for write", fname)) ;
|
||||
printf("%s\n", fileErrorText("Error opening file %s for write", fname)) ;
|
||||
return false;
|
||||
}
|
||||
entry_address = MEMORY_ADDRESS_INVALID; // not known
|
||||
@@ -538,6 +538,7 @@ bool memoryimage_c::load_papertape(const char *fname) {
|
||||
entry_address = MEMORY_ADDRESS_INVALID; // not yet known
|
||||
|
||||
stream_byte_index = 0;
|
||||
block_byte_size = addr = 0 ; // -Wmaybe-uninitialized
|
||||
while (!feof(fin)) {
|
||||
b = fgetc(fin);
|
||||
// ERROR("[0x%04x] state=%d b=0x%02x sum=0x%02x block_byte_idx=%d",
|
||||
|
||||
@@ -134,6 +134,7 @@ int pru_c::start(enum prucode_enum prucode_id) {
|
||||
// use stop() before restart()
|
||||
assert(this->prucode_id == PRUCODE_NONE);
|
||||
|
||||
|
||||
/* initialize PRU */
|
||||
if ((rtn = prussdrv_init()) != 0) {
|
||||
ERROR("prussdrv_init() failed");
|
||||
@@ -152,6 +153,7 @@ int pru_c::start(enum prucode_enum prucode_id) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
http://credentiality2.blogspot.com/2015/09/beaglebone-pru-ddr-memory-access.html
|
||||
* get pointer to shared DDR
|
||||
@@ -165,6 +167,13 @@ int pru_c::start(enum prucode_enum prucode_id) {
|
||||
ddrmem->base_physical = prussdrv_get_phys_addr((void *) (ddrmem->base_virtual));
|
||||
ddrmem->info(); // may abort program
|
||||
|
||||
// get address of mail box struct in PRU
|
||||
mailbox_connect();
|
||||
// now all mailbox command fields initialized/cleared, PRUs can be started
|
||||
|
||||
// get address of device register descriptor struct in PRU
|
||||
iopageregisters_connect();
|
||||
|
||||
// search code in dictionary
|
||||
struct prucode_entry *pce;
|
||||
for (pce = prucode; pce->id != prucode_id && pce->id != PRUCODE_EOD; pce++)
|
||||
@@ -190,19 +199,20 @@ int pru_c::start(enum prucode_enum prucode_id) {
|
||||
pce->pru1_entry)) != 0) {
|
||||
FATAL("prussdrv_exec_program(PRU1) failed");
|
||||
}
|
||||
INFO("Loaded pru code with id = %d", prucode_id);
|
||||
INFO("Loaded and started PRU code with id = %d", prucode_id);
|
||||
|
||||
timeout.wait_ms(100); // wait for PRU to come up, much too long
|
||||
|
||||
// get address of mail box struct in PRU
|
||||
mailbox_connect();
|
||||
// now all fields initialized/cleared
|
||||
|
||||
// get address of device register descriptor struct in PRU
|
||||
iopageregisters_connect();
|
||||
|
||||
this->prucode_id = prucode_id;
|
||||
|
||||
// verify PRU1 is executing its command loop
|
||||
mailbox->arm2pru_req = ARM2PRU_NOP;
|
||||
timeout.wait_ms(1);
|
||||
if (mailbox->arm2pru_req != ARM2PRU_NONE) {
|
||||
FATAL("PRU1 is not executing its command loop");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
|
||||
error: //
|
||||
|
||||
@@ -157,7 +157,7 @@ void storagedrive_c::file_write(uint8_t *buffer, uint64_t position, unsigned len
|
||||
// 3. write data
|
||||
f.write((const char*) buffer, len);
|
||||
if (f.fail())
|
||||
ERROR("file_write() failure on %s", name);
|
||||
ERROR("file_write() failure on %s", name.value.c_str());
|
||||
f.flush();
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ void storagedrive_selftest_c::block_buffer_fill(unsigned block_number) {
|
||||
assert((block_size % 4) == 0); // whole uint32
|
||||
for (unsigned i = 0; i < block_size / 4; i++) {
|
||||
// i counts dwords in buffer
|
||||
// pattern: global incrementing uint32
|
||||
// pattern: global incrementing uint32
|
||||
uint32_t pattern = i + (block_number * block_size / 4);
|
||||
((uint32_t*) block_buffer)[i] = pattern;
|
||||
}
|
||||
@@ -188,7 +188,7 @@ void storagedrive_selftest_c::block_buffer_check(unsigned block_number) {
|
||||
assert((block_size % 4) == 0); // whole uint32
|
||||
for (unsigned i = 0; i < block_size / 4; i++) {
|
||||
// i counts dwords in buffer
|
||||
// pattern: global incrementing uint32
|
||||
// pattern: global incrementing uint32
|
||||
uint32_t pattern_expected = i + (block_number * block_size / 4);
|
||||
uint32_t pattern_found = ((uint32_t*) block_buffer)[i];
|
||||
if (pattern_expected != pattern_found) {
|
||||
|
||||
@@ -140,7 +140,7 @@ void unibus_c::interrupt(uint8_t priority, uint16_t vector) {
|
||||
bool unibus_c::dma(enum unibus_c::arbitration_mode_enum arbitration_mode, uint8_t control,
|
||||
uint32_t startaddr, unsigned blocksize) {
|
||||
uint64_t dmatime_ns, totaltime_ns;
|
||||
uint8_t dma_opcode;
|
||||
uint8_t dma_opcode = ARBITRATION_MODE_NONE; // inihibit compiler warnings
|
||||
|
||||
// can access bus with DMA when there's a Bus Arbitrator
|
||||
assert(pru->prucode_id == pru_c::PRUCODE_UNIBUS);
|
||||
|
||||
56
10.01_base/2_src/pru0/pru0_main_all.c
Normal file
56
10.01_base/2_src/pru0/pru0_main_all.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* pru0_main.c: endless loop, writes outputs on R30 from mailbox (C solution)
|
||||
|
||||
Copyright (c) 2018, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
from d:\RetroCmp\dec\pdp11\UniBone\91_3rd_party\pru-c-compile\pru-software-support-package\examples\am335x\PRU_gpioToggle\
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pru_cfg.h>
|
||||
#include "resource_table_empty.h"
|
||||
|
||||
#include "pru_pru_mailbox.h"
|
||||
|
||||
volatile register uint32_t __R30;
|
||||
volatile register uint32_t __R31;
|
||||
|
||||
void main(void) {
|
||||
|
||||
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
|
||||
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
|
||||
|
||||
// loop forever
|
||||
void pru0_dataout(void) ;
|
||||
pru0_dataout() ;
|
||||
#ifdef USED
|
||||
// old code using shared RAM mailbox, not reached
|
||||
while(1) {
|
||||
__R30 = pru_pru_mailbox.pru0_r30 ;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
210
10.01_base/2_src/pru1/pru1_main_test.c
Normal file
210
10.01_base/2_src/pru1/pru1_main_test.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/* pru1_main.c: main loop with mailbox cmd interface. Test functions.
|
||||
|
||||
Copyright (c) 2018-2019, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
28-mar-2019 JH split off from "all-function" main
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
Functions to test GPIOs, shared memory and mailbox.
|
||||
Separated from "all-function" main() because of PRU code size limits.
|
||||
Application has to load this into PRU1 depending on system state.
|
||||
|
||||
from d:\RetroCmp\dec\pdp11\UniBone\91_3rd_party\pru-c-compile\pru-software-support-package\examples\am335x\PRU_gpioToggle
|
||||
Test GPIO, shared mem and interrupt
|
||||
a) waits until ARM writes a value to mailbox.arm2pru_req
|
||||
b) ACKs the value in mailbox.arm2pru_resp, clears arm2pru_req
|
||||
c) toggles 1 mio times GPIO, with delay as set by ARM
|
||||
d) signal EVENT0
|
||||
e) goto a
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <pru_cfg.h>
|
||||
#include "resource_table_empty.h"
|
||||
|
||||
#include "pru1_utils.h"
|
||||
|
||||
#include "pru_pru_mailbox.h"
|
||||
#include "mailbox.h"
|
||||
#include "ddrmem.h"
|
||||
#include "iopageregister.h"
|
||||
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_statemachine_arbitration.h"
|
||||
#include "pru1_statemachine_dma.h"
|
||||
#include "pru1_statemachine_intr.h"
|
||||
#include "pru1_statemachine_slave.h"
|
||||
#include "pru1_statemachine_init.h"
|
||||
#include "pru1_statemachine_powercycle.h"
|
||||
|
||||
|
||||
void main(void) {
|
||||
|
||||
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
|
||||
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
|
||||
|
||||
// clear all tables, as backup if ARM fails todo
|
||||
iopageregisters_init();
|
||||
|
||||
buslatches_reset(); // all deasserted
|
||||
|
||||
// init mailbox
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE;
|
||||
mailbox.events.eventmask = 0;
|
||||
mailbox.events.initialization_signals_prev = 0;
|
||||
mailbox.events.initialization_signals_cur = 0;
|
||||
|
||||
while (1) {
|
||||
// display opcode (active for one cycle
|
||||
// __R30 = (mailbox.arm2pru_req & 0xf) << 8;
|
||||
/*
|
||||
mailbox.arm2pru_resp = mailbox.arm2pru_req ;
|
||||
__R30 = (mailbox.arm2pru_resp & 0xf) << 8;
|
||||
mailbox.arm2pru_resp = mailbox.arm2pru_req ;
|
||||
}
|
||||
*/
|
||||
/*** Attention: arm2pru_req (and all mailbox vars) change at ANY TIME
|
||||
* - ARM must set arm2pru_req as last operation on mailbox,
|
||||
* memory barrier needed.
|
||||
* - ARM may not access mailbox until arm2pru_req is 0
|
||||
* - PRU only clears arm2pru_req after actual processing if mailbox
|
||||
* ***/
|
||||
switch (mailbox.arm2pru_req) {
|
||||
case ARM2PRU_NONE: // == 0
|
||||
// reloop
|
||||
break;
|
||||
case ARM2PRU_NOP: // needed to probe PRU run state
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_HALT:
|
||||
__halt(); // that's it
|
||||
break;
|
||||
#ifdef USED
|
||||
case ARM2PRU_MAILBOXTEST1:
|
||||
// simulate a register read access.
|
||||
#ifdef TEST_TIMEOUT
|
||||
while (1) {
|
||||
// toggle with REGSEL_0 = PRU1_8
|
||||
__R30 |= (1 << 8);
|
||||
// buslatches_setbits(1, BIT(6), BIT(6)) ;
|
||||
TIMEOUT_SET(NANOSECS(1000));// 1 usec / level
|
||||
while (!TIMEOUT_REACHED);
|
||||
__R30 &= ~(1 << 8);
|
||||
//buslatches_setbits(1, BIT(6), 0) ;
|
||||
TIMEOUT_SET(NANOSECS(1000));
|
||||
while (!TIMEOUT_REACHED);
|
||||
}
|
||||
#endif
|
||||
|
||||
// show on REG_DATAOUT
|
||||
buslatches_pru0_dataout(mailbox.mailbox_test.addr);
|
||||
// pru_pru_mailbox.pru0_r30 = mailbox.mailbox_test.addr & 0xff;
|
||||
// __R30 = (mailbox.mailbox_test.addr & 0xf) << 8;
|
||||
mailbox.mailbox_test.val = mailbox.mailbox_test.addr;
|
||||
__R30 = (mailbox.arm2pru_req & 0xf) << 8; // optical ACK
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
#endif
|
||||
case ARM2PRU_BUSLATCH_INIT: // set all mux registers to "neutral"
|
||||
buslatches_reset();
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
|
||||
case ARM2PRU_BUSLATCH_SET: { // set a mux register
|
||||
|
||||
// don't feed "volatile" vars into buslatch_macros !!!
|
||||
uint8_t reg_sel = mailbox.buslatch.addr & 7;
|
||||
uint8_t bitmask = mailbox.buslatch.bitmask;
|
||||
uint8_t val = mailbox.buslatch.val;
|
||||
//buslatches.cur_reg_sel = 0xff; // force new setting of reg_sel
|
||||
if (BUSLATCHES_REG_IS_BYTE(reg_sel))
|
||||
buslatches_setbyte(reg_sel, val);
|
||||
else
|
||||
buslatches_setbits(reg_sel, bitmask, val);
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
}
|
||||
case ARM2PRU_BUSLATCH_GET: {
|
||||
// don't feed "volatile" vars into buslatch_macros !!!
|
||||
uint8_t reg_sel = mailbox.buslatch.addr & 7;
|
||||
// buslatches.cur_reg_sel = 0xff; // force new setting of reg_sel
|
||||
mailbox.buslatch.val = buslatches_getbyte(reg_sel);
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
}
|
||||
case ARM2PRU_BUSLATCH_EXERCISER: // exercise 8 byte accesses to mux registers
|
||||
buslatches_exerciser() ;
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break ;
|
||||
|
||||
case ARM2PRU_BUSLATCH_TEST: {
|
||||
buslatches_test(mailbox.buslatch_test.addr_0_7, mailbox.buslatch_test.addr_8_15,
|
||||
mailbox.buslatch_test.data_0_7, mailbox.buslatch_test.data_8_15);
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
}
|
||||
case ARM2PRU_INITPULSE: // generate a pulse on UNIBUS INIT
|
||||
// INIT: latch[7], bit 3
|
||||
buslatches_setbits(7, BIT(3), BIT(3)); // assert INIT
|
||||
__delay_cycles(MILLISECS(250)); // INIT is 250ms
|
||||
buslatches_setbits(7, BIT(3), 0); // deassert INIT
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
|
||||
case ARM2PRU_POWERCYCLE: // do ACLO/DCLO power cycle
|
||||
buslatches_powercycle();
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_DMA_ARB_NONE:
|
||||
sm_dma_start(); // without NPR/NPG arbitration
|
||||
// simply call current state function, until stopped
|
||||
// parallel the BUS-slave statemachine is triggered
|
||||
// by master logic.
|
||||
while (!sm_dma.state())
|
||||
;
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_DDR_FILL_PATTERN:
|
||||
ddrmem_fill_pattern();
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_DDR_SLAVE_MEMORY:
|
||||
// respond to UNIBUS cycles as slave and
|
||||
// access DDR as UNIBUS memory.
|
||||
|
||||
// only debugging: all signals deasserted
|
||||
buslatches_reset();
|
||||
|
||||
// do UNIBUS slave cycles, until ARM abort this by
|
||||
// writing into mailbox.arm2pru_req
|
||||
while (mailbox.arm2pru_req == ARM2PRU_DDR_SLAVE_MEMORY) {
|
||||
sm_slave_start();
|
||||
// do all states of an access, start when MSYN found.
|
||||
while (!sm_slave.state())
|
||||
;
|
||||
}
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
} // switch
|
||||
} // while
|
||||
}
|
||||
|
||||
209
10.01_base/2_src/pru1/pru1_main_unibus.c
Normal file
209
10.01_base/2_src/pru1/pru1_main_unibus.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/* pru1_main_unibus.c: main loop with mailbox cmd interface. UNIBUS devices with opt. phys. PDP-11 CPU.
|
||||
|
||||
Copyright (c) 2018-2019, Joerg Hoppe
|
||||
j_hoppe@t-online.de, www.retrocmp.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOERG HOPPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
28-mar-2019 JH split off from "all-function" main
|
||||
12-nov-2018 JH entered beta phase
|
||||
|
||||
Master and slave functionality for UNIBUS devices.
|
||||
Assumes a physical PDP-11 CPU is working as Arbitrator for
|
||||
NPR/NG/SACK and BR/BG/SACK.
|
||||
Needed if UniBone runs in a system running PDP-11 CPU
|
||||
and simulated or physical devices do DMA or INTR.
|
||||
|
||||
Separated from "all-function" main() because of PRU code size limits.
|
||||
Application has to load this into PRU1 depending on system state.
|
||||
|
||||
from d:\RetroCmp\dec\pdp11\UniBone\91_3rd_party\pru-c-compile\pru-software-support-package\examples\am335x\PRU_gpioToggle
|
||||
Test GPIO, shared mem and interrupt
|
||||
a) waits until ARM writes a value to mailbox.arm2pru_req
|
||||
b) ACKs the value in mailbox.arm2pru_resp, clears arm2pru_req
|
||||
c) toggles 1 mio times GPIO, with delay as set by ARM
|
||||
d) signal EVENT0
|
||||
e) goto a
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <pru_cfg.h>
|
||||
#include "resource_table_empty.h"
|
||||
|
||||
#include "pru1_utils.h"
|
||||
|
||||
#include "pru_pru_mailbox.h"
|
||||
#include "mailbox.h"
|
||||
#include "ddrmem.h"
|
||||
#include "iopageregister.h"
|
||||
|
||||
#include "pru1_buslatches.h"
|
||||
#include "pru1_statemachine_arbitration.h"
|
||||
#include "pru1_statemachine_dma.h"
|
||||
#include "pru1_statemachine_intr.h"
|
||||
#include "pru1_statemachine_slave.h"
|
||||
#include "pru1_statemachine_init.h"
|
||||
#include "pru1_statemachine_powercycle.h"
|
||||
|
||||
void main(void) {
|
||||
|
||||
/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
|
||||
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
|
||||
|
||||
// clear all tables, as backup if ARM fails todo
|
||||
iopageregisters_init();
|
||||
|
||||
buslatches_reset(); // all deasserted, caches cleared
|
||||
|
||||
/* ARM must init mailbox, especially:
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE;
|
||||
mailbox.events.eventmask = 0;
|
||||
mailbox.events.initialization_signals_prev = 0;
|
||||
mailbox.events.initialization_signals_cur = 0;
|
||||
*/
|
||||
|
||||
/* start parallel emulation of all devices,
|
||||
* Process __DMA and _INTR bus master operations
|
||||
*
|
||||
* ! Several state machines (DMA, Powercycle, INIT,) use the same global timeout.
|
||||
* ! Never execute these in parallel !
|
||||
*/
|
||||
// Reset PDP-11 with power-cycle simulation.
|
||||
// Necessary, as until now NPR/NPG/BG/BR/SACK lines were "unconnected"
|
||||
// buslatches_powercycle();
|
||||
// __delay_cycles(MILLISECS(100));
|
||||
// execute 2x, because M9312 boot ROMs need this
|
||||
// __delay_cycles(MILLISECS(250));
|
||||
// buslatches_powercycle();
|
||||
|
||||
// buslatches_pulse_debug ;
|
||||
|
||||
// base operation: accept and execute slave cycles
|
||||
sm_slave_start();
|
||||
|
||||
while (true) {
|
||||
uint32_t arm2pru_req_cached;
|
||||
// do all states of an access, start when MSYN found.
|
||||
|
||||
// slave cycles may trigger events to ARM, which changes "active" registers
|
||||
// and issues interrupts
|
||||
while (!sm_slave.state())
|
||||
; // execute complete slave cycle, then check NPR/INTR
|
||||
|
||||
// update state of init lines
|
||||
// INIT never asserted in the midst of a transaction, bit 3,4,5
|
||||
do_event_initializationsignals();
|
||||
|
||||
// standard operation may be interrupt by other requests
|
||||
arm2pru_req_cached = mailbox.arm2pru_req;
|
||||
switch (arm2pru_req_cached) {
|
||||
case ARM2PRU_NONE:
|
||||
// pass BG[4-7] to next device, state machine "idle"
|
||||
// pass all Arbitration GRANT IN to GRANT OUT for next device.
|
||||
// This is not necessary while INTR or DMA is actiove:
|
||||
// INTR is only 1 cycle, DMA has SACK set all the time, arbitration
|
||||
// prohibited then.
|
||||
sm_arb_state_idle();
|
||||
// do only forward GRANT lines if not INTR is pending,
|
||||
// else our GRANT would be passed too.
|
||||
break; // fast case: only slave operation
|
||||
case ARM2PRU_NOP: // needed to probe PRU run state
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_DMA_ARB_NONE: // ignore SACK condition
|
||||
case ARM2PRU_DMA_ARB_MASTER: // also without arbitration, TODO!
|
||||
sm_dma_start();
|
||||
while (!sm_dma.state())
|
||||
;
|
||||
// a dma cycle into a device register may trigger an interrupt
|
||||
// do not delete that condition
|
||||
if (mailbox.arm2pru_req == arm2pru_req_cached)
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // clear request
|
||||
break;
|
||||
case ARM2PRU_DMA_ARB_CLIENT:
|
||||
// start DMA cycle
|
||||
// can not run parallel with INTR levels
|
||||
sm_arb_start(ARBITRATION_PRIORITY_BIT_NP);
|
||||
while (!sm_arb.state()) {
|
||||
// sm_slave is most time critical, as it must keep track with MSYN/SSYN bus traffic.
|
||||
// so give it more cpu cycles
|
||||
while (!sm_slave.state())
|
||||
;
|
||||
}
|
||||
// now SACK held and BBSY set, slave state machine ended, since BBSY found inactive
|
||||
|
||||
// debug pin reset by bus access
|
||||
//DEBUG_PIN_SET(1) ;
|
||||
sm_dma_start();
|
||||
//DEBUG_PIN_SET(1) ;
|
||||
while (!sm_dma.state())
|
||||
//DEBUG_PIN_SET(1) ;
|
||||
;// execute dma master cycles
|
||||
// a dma cycle into a device register may trigger an interrupt
|
||||
// do not delete that condition
|
||||
if (mailbox.arm2pru_req == arm2pru_req_cached)
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // clear request
|
||||
break;
|
||||
case ARM2PRU_INTR:
|
||||
// start one INTR cycle. May be raised in midst of slave cycle
|
||||
// by ARM, if access to "active" register triggers INTR.
|
||||
// no multiple levels simultaneously allowed, not parallel with DMA !
|
||||
sm_arb_start(mailbox.intr.priority_bit);
|
||||
// wait while INTR is accepted. This may take long time,
|
||||
// if system is at high processor priority (PSW register)
|
||||
while (!sm_arb.state()) {
|
||||
// sm_slave is most time critical, as it must keep track with MSYN/SSYN bus traffic.
|
||||
// so give it more cpu cycles
|
||||
while (!sm_slave.state())
|
||||
;
|
||||
}
|
||||
// now SACK held and BBSY set, slave state machine ended, since BBSY found inactive
|
||||
sm_intr_start();
|
||||
while (!sm_intr.state())
|
||||
; // execute intr cycle as bus master
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // clear request
|
||||
break;
|
||||
case ARM2PRU_INITPULSE: // generate a pulse on UNIBUS INIT
|
||||
// only busmaster may assert INIT. violated here!
|
||||
sm_slave_start();
|
||||
sm_init_start();
|
||||
while (!sm_slave.state() || !sm_init.state())
|
||||
;
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
case ARM2PRU_POWERCYCLE: // do ACLO/DCLO power cycle
|
||||
// Runs for 4* POWERCYCLE_DELAY_MS millsecs, approx 1 sec.
|
||||
// perform slave states in parallel, so emulated memory
|
||||
// is existent for power fail trap and reboot
|
||||
sm_slave_start();
|
||||
sm_powercycle_start();
|
||||
while (!sm_slave.state() || !sm_powercycle.state())
|
||||
;
|
||||
mailbox.arm2pru_req = ARM2PRU_NONE; // ACK: done
|
||||
break;
|
||||
|
||||
default: // ignore all other requestes while executing emulation
|
||||
;
|
||||
} // switch
|
||||
} // while (true)
|
||||
|
||||
// never reached
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user