-/* This file is part of the program psim.
-
- Copyright (C) 1994-1996,1998, Andrew Cagney <cagney@highland.com.au>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- */
+/* The common simulator framework for GDB, the GNU Debugger.
+ Copyright 2002-2022 Free Software Foundation, Inc.
-#include "sim-main.h"
-#include "hw-base.h"
+ Contributed by Andrew Cagney and Red Hat.
-/* NOTE: pal is naughty and grubs around looking at things outside of
- its immediate domain */
-#include "hw-tree.h"
+ This file is part of GDB.
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This must come before any other includes. */
+#include "defs.h"
+
+#include <stdlib.h>
+#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
+
+#include "sim-main.h"
+#include "hw-main.h"
+#include "sim-io.h"
+
+/* NOTE: pal is naughty and grubs around looking at things outside of
+ its immediate domain */
+#include "hw-tree.h"
/* DEVICE
-
+
pal - glue logic device containing assorted junk
-
+
DESCRIPTION
-
+
Typical hardware dependant hack. This device allows the firmware
to gain access to all the things the firmware needs (but the OS
doesn't).
RESET (write): halts the simulator. The value written to the
register is used as an exit status.
-
+
PROCESSOR ID (read): returns the processor identifier (0 .. N-1) of
the processor performing the read.
-
+
INTERRUPT (write): This register must be written using a two byte
store. The low byte specifies a port and the upper byte specifies
the a level. LEVEL is driven on the specified port. By
PROPERTIES
-
+
reg = <address> <size> (required)
Specify the address (within the parent bus) that this device is to
be located.
+ poll? = <boolean>
+
+ If present and true, indicates that the device should poll its
+ input.
+
PORTS
hw_pal_countdown_value = 0x24,
hw_pal_timer = 0x28,
hw_pal_timer_value = 0x2c,
- hw_pal_address_mask = 0x2f,
+ hw_pal_address_mask = 0x3f,
};
} hw_pal_console_buffer;
typedef struct _hw_pal_counter {
- hw_event *handler;
- signed64 start;
- unsigned32 delta;
+ struct hw_event *handler;
+ int64_t start;
+ uint32_t delta;
int periodic_p;
} hw_pal_counter;
hw_pal_counter countdown;
hw_pal_counter timer;
struct hw *disk;
+ do_hw_poll_read_method *reader;
} hw_pal_device;
enum {
{ "countdown", COUNTDOWN_PORT, 0, output_port, },
{ "timer", TIMER_PORT, 0, output_port, },
{ "int", INT_PORT, MAX_NR_PROCESSORS, output_port, },
- { NULL }
+ { NULL, 0, 0, 0 }
};
{
HW_TRACE ((me, "timer expired"));
counter->start = hw_event_queue_time (me);
- hw_port_event (me, TIMER_PORT, 1, NULL, NULL_CIA);
+ hw_port_event (me, TIMER_PORT, 1);
hw_event_queue_schedule (me, counter->delta, do_counter_event, counter);
}
else
{
HW_TRACE ((me, "countdown expired"));
counter->delta = 0;
- hw_port_event (me, COUNTDOWN_PORT, 1, NULL, NULL_CIA);
+ hw_port_event (me, COUNTDOWN_PORT, 1);
}
}
hw_pal_device *pal,
const char *reg,
hw_pal_counter *counter,
- unsigned32 *word,
+ uint32_t *word,
unsigned nr_bytes)
{
- unsigned32 val;
+ uint32_t val;
if (nr_bytes != 4)
hw_abort (me, "%s - bad read size must be 4 bytes", reg);
val = counter->delta;
hw_pal_device *pal,
const char *reg,
hw_pal_counter *counter,
- unsigned32 *word,
+ uint32_t *word,
unsigned nr_bytes)
{
- unsigned32 val;
+ uint32_t val;
if (nr_bytes != 4)
hw_abort (me, "%s - bad read size must be 4 bytes", reg);
if (counter->delta != 0)
hw_pal_device *pal,
const char *reg,
hw_pal_counter *counter,
- const unsigned32 *word,
+ const uint32_t *word,
unsigned nr_bytes)
{
if (nr_bytes != 4)
static void
scan_hw_pal (struct hw *me)
{
-#if 0
- hw_pal_struct hw *hw_pal = (hw_pal_struct hw *) hw_data (me);
-#endif
+ hw_pal_device *hw_pal = (hw_pal_device *)hw_data (me);
char c;
int count;
- count = sim_io_read_stdin (hw_system (me), &c, sizeof(c));
-#if 0
+ count = do_hw_poll_read (me, hw_pal->reader, 0/*STDIN*/, &c, sizeof (c));
switch (count)
{
- case sim_io_not_ready:
- case sim_io_eof:
+ case HW_IO_NOT_READY:
+ case HW_IO_EOF:
hw_pal->input.buffer = 0;
hw_pal->input.status = 0;
break;
hw_pal->input.buffer = c;
hw_pal->input.status = 1;
}
-#endif
}
/* write the character to the hw_pal */
void *dest,
int space,
unsigned_word addr,
- unsigned nr_bytes,
- sim_cpu *cpu,
- sim_cia cia)
+ unsigned nr_bytes)
{
hw_pal_device *hw_pal = (hw_pal_device *) hw_data (me);
unsigned_1 *byte = (unsigned_1 *) dest;
{
case hw_pal_cpu_nr_register:
-#ifdef CPU_INDEX
- *byte = CPU_INDEX (cpu);
-#else
- *byte = 0;
-#endif
+ *byte = CPU_INDEX (hw_system_cpu (me));
HW_TRACE ((me, "read - cpu-nr %d\n", *byte));
break;
const void *source,
int space,
unsigned_word addr,
- unsigned nr_bytes,
- sim_cpu *cpu,
- sim_cia cia)
+ unsigned nr_bytes)
{
hw_pal_device *hw_pal = (hw_pal_device*) hw_data (me);
unsigned_1 *byte = (unsigned_1 *) source;
-
+
switch (addr & hw_pal_address_mask)
{
case hw_pal_reset_register:
- sim_engine_halt (hw_system (me), cpu, NULL, cia, sim_exited, byte[0]);
+ hw_halt (me, sim_exited, byte[0]);
break;
case hw_pal_int_register:
hw_port_event (me,
INT_PORT + byte[0], /*port*/
- (nr_bytes > 1 ? byte[1] : 0), /* val */
- cpu, cia);
+ (nr_bytes > 1 ? byte[1] : 0)); /* val */
break;
case hw_pal_read_fifo:
do_counter_write (me, hw_pal, "countdown",
&hw_pal->countdown, source, nr_bytes);
break;
-
+
case hw_pal_timer:
do_counter_write (me, hw_pal, "timer",
&hw_pal->timer, source, nr_bytes);
break;
-
+
}
return nr_bytes;
}
#if NOT_YET
static void
-hw_pal_instance_delete_callback(hw_instance *instance)
+hw_pal_instance_delete_callback (hw_instance *instance)
{
/* nothing to delete, the hw_pal is attached to the struct hw */
return;
set_hw_ports (hw, hw_pal_ports);
/* attach ourselves */
do_hw_attach_regs (hw);
-
+ /* If so configured, enable polled input */
+ if (hw_find_property (hw, "poll?") != NULL
+ && hw_find_boolean_property (hw, "poll?"))
+ {
+ hw_pal->reader = sim_io_poll_read;
+ }
+ else
+ {
+ hw_pal->reader = sim_io_read;
+ }
/* tag the periodic timer */
hw_pal->timer.periodic_p = 1;
}
-const struct hw_device_descriptor dv_pal_descriptor[] = {
+const struct hw_descriptor dv_pal_descriptor[] = {
{ "pal", hw_pal_finish, },
- { NULL },
+ { NULL, NULL },
};