* interp.c (sim_open): Tidy up device creation.

* dv-mn103int.c (mn103int_port_event): Drive NMI with non-zero value.
(mn103int_io_read_buffer): Convert absolute address to register block offsets.
(read_icr, write_icr): Convert block offset into group offset.
This commit is contained in:
Andrew Cagney
1998-03-25 05:37:42 +00:00
parent 6100784a60
commit 8077fed51e
3 changed files with 89 additions and 48 deletions

View File

@ -28,8 +28,6 @@ Makefile.in
config.in config.in
configure configure
configure.in configure.in
dv-mn103cpu.c
dv-mn103int.c
mn10300_sim.h mn10300_sim.h
gencode.c gencode.c
interp.c interp.c
@ -41,6 +39,9 @@ op_utils.c
Things-to-lose: Things-to-lose:
dv-mn103cpu.c
dv-mn103int.c
Do-last: Do-last:
# End of file. # End of file.

View File

@ -1,3 +1,13 @@
Wed Mar 25 16:14:50 1998 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (sim_open): Tidy up device creation.
* dv-mn103int.c (mn103int_port_event): Drive NMI with non-zero
value.
(mn103int_io_read_buffer): Convert absolute address to register
block offsets.
(read_icr, write_icr): Convert block offset into group offset.
Wed Mar 25 15:08:49 1998 Andrew Cagney <cagney@b1.cygnus.com> Wed Mar 25 15:08:49 1998 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (sim_open): Create second 1mb memory region at * interp.c (sim_open): Create second 1mb memory region at

View File

@ -119,10 +119,11 @@ enum mn103int_trigger {
enum mn103int_type { enum mn103int_type {
NMI_GROUP, NMI_GROUP,
INT_GROUP, LEVEL_GROUP,
}; };
struct mn103int_group { struct mn103int_group {
int gid;
int level; int level;
unsigned enable; unsigned enable;
unsigned request; unsigned request;
@ -134,8 +135,8 @@ struct mn103int_group {
enum { enum {
FIRST_NMI_GROUP = 0, FIRST_NMI_GROUP = 0,
LAST_NMI_GROUP = 1, LAST_NMI_GROUP = 1,
FIRST_INT_GROUP = 2, FIRST_LEVEL_GROUP = 2,
LAST_INT_GROUP = 24, LAST_LEVEL_GROUP = 24,
NR_GROUPS, NR_GROUPS,
}; };
@ -360,13 +361,14 @@ mn103int_finish (struct hw *me)
struct mn103int_group *group = &controller->group[gid]; struct mn103int_group *group = &controller->group[gid];
group->enable = 0xf; group->enable = 0xf;
group->trigger = NEGATIVE_EDGE; group->trigger = NEGATIVE_EDGE;
group->gid = gid;
if (FIRST_NMI_GROUP <= gid && gid <= LAST_NMI_GROUP) if (FIRST_NMI_GROUP <= gid && gid <= LAST_NMI_GROUP)
{ {
group->type = NMI_GROUP; group->type = NMI_GROUP;
} }
else if (FIRST_INT_GROUP <= gid && gid <= LAST_INT_GROUP) else if (FIRST_LEVEL_GROUP <= gid && gid <= LAST_LEVEL_GROUP)
{ {
group->type = INT_GROUP; group->type = LEVEL_GROUP;
} }
else else
hw_abort (me, "internal error - unknown group id"); hw_abort (me, "internal error - unknown group id");
@ -390,7 +392,7 @@ find_highest_interrupt_group (struct hw *me,
selected = FIRST_NMI_GROUP; selected = FIRST_NMI_GROUP;
controller->group[FIRST_NMI_GROUP].level = 7; controller->group[FIRST_NMI_GROUP].level = 7;
for (gid = FIRST_INT_GROUP; gid <= LAST_INT_GROUP; gid++) for (gid = FIRST_LEVEL_GROUP; gid <= LAST_LEVEL_GROUP; gid++)
{ {
struct mn103int_group *group = &controller->group[gid]; struct mn103int_group *group = &controller->group[gid];
if ((group->request & group->enable) != 0) if ((group->request & group->enable) != 0)
@ -491,12 +493,12 @@ mn103int_port_event (struct hw *me,
if ((group->request & group->enable) != 0) if ((group->request & group->enable) != 0)
{ {
HW_TRACE ((me, "port-out NMI")); HW_TRACE ((me, "port-out NMI"));
hw_port_event (me, NMI_PORT, 0, NULL, NULL_CIA); hw_port_event (me, NMI_PORT, 1, NULL, NULL_CIA);
} }
break; break;
} }
case INT_GROUP: case LEVEL_GROUP:
{ {
/* if an interrupt is now pending */ /* if an interrupt is now pending */
HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - INT", HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - INT",
@ -513,12 +515,24 @@ mn103int_port_event (struct hw *me,
/* Read/write to to an ICR (group control register) */ /* Read/write to to an ICR (group control register) */
static struct mn103int_group *
decode_group (struct hw *me,
struct mn103int *controller,
unsigned_word base,
unsigned_word *offset)
{
int gid = (base / 8) % NR_GROUPS;
*offset = (base % 8);
return &controller->group[gid];
}
static unsigned8 static unsigned8
read_icr (struct hw *me, read_icr (struct hw *me,
struct mn103int *controller, struct mn103int *controller,
struct mn103int_group *group, unsigned_word base)
unsigned_word offset)
{ {
unsigned_word offset;
struct mn103int_group *group = decode_group (me, controller, base, &offset);
unsigned8 val = 0; unsigned8 val = 0;
switch (group->type) switch (group->type)
{ {
@ -528,25 +542,35 @@ read_icr (struct hw *me,
{ {
case 0: case 0:
val = INSERT_ID (group->request); val = INSERT_ID (group->request);
HW_TRACE ((me, "read-icr 0x%02x", val)); HW_TRACE ((me, "read-icr group=%d nmi 0x%02x",
group->gid, val));
break;
default:
break; break;
} }
break; break;
case INT_GROUP: case LEVEL_GROUP:
switch (offset) switch (offset)
{ {
case 0: case 0:
val = (INSERT_IR (group->request) val = (INSERT_IR (group->request)
| INSERT_ID (group->request & group->enable)); | INSERT_ID (group->request & group->enable));
HW_TRACE ((me, "read-icr 0:0x%02x", val)); HW_TRACE ((me, "read-icr group=%d level 0 0x%02x",
group->gid, val));
break; break;
case 1: case 1:
val = (INSERT_LV (group->level) val = (INSERT_LV (group->level)
| INSERT_IE (group->enable)); | INSERT_IE (group->enable));
HW_TRACE ((me, "read-icr 1:0x%02x", val)); HW_TRACE ((me, "read-icr level-%d level 1 0x%02x",
group->gid, val));
break; break;
} }
break;
default:
break;
} }
return val; return val;
@ -555,10 +579,11 @@ read_icr (struct hw *me,
static void static void
write_icr (struct hw *me, write_icr (struct hw *me,
struct mn103int *controller, struct mn103int *controller,
struct mn103int_group *group, unsigned_word base,
unsigned_word offset,
unsigned8 val) unsigned8 val)
{ {
unsigned_word offset;
struct mn103int_group *group = decode_group (me, controller, base, &offset);
switch (group->type) switch (group->type)
{ {
@ -566,7 +591,8 @@ write_icr (struct hw *me,
switch (offset) switch (offset)
{ {
case 0: case 0:
HW_TRACE ((me, "write-icr 0x%02x", val)); HW_TRACE ((me, "write-icr group=%d nmi 0x%02x",
group->gid, val));
group->request &= ~EXTRACT_ID (val); group->request &= ~EXTRACT_ID (val);
break; break;
default: default:
@ -574,17 +600,19 @@ write_icr (struct hw *me,
} }
break; break;
case INT_GROUP: case LEVEL_GROUP:
switch (offset) switch (offset)
{ {
case 0: /* request/detect */ case 0: /* request/detect */
/* Clear any ID bits and then set them according to IR */ /* Clear any ID bits and then set them according to IR */
HW_TRACE ((me, "write-icr 0:0x%02x", val)); HW_TRACE ((me, "write-icr group=%d level 0 0x%02x",
group->gid, val));
group->request &= EXTRACT_ID (val); group->request &= EXTRACT_ID (val);
group->request |= EXTRACT_IR (val) & EXTRACT_ID (val); group->request |= EXTRACT_IR (val) & EXTRACT_ID (val);
break; break;
case 1: /* level/enable */ case 1: /* level/enable */
HW_TRACE ((me, "write-icr 1:0x%02x", val)); HW_TRACE ((me, "write-icr group=%d level 1 0x%02x",
group->gid, val));
group->level = EXTRACT_LV (val); group->level = EXTRACT_LV (val);
group->enable = EXTRACT_IE (val); group->enable = EXTRACT_IE (val);
break; break;
@ -595,6 +623,9 @@ write_icr (struct hw *me,
push_interrupt_level (me, controller); push_interrupt_level (me, controller);
break; break;
default:
break;
} }
} }
@ -616,10 +647,13 @@ read_iagr (struct hw *me,
& controller->group[val].enable)) & controller->group[val].enable))
/* oops, lost the request */ /* oops, lost the request */
val = 0; val = 0;
HW_TRACE ((me, "read-iagr %d", (int) val));
break; break;
} }
default: default:
val = 0; val = 0;
HW_TRACE ((me, "read-iagr 0x%08lx bad offset", (long) offset));
break;
} }
return val; return val;
} }
@ -658,6 +692,7 @@ read_extmd (struct hw *me,
val |= (group[gid].trigger << (gid * 2)); val |= (group[gid].trigger << (gid * 2));
} }
} }
HW_TRACE ((me, "read-extmd 0x%02lx", (long) val));
return val; return val;
} }
@ -677,6 +712,7 @@ write_extmd (struct hw *me,
/* MAYBE: interrupts already pending? */ /* MAYBE: interrupts already pending? */
} }
} }
HW_TRACE ((me, "write-extmd 0x%02lx", (long) val));
} }
@ -685,29 +721,23 @@ write_extmd (struct hw *me,
static int static int
decode_addr (struct hw *me, decode_addr (struct hw *me,
struct mn103int *controller, struct mn103int *controller,
unsigned_word addr) unsigned_word address,
unsigned_word *offset)
{ {
int i; int i;
for (i = 0; i < NR_BLOCKS; i++) for (i = 0; i < NR_BLOCKS; i++)
{ {
if (addr >= controller->block[i].base if (address >= controller->block[i].base
&& addr <= controller->block[i].bound) && address <= controller->block[i].bound)
{
*offset = address - controller->block[i].base;
return i; return i;
} }
}
hw_abort (me, "bad address"); hw_abort (me, "bad address");
return -1; return -1;
} }
static struct mn103int_group *
decode_group (struct hw *me,
struct mn103int *controller,
unsigned_word addr)
{
unsigned_word offset = (addr - controller->block[ICR_BLOCK].base);
int gid = (offset / 8) % NR_GROUPS;
return &controller->group[gid];
}
static unsigned static unsigned
mn103int_io_read_buffer (struct hw *me, mn103int_io_read_buffer (struct hw *me,
void *dest, void *dest,
@ -720,21 +750,21 @@ mn103int_io_read_buffer (struct hw *me,
struct mn103int *controller = hw_data (me); struct mn103int *controller = hw_data (me);
unsigned8 *buf = dest; unsigned8 *buf = dest;
unsigned byte; unsigned byte;
HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
for (byte = 0; byte < nr_bytes; byte++) for (byte = 0; byte < nr_bytes; byte++)
{ {
unsigned_word address = base + byte; unsigned_word address = base + byte;
switch (decode_addr (me, controller, address)) unsigned_word offset;
switch (decode_addr (me, controller, address, &offset))
{ {
case ICR_BLOCK: case ICR_BLOCK:
buf[byte] = read_icr (me, controller, buf[byte] = read_icr (me, controller, offset);
decode_group (me, controller, address),
address);
break; break;
case IAGR_BLOCK: case IAGR_BLOCK:
buf[byte] = read_iagr (me, controller, address); buf[byte] = read_iagr (me, controller, offset);
break; break;
case EXTMD_BLOCK: case EXTMD_BLOCK:
buf[byte] = read_extmd (me, controller, address); buf[byte] = read_extmd (me, controller, offset);
break; break;
default: default:
hw_abort (me, "bad switch"); hw_abort (me, "bad switch");
@ -755,21 +785,21 @@ mn103int_io_write_buffer (struct hw *me,
struct mn103int *controller = hw_data (me); struct mn103int *controller = hw_data (me);
const unsigned8 *buf = source; const unsigned8 *buf = source;
unsigned byte; unsigned byte;
HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
for (byte = 0; byte < nr_bytes; byte++) for (byte = 0; byte < nr_bytes; byte++)
{ {
unsigned_word address = base + byte; unsigned_word address = base + byte;
switch (decode_addr (me, controller, address)) unsigned_word offset;
switch (decode_addr (me, controller, address, &offset))
{ {
case ICR_BLOCK: case ICR_BLOCK:
write_icr (me, controller, write_icr (me, controller, offset, buf[byte]);
decode_group (me, controller, address),
address, buf[byte]);
break; break;
case IAGR_BLOCK: case IAGR_BLOCK:
/* not allowed */ /* not allowed */
break; break;
case EXTMD_BLOCK: case EXTMD_BLOCK:
write_extmd (me, controller, address, buf[byte]); write_extmd (me, controller, offset, buf[byte]);
break; break;
default: default:
hw_abort (me, "bad switch"); hw_abort (me, "bad switch");