--- tme/bus/multibus/sun-mie.c 2018/04/24 16:40:03 1.1 +++ tme/bus/multibus/sun-mie.c 2018/04/24 16:45:16 1.1.1.4 @@ -1,4 +1,4 @@ -/* $Id: sun-mie.c,v 1.1 2018/04/24 16:40:03 root Exp $ */ +/* $Id: sun-mie.c,v 1.1.1.4 2018/04/24 16:45:16 root Exp $ */ /* bus/multibus/sun_mie.c - implementation of the Sun Intel Ethernet Multibus emulation: */ @@ -34,7 +34,7 @@ */ #include -_TME_RCSID("$Id: sun-mie.c,v 1.1 2018/04/24 16:40:03 root Exp $"); +_TME_RCSID("$Id: sun-mie.c,v 1.1.1.4 2018/04/24 16:45:16 root Exp $"); /* includes: */ #include @@ -158,6 +158,10 @@ struct tme_sun_mie { /* the callout flags: */ int tme_sun_mie_callout_flags; + int tme_sun_mie_ca_callout_delay; + int tme_sun_mie_ca_callout_pending; + int tme_sun_mie_pending_deassert_intr; + /* if our interrupt line is currently asserted: */ int tme_sun_mie_int_asserted; @@ -168,7 +172,7 @@ struct tme_sun_mie { tme_uint8_t tme_sun_mie_memory[TME_SUN_MIE_MEMSIZE]; /* the active TLB entries for each page map entry on the board: */ - struct tme_bus_tlb *tme_sun_mie_tlbs[TME_SUN_MIE_PGMAP_COUNT * TME_SUN_MIE_PGMAP_TLBS]; + struct tme_token *tme_sun_mie_tlb_tokens[TME_SUN_MIE_PGMAP_COUNT * TME_SUN_MIE_PGMAP_TLBS]; unsigned int tme_sun_mie_tlb_head[TME_SUN_MIE_PGMAP_COUNT]; /* the i825x6 image of the CSR: */ @@ -200,6 +204,8 @@ struct tme_sun_mie_connection { static const struct tme_bus_signals _tme_sun_mie_bus_signals_generic = TME_BUS_SIGNALS_GENERIC; static const struct tme_bus_signals _tme_sun_mie_bus_signals_i825x6 = TME_BUS_SIGNALS_I825X6; +extern int printf(const char *format, ...); + /* the sun_mie callout function. it must be called with the mutex locked: */ static void _tme_sun_mie_callout(struct tme_sun_mie *sun_mie, int new_callouts) @@ -286,6 +292,12 @@ _tme_sun_mie_callout(struct tme_sun_mie /* unlock the mutex: */ tme_mutex_unlock(&sun_mie->tme_sun_mie_mutex); +#if 1 + printf("callout conn_i825x6->tme_bus_signal; signal %x, level %x; %x\n", + (int)signal, (int)level, (int)(signal | level)); +#endif + +if (signal) /* do the callout: */ rc = (conn_i825x6 != NULL ? ((*conn_i825x6->tme_bus_signal) @@ -355,6 +367,9 @@ _tme_sun_mie_callout(struct tme_sun_mie /* if this callout was successful, note the new state of the interrupt signal: */ if (rc == TME_OK) { +#if 1 + printf("IE assert int %x, csr %x\n", (int)int_asserted, (int)csr); +#endif sun_mie->tme_sun_mie_int_asserted = int_asserted; } @@ -404,6 +419,15 @@ _tme_sun_mie_bus_cycle_regs(void *_sun_m tme_uint16_t pcr_old, pcr_new, pcr_diff; int new_callouts; +#if 1 + printf("mie_bus_cycle_regs; type %x, addr %x, size %d, %02x %02x\n", + (int)cycle_init->tme_bus_cycle_type, + (int)cycle_init->tme_bus_cycle_address, + (int)cycle_init->tme_bus_cycle_size, + (int)cycle_init->tme_bus_cycle_buffer[0], + (int)cycle_init->tme_bus_cycle_buffer[1]); +#endif + /* recover our data structure: */ sun_mie = (struct tme_sun_mie *) _sun_mie; @@ -442,9 +466,9 @@ _tme_sun_mie_bus_cycle_regs(void *_sun_m /* invalidate the TLB entries: */ for (; tlb_i < tlb_j; tlb_i++) { - if (sun_mie->tme_sun_mie_tlbs[tlb_i] != NULL) { - tme_bus_tlb_invalidate(sun_mie->tme_sun_mie_tlbs[tlb_i]); - sun_mie->tme_sun_mie_tlbs[tlb_i] = NULL; + if (sun_mie->tme_sun_mie_tlb_tokens[tlb_i] != NULL) { + tme_token_invalidate(sun_mie->tme_sun_mie_tlb_tokens[tlb_i]); + sun_mie->tme_sun_mie_tlb_tokens[tlb_i] = NULL; } } } @@ -470,6 +494,10 @@ _tme_sun_mie_bus_cycle_regs(void *_sun_m & ~TME_SUN_MIE_CSR_READONLY) | (csr_old & TME_SUN_MIE_CSR_READONLY)); +#if 1 + printf("csr_new %x, csr_old %x, csr %x\n", + (int)csr_new, (int)csr_old, (int)TME_SUN_MIE_CSR_GET(sun_mie)); +#endif TME_SUN_MIE_CSR_PUT(sun_mie, csr_new); pcr_new = ((TME_SUN_MIE_PCR_GET(sun_mie) & ~TME_SUN_MIE_PCR_READONLY) @@ -505,6 +533,11 @@ _tme_sun_mie_bus_cycle_regs(void *_sun_m /* nothing to do */ } +#if 1 + printf("IE now csr %x, tme_sun_mie_int_asserted %x\n", + (int)csr_new, (int)sun_mie->tme_sun_mie_int_asserted); +#endif + #ifndef TME_NO_LOG if (csr_new != sun_mie->tme_sun_mie_last_log_csr) { sun_mie->tme_sun_mie_last_log_csr = csr_new; @@ -516,6 +549,16 @@ _tme_sun_mie_bus_cycle_regs(void *_sun_m } #endif /* !TME_NO_LOG */ +#if 1 + if (cycle_init->tme_bus_cycle_type & TME_BUS_CYCLE_WRITE) + if (sun_mie->tme_sun_mie_pending_deassert_intr) { + sun_mie->tme_sun_mie_pending_deassert_intr = 0; + printf("turning off pending intr\n"); + csr_new &= ~TME_SUN_MIE_CSR_INTR; + TME_SUN_MIE_CSR_PUT(sun_mie, csr_new); + } +#endif + /* make any new callouts: */ _tme_sun_mie_callout(sun_mie, new_callouts); @@ -533,6 +576,13 @@ _tme_sun_mie_bus_signal(struct tme_bus_c { struct tme_sun_mie *sun_mie; +#if 1 + printf("_tme_sun_mie_bus_signal() %x, index %d, count %d\n", + (int)signal, + (int)TME_BUS_SIGNAL_INDEX(signal), + (int)_tme_sun_mie_bus_signals_generic.tme_bus_signals_count); +#endif + /* return now if this is not a generic bus signal: */ if (TME_BUS_SIGNAL_INDEX(signal) > _tme_sun_mie_bus_signals_generic.tme_bus_signals_count) { @@ -542,6 +592,32 @@ _tme_sun_mie_bus_signal(struct tme_bus_c /* recover our data structures: */ sun_mie = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private; +#if 1 + printf("_tme_sun_mie_bus_signal() doing it %x\n", (int)signal); +#endif + +#if 1 +if (TME_BUS_SIGNAL_WHICH(signal) == TME_BUS_SIGNAL_INT_UNSPEC) +{ + tme_uint16_t csr; + unsigned int level; + csr = TME_SUN_MIE_CSR_GET(sun_mie); + level = signal & TME_BUS_SIGNAL_LEVEL_MASK; + + if (level == TME_BUS_SIGNAL_LEVEL_ASSERTED) { + printf("assert csr intr!\n"); + csr |= TME_SUN_MIE_CSR_INTR; + TME_SUN_MIE_CSR_PUT(sun_mie, csr); + } + if (level == TME_BUS_SIGNAL_LEVEL_NEGATED) { + printf("deassert csr intr!\n"); +// csr &= ~TME_SUN_MIE_CSR_INTR; +// TME_SUN_MIE_CSR_PUT(sun_mie, csr); + sun_mie->tme_sun_mie_pending_deassert_intr = 1; + } +} +#endif + /* since this function is currently only given to the i825x6, just copy its signal through to the Multibus: */ conn_bus = sun_mie->tme_sun_mie_conn_regs; @@ -577,25 +653,20 @@ _tme_sun_mie_bus_signals_add(struct tme_ return (TME_OK); } -/* the sun_mie TLB allocator for the i825x6: */ +/* the sun_mie TLB adder for the i825x6: */ static int -_tme_sun_mie_tlb_set_allocate(struct tme_bus_connection *conn_bus, - unsigned int count, unsigned int sizeof_one, - TME_ATOMIC_POINTER_TYPE(struct tme_bus_tlb *) _tlbs) +_tme_sun_mie_tlb_set_add(struct tme_bus_connection *conn_bus, + struct tme_bus_tlb_set_info *tlb_set_info) { - struct tme_bus_tlb *tlbs, *tlb; - unsigned int tlb_i; - /* allocate a singleton set: */ - tlbs = (struct tme_bus_tlb *) tme_malloc(count * sizeof_one); - tlb = tlbs; - for (tlb_i = 0; tlb_i < count; tlb_i++) { - tme_bus_tlb_invalidate(tlb); - tlb = (struct tme_bus_tlb *) (((tme_uint8_t *) tlb) + sizeof_one); + /* if this TLB set provides a bus context register: */ + if (tlb_set_info->tme_bus_tlb_set_info_bus_context != NULL) { + + /* this bus only has one context: */ + (*tlb_set_info->tme_bus_tlb_set_info_bus_context) = 0; + tlb_set_info->tme_bus_tlb_set_info_bus_context_max = 0; } - TME_ATOMIC_WRITE(struct tme_bus_tlb *, *_tlbs, tlbs); - - /* done: */ + return (TME_OK); } @@ -603,10 +674,11 @@ _tme_sun_mie_tlb_set_allocate(struct tme static int _tme_sun_mie_tlb_fill(struct tme_bus_connection *conn_bus, struct tme_bus_tlb *tlb, - tme_bus_addr_t address, + tme_bus_addr_t address_wider, unsigned int cycles) { struct tme_sun_mie *sun_mie; + tme_bus_addr32_t address; unsigned int pgmap_i; unsigned int tlb_i; tme_uint16_t pgmap; @@ -614,6 +686,10 @@ _tme_sun_mie_tlb_fill(struct tme_bus_con /* recover our data structures: */ sun_mie = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private; + /* get the normal-width address: */ + address = address_wider; + assert (address == address_wider); + /* the address must be within range: */ assert(address <= 0xffffff); @@ -638,18 +714,17 @@ _tme_sun_mie_tlb_fill(struct tme_bus_con /* if the new head pointer already has a TLB entry, and it doesn't happen to be the same one that we're filling now, invalidate it: */ - if (sun_mie->tme_sun_mie_tlbs[tlb_i] != NULL - && sun_mie->tme_sun_mie_tlbs[tlb_i] != TME_ATOMIC_READ(struct tme_bus_tlb *, - tlb->tme_bus_tlb_backing_reservation)) { - tme_bus_tlb_invalidate(sun_mie->tme_sun_mie_tlbs[tlb_i]); + if (sun_mie->tme_sun_mie_tlb_tokens[tlb_i] != NULL + && sun_mie->tme_sun_mie_tlb_tokens[tlb_i] != tlb->tme_bus_tlb_token) { + tme_token_invalidate(sun_mie->tme_sun_mie_tlb_tokens[tlb_i]); } /* initialize the TLB entry: */ tme_bus_tlb_initialize(tlb); /* this TLB entry covers this range: */ - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_first, address); - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_last, address | (TME_SUN_MIE_PAGESIZE - 1)); + tlb->tme_bus_tlb_addr_first = address; + tlb->tme_bus_tlb_addr_last = address | (TME_SUN_MIE_PAGESIZE - 1); /* allow reading and writing: */ tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE; @@ -666,10 +741,16 @@ _tme_sun_mie_tlb_fill(struct tme_bus_con tlb->tme_bus_tlb_emulator_off_read = tlb->tme_bus_tlb_emulator_off_write; +#if 1 + printf("_tme_sun_mie_tlb_fill() tlb first %08x, last %08x, off_write %08x\n", + (int)tlb->tme_bus_tlb_addr_first, + (int)tlb->tme_bus_tlb_addr_last, + (int)tlb->tme_bus_tlb_emulator_off_write); +#endif + /* add this TLB entry to the active list: */ - sun_mie->tme_sun_mie_tlbs[tlb_i] = - TME_ATOMIC_READ(struct tme_bus_tlb *, - tlb->tme_bus_tlb_backing_reservation); + sun_mie->tme_sun_mie_tlb_tokens[tlb_i] = + tlb->tme_bus_tlb_token; /* unlock our mutex: */ tme_mutex_unlock(&sun_mie->tme_sun_mie_mutex); @@ -681,13 +762,19 @@ _tme_sun_mie_tlb_fill(struct tme_bus_con static int _tme_sun_mie_tlb_fill_regs(struct tme_bus_connection *conn_bus, struct tme_bus_tlb *tlb, - tme_bus_addr_t address, unsigned int cycles) + tme_bus_addr_t address_wider, + unsigned int cycles) { struct tme_sun_mie *sun_mie; + tme_bus_addr32_t address; /* recover our data structures: */ sun_mie = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private; + /* get the normal-width address: */ + address = address_wider; + assert (address == address_wider); + /* the address must be within range: */ assert(address < TME_SUN_MIE_SIZ_REGS); @@ -700,10 +787,8 @@ _tme_sun_mie_tlb_fill_regs(struct tme_bu + TME_SUN_MIE_SIZ_PGMAP)) { /* this TLB entry covers this range: */ - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_first, TME_SUN_MIE_REG_PGMAP); - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_last, (TME_SUN_MIE_REG_PGMAP - + TME_SUN_MIE_SIZ_PGMAP - - 1)); + tlb->tme_bus_tlb_addr_first = TME_SUN_MIE_REG_PGMAP; + tlb->tme_bus_tlb_addr_last = (TME_SUN_MIE_REG_PGMAP + TME_SUN_MIE_SIZ_PGMAP - 1); } /* if this address falls in the PROM: */ @@ -713,10 +798,8 @@ _tme_sun_mie_tlb_fill_regs(struct tme_bu /* this TLB entry covers this range: */ - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_first, TME_SUN_MIE_REG_PROM); - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_last, (TME_SUN_MIE_REG_PROM - + TME_SUN_MIE_SIZ_PROM - - 1)); + tlb->tme_bus_tlb_addr_first = TME_SUN_MIE_REG_PROM; + tlb->tme_bus_tlb_addr_last = TME_SUN_MIE_REG_PROM + TME_SUN_MIE_SIZ_PROM - 1; } /* if this address falls in the CSR: */ @@ -726,10 +809,8 @@ _tme_sun_mie_tlb_fill_regs(struct tme_bu /* this TLB entry covers this range: */ - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_first, TME_SUN_MIE_REG_CSR); - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_last, (TME_SUN_MIE_REG_CSR - + TME_SUN_MIE_SIZ_CSR - - 1)); + tlb->tme_bus_tlb_addr_first = TME_SUN_MIE_REG_CSR; + tlb->tme_bus_tlb_addr_last = TME_SUN_MIE_REG_CSR + TME_SUN_MIE_SIZ_CSR - 1; } /* otherwise, this address must fall in the unused hole or in the @@ -739,17 +820,20 @@ _tme_sun_mie_tlb_fill_regs(struct tme_bu + TME_SUN_MIE_SIZ_CSR)); /* this TLB entry covers this range: */ - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_first, (TME_SUN_MIE_REG_CSR - + TME_SUN_MIE_SIZ_CSR)); - TME_ATOMIC_WRITE(tme_bus_addr_t, tlb->tme_bus_tlb_addr_last, (TME_SUN_MIE_REG_PE_ALO - + TME_SUN_MIE_SIZ_PE_ALO - - 1)); + tlb->tme_bus_tlb_addr_first = (TME_SUN_MIE_REG_CSR + TME_SUN_MIE_SIZ_CSR); + tlb->tme_bus_tlb_addr_last = (TME_SUN_MIE_REG_PE_ALO + TME_SUN_MIE_SIZ_PE_ALO - 1); } /* all address ranges allow fast reading: */ tlb->tme_bus_tlb_emulator_off_read = &sun_mie->tme_sun_mie_regs[0]; tlb->tme_bus_tlb_rwlock = &sun_mie->tme_sun_mie_rwlock; +#if 0 + /* XXX when debugging, nothing is fast readable or writable: */ + tlb->tme_bus_tlb_emulator_off_read = TME_EMULATOR_OFF_UNDEF; + tlb->tme_bus_tlb_emulator_off_write = TME_EMULATOR_OFF_UNDEF; +#endif + /* allow reading and writing: */ tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE; @@ -966,7 +1050,7 @@ _tme_sun_mie_connections_new(struct tme_ conn_bus->tme_bus_subregions.tme_bus_subregion_address_last = 0xffffff; conn_bus->tme_bus_signals_add = _tme_sun_mie_bus_signals_add; conn_bus->tme_bus_signal = _tme_sun_mie_bus_signal; - conn_bus->tme_bus_tlb_set_allocate = _tme_sun_mie_tlb_set_allocate; + conn_bus->tme_bus_tlb_set_add = _tme_sun_mie_tlb_set_add; conn_bus->tme_bus_tlb_fill = _tme_sun_mie_tlb_fill; } else if (regs) {