aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/ppc/.Sanitize7
-rw-r--r--sim/ppc/ChangeLog484
-rw-r--r--sim/ppc/hw_disk.c255
-rw-r--r--sim/ppc/hw_init.c569
-rw-r--r--sim/ppc/hw_register.c125
-rw-r--r--sim/ppc/hw_vm.c269
6 files changed, 1708 insertions, 1 deletions
diff --git a/sim/ppc/.Sanitize b/sim/ppc/.Sanitize
index 0e10881..47ca881 100644
--- a/sim/ppc/.Sanitize
+++ b/sim/ppc/.Sanitize
@@ -73,7 +73,10 @@ filter_filename.h
hw_com.c
hw_cpu.c
hw_cpu.h
+hw_disk.c
hw_eeprom.c
+hw_htab.c
+hw_init.c
hw_iobus.c
hw_memory.c
hw_nvram.c
@@ -82,6 +85,9 @@ hw_pci_ide.c
hw_phb.c
hw_phb.h
hw_pic.c
+hw_register.c
+hw_trace.c
+hw_vm.c
idecode_branch.h
idecode_expression.h
idecode_fields.h
@@ -101,6 +107,7 @@ options.c
options.h
os_emul.c
os_emul.h
+pk_disklabel.c
ppc-cache-rules
ppc-instructions
ppc-opcode-complex
diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog
index c562fb3..a3738b1 100644
--- a/sim/ppc/ChangeLog
+++ b/sim/ppc/ChangeLog
@@ -1,9 +1,25 @@
+Wed Jun 5 01:39:07 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * psim.c (psim_options): Correct type of dummy arguments being
+ passed to a device_ioctl call.
+
+ * hw_init.c (hw_data_init_data_callback): Adjust printf arguments.
+ (write_stack_arguments): Ditto.
+ * hw_trace.c: Instance callback entry no longer a table.
+
+Wed Jun 5 01:39:07 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * emul_unix.c (do_unix_umask): Cast printf argument.
+ (convert_to_linux_termios): Use LINUX_VSWTC not LINUX_VSWCH
+
Mon Jun 3 15:02:04 1996 Michael Meissner <meissner@tiktok.cygnus.com>
- * device_table.c (update_for_binary_section): Abort if we find an
+ * hw_init.c (update_for_binary_section): Abort if we find an
.interp section, which indicates the need for shared libraries to
be loaded.
+Mon Jun 3 15:02:04 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
* emul_unix.c (do_unix_{time,gettimeofday,getrusage}): Add support
for time, gettimeofday, and getrusage system calls.
({solaris,linux}_descriptors): Add new system calls.
@@ -14,6 +30,17 @@ Mon Jun 3 15:02:04 1996 Michael Meissner <meissner@tiktok.cygnus.com>
(AC_TYPE_{MODE,OFF,PID,SIZE,UID}_T): Define.
* config{.in,ure}: Regenerate.
+Mon Jun 3 23:19:57 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * emul_netbsd.c (emul_netbsd_create): Use the more specific names
+ `ppc-elf' and `ppc-xcoff' for the stack-type.
+ * emul_unix.c (emul_unix_create): Ditto.
+ * emul_bugapi.c (emul_bugapi_create): Ditto.
+ * hw_init.c: Reconize the new names.
+
+ * emul_unix.c (do_unix_break): Adjust so that the updated ioctl
+ call is used (no system parameter).
+
Sun Jun 2 11:21:17 1996 Michael Meissner <meissner@tiktok.cygnus.com>
* emul_unix.{h,c}: New files to provide Solaris and Linux system
@@ -46,6 +73,154 @@ Sun Jun 2 11:21:17 1996 Michael Meissner <meissner@tiktok.cygnus.com>
* psim.c (psim_usage): Add message about solaris, linux
emulations.
+Thu May 30 00:00:10 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * hw_iobus.c: Tidy up notes so that they can be auto-extracted.
+
+ * README: Correct PSIM's title
+
+Wed May 29 23:50:26 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * basics.h: New global type object_disposition, used to indicate
+ the status of objects when things are restarted.
+
+Fri May 17 17:28:52 1996 Andrew Cagney <cagney@benjimen.highland.com.au>
+
+ * device_table.h: Change the interrupt descriptor structure so
+ that it includes an additional member - an upper bound on the
+ interrupts by that name.
+
+ * device.c (device_interrupt_decode): Allow a range of interrupt
+ ports (eg rst0 .. rst6) if the port descriptors bound is non zero.
+
+ * device.c (device_tree_print_device): Include a list of valid
+ interrupt ports when listing supported devices.
+
+ * device.h, device.c (device_child_interrupt_*): Delete. Not used.
+
+ * emul_generic.c (emul_add_tree_hardware): Modify the creation of
+ the interrupt net so that it uses int0 .. intN.
+
+Tue May 14 23:03:53 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * device.h, device.c (device_ioctl): Drop the system argument.
+ Devices can not obtain this using the device_system() call.
+ * device_table.h: Adjust accordingly.
+ * hw_*.c: Adjust accordingly.
+ * emul_netbsd.c (do_break): Adjust call to vm device accordingly.
+ * psim.c (psim_options): Use a device_ioctl call to force the
+ hw_trace device to update the trace options.
+ * hw_trace.c: Replace the init function with an ioctl call. Adjust
+ doc accordingly.
+
+ * psim.c (psim_init): Re-order initialization so that the
+ os-emulation is initialized after the device tree. Without this,
+ os-emul's are not able to create instances or access properties
+ that contain an instance handle.
+
+ * device.h, device.c (device_add_*_property): Make these functions
+ internal to device.c. The user has access to the more generic
+ device_tree_add_parsed function. Differentiate between the initial
+ and current value for each property.
+ * (clean_device_properties): New function that deletes any
+ properties created after the start of a simulation and restores
+ the initial value of any others (ignoring ihandles).
+ * (init_device_properties): (Re)Initialize any properties that
+ contain ihandles. create
+
+ * (device_tree_init): Include calls to clean the device tree's
+ properties and then initialize them. Document this in the device.h
+ file.
+
+Mon May 6 17:36:15 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * interrupts.c (decrementer_interrupt): Always pend a decrementer
+ interrupt even if it is not yet possible to deliver it.
+
+Wed May 1 12:26:51 1996 Andrew Cagney <cagney@benjimen>
+
+ * mon.h, mon.c (mon_get_number_of_insns): Make this externally
+ visable adjusting the arguments so that the interface is correct.
+ (mon_print_info): Adjust calls.
+
+ * registers.h, registers.c (register_description): Add phony
+ cycle, insn and stall registers.
+
+ * psim.c (psim_read_register): Return nr of instructions for given
+ processor.
+
+Tue Apr 30 22:09:09 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * hw_htab.c: New file. Extract contents from disk_table.c.
+ Contains a device that, during initialization will create a
+ PowerPC htab in memory.
+ * hw_register.c: New file. Extract contents from disk_table.c.
+ Contains a device that, during initialization, will parse its
+ property list and use that to initialize various processor
+ registers (not target specific).
+ * hw_vm.c: New file. Extract contents from disk_table.c. Contains
+ a device that handles accesses to invalid virtual memory addresses
+ (in user mode).
+ * hw_init.c: New file. Extract contents from disk_table.c. Misc
+ devices that can initialize memory from a file.
+ * hw_trace.c: New file. Extract contents from disk_table.c.
+ Configure trace options from property values.
+
+ * Makefile.in (hw_htab.o, hw_register.o, hw_vm.o, hw_init.o,
+ hw_trace.c): Add new device files.
+
+ * device_table.c: Remove above code, now in separate independant
+ files.
+
+Fri Apr 26 00:00:07 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * hw_disk.c: New file. Disk and CDROM device.
+
+ * Makefile.in (hw_disk.o): Add device hw_disk.c.
+
+ * pk_disklabel.c: New file. Implement the miss-named disk-label
+ package.
+
+ * Makefile.in (pk.h): Create the file pk.h that contains a list of all
+ the packages.
+
+ * Makefile.in (hw.h, hw.c): Add dependancy on Makefile so that
+ they are re-created when the makefile is updated.
+
+ * emul_generic.c (emul_add_tree_hardware): Add a disk device
+ (below the iobus) to the device tree. Include an ihandle of
+ the disk as /chosen/disk.
+
+ * emul_bugapi.c (emul_bugapi_create): Don't initialize the input,
+ output and (new) disk handles yet.
+ * (emul_bugapi_init): Initialize the input, output (and just added)
+ disk ihandles here.
+ * (emul_bugapi_do_diskio): New. Performs disk i/o (well at least
+ what I think the behavour is).
+ * emul_bugapi.c (emul_bugapi_instruction_call): Add hook to disk
+ i/o bug call. For RETURN call, exit using gpr[3]'s status even
+ though this isn't part of the spec - makes it possible for machine
+ code to signal the aporting of a simulation run.
+
+ * emul_chirp.c (chirp_emul_call_method): Add support for the
+ claim/release methods.
+ * (chirp_emul_exit): Add an optional exit status argument to
+ the exit method. Makes it possible for chirp emul simulations
+ to abort upon an error.
+ * device.h, device.c (device_instance_claim,
+ device_instance_release): New methods for claiming and releasing
+ memory.
+ * hw_memory.c: add claim and release memory methods.
+ * hw_*: Use the claim memory method when allocating physical
+ memory.
+
+Thu Apr 18 23:38:10 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * hw_nvram.c (hw_nvram_update_clock): Use the current not previous
+ time when updating the clock.
+
+ * hw_nvram.c: Tidy up documentation
+
Fri May 24 10:08:10 1996 Michael Meissner <meissner@tiktok.cygnus.com>
* configure.in (AC_STRUCT_ST_{BLKSIZE,BLOCKS,RDEV}): Use these
@@ -162,6 +337,42 @@ Sun Apr 14 21:32:41 1996 Andrew Cagney <cagney@highland.com.au>
* device_table.c (stack_ioctl_callback): Return 0 status.
(vm_ioctl_callback): Ditto
+Sat Apr 13 00:00:24 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * emul_netbsd.c (do_read): Correctly set the return value.
+ (do_getpid): Ditto.
+ (do_getuid): Ditto.
+ (do_geteuid): Ditto.
+ (do_dup): Ditto.
+ (do_getegid): Ditto.
+ (do_getgid): Ditto.
+ (do_sigprocmask): Ditto.
+ (do_umask): Ditto.
+ (do_dup2): Ditto.
+ (do_gettimeofday): Ditto.
+ (do_getrusage): Ditto.
+ (do_fstat): Ditto.
+ (do_stat): Ditto.
+ (do_lseek): Ditto.
+ (do___sysctl): Ditto.
+
+Fri Apr 12 20:56:47 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * device_table.c (vm_ioctl_callback): Don't access the processor
+ registers directly, instead leave it to the caller to handle this.
+
+ * emul_netbsd.c (do_break): Which calls vm_ioctl_callback to
+ perform a break. Pass in the new break value and set the
+ registers according to the result.
+
+ * emul_generic.c (emul_write_status): Change so that r3 contains
+ either status or errno and failure is indicated by SO.
+
+Thu Apr 4 23:03:38 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * emul_bugapi.c (emul_bugapi_create): More strict check of OEA
+ address.
+
Thu Apr 4 20:58:05 1996 Andrew Cagney <cagney@highland.com.au>
* interrupts.h (interrupts): New structure contains state of
@@ -199,6 +410,25 @@ Fri Mar 29 20:17:17 1996 Andrew Cagney <cagney@highland.com.au>
* Makefile.in (hw_iobus.o): New dependency.
+Fri Mar 29 12:17:58 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * emul_bugapi.c (_os_emul_data): Add fields for output, input.
+ (emul_bugapi_create): Create input, output from /chosen/stdin and
+ /chosen/stdout.
+ (emul_bugapi_do_{read,write}): Switch to use device_instance
+ interface.
+ (emul_bugapi_instruction_call): Change calls to
+ emul_bugapi_do_{read,write} to pass device instance argument.
+
+Tue Mar 26 14:57:58 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * igen.c (idecode_switch_end): Fix 2/26 change so that an extra
+ default is not written out if a default was already written.
+
+ * psim.c (psim_{read,write}_register): Use sizeof unsigned_8 to
+ size cooked_buf, not sizeof natural_word, since floating point
+ registers are 8 bytes.
+
Mon Mar 25 22:07:13 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
* configure: Regenerate with autoconf 2.9.
@@ -207,6 +437,11 @@ Thu Mar 21 00:14:26 1996 Andrew Cagney <cagney@highland.com.au>
* device_table.h: Always include string headers.
+Thu Mar 21 00:06:09 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * main.c (error): Be careful to not try to print out statistics
+ when the simulation was never created.
+
Sun Mar 17 22:40:57 1996 Andrew Cagney <cagney@highland.com.au>
* basics.h: Move the event queue's definition to here so that it
@@ -322,6 +557,11 @@ Sun Mar 3 03:10:22 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
* device.c (device_tree_print_device, device_tree_add_parsed):
Remove references to phandle properties.
+Wed Feb 28 00:43:07 1996 Andrew Cagney - aka Noid <cagney@highland.com.au>
+
+ * Makefile.in (corefile.o): missing dependency on device_table.h
+ etc.
+
Tue Feb 27 23:59:35 1996 Andrew Cagney - aka Noid <cagney@highland.com.au>
* device_table.h: Revamp device init callbacks so that they are a
@@ -339,6 +579,13 @@ Tue Feb 27 23:59:35 1996 Andrew Cagney - aka Noid <cagney@highland.com.au>
* (address nee config_address): ditto.
* (interrupt): ditto.
+Mon Feb 26 21:11:20 1996 Andrew Cagney - aka Noid <cagney@highland.com.au>
+
+ * igen.c (idecode_switch_end): Output a default entry when the
+ switch statement is perfect. Firstly stops GCC complaining about
+ an incomplete switch and secondly it will be eliminated by a good
+ compiler any way.
+
Mon Feb 26 22:47:15 1996 Andrew Cagney - aka Noid <cagney@highland.com.au>
* Makefile.in (hw.h, hw.c): New targets. Create from the list of
@@ -362,3 +609,238 @@ Mon Feb 26 22:24:00 1996 Andrew Cagney - aka Noid <cagney@highland.com.au>
* device_table.c: Delete the memory device (moved to hw_memory.c).
* hw_memory.c: New file. Just an OpenBoot memory device.
+
+Wed Jan 17 21:47:34 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * device.c (device_init_address): New. Split initialization into
+ two stages, address and address spaces
+ * device.c (device_init_data): New. ... and data or other work.
+ With out this, devices try to modify memory before it as been
+ attached.
+
+ * device.c (device_tree_init): Update to perform staged
+ initialization.
+
+ * device.c (device_init): Delete.
+
+Wed Jan 17 21:43:09 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * device_table.c (data_*): Rewrite to make heaver use of property
+ nodes. Allow initialization by different data types.
+ * device_table.c (htab_* pte_*): Rewrite to use properties.
+
+ * emul_chirp.c (emul_chirp_create): Use
+ * emul_bugapi.c (emul_bugapi_create): Ditto
+ * emul_netbsd.c (emul_netbsd_create): Ditto
+
+Wed Jan 17 21:24:50 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * emul_generic.c (emul_add_tree_options): Annotate existing tree
+ with options that haven't yet been specified.
+ * emul_generic.c (emul_add_tree_hardware): Annotate existing tree
+ with demo devices and properties.
+
+ * emul_chirp.c (emul_chirp_create): Update to use new
+ device_tree_add_parsed call and additional information now
+ included in the device tree. Use emul_add_tree* functions to add
+ any missing details.
+ * emul_bugapi.c (emul_bugapi_create): Ditto
+ * emul_netbsd.c (emul_netbsd_create): Ditto
+
+Wed Jan 17 21:18:27 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * device.c (device_instance_create): New. Create/delete and
+ operate on instances of a device.
+ * device.c (device_instance_delete): Ditto
+ * device.c (device_instance_read): Ditto
+ * device.c (device_instance_write): Ditto
+ * device.c (device_instance_seek): Ditto
+ * device.c (device_instance_data): Ditto
+ * device.c (device_instance_name): Ditto
+ * device.c (device_instance_path): Ditto
+
+ * emul_chirp.c (chirp_emul_open): Implement using device_instance.
+ * emul_chirp.c (chirp_emul_close): Ditto
+ * emul_chirp.c (chirp_emul_read): Ditto
+ * emul_chirp.c (chirp_emul_write): Ditto
+ * emul_chirp.c (chirp_emul_seek): Ditto
+
+ * emul_chirp.c (chirp_read_t2h_args): Read arguments from device.
+ Being careful to convert all from target to host byte order.
+ * emul_chirp.c (chirp_write_h2t_args): Converse.
+
+Wed Jan 17 20:07:15 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * device.c (device_tree_add_parsed): New. Rewrite code to add
+ devices to the device tree so that a single printf style function
+ is used.
+
+ * device.c (device_tree_add_*): Delete. Replaced by above.
+
+ * device.c (split_device_specifier): Functions to manipulate a
+ device specifier (path) breaking it into its components
+ * device.c (split_property_specifier): Ditto
+ * device.c (split_device_name): Ditto
+ * device.c (split_find_device): Ditto
+
+ * device.c (scan_*): Delete
+
+ * device.c (device_tree_find_device): Rewrite to use above.
+ * device.c (device_add_property): Ditto
+
+Wed Jan 17 19:51:56 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * psim.c(psim_options): Parse the psim options, installing their
+ value in the device tree. Options are now first entered into a
+ device tree and then extracted out again when needed. This allows
+ greater flexability in configuration.
+
+ * psim.c (psim_tree): Returns a basic device tree ready for
+ parsing by psim_options.
+ * psim.c (psim_usage): New. Give usage to varing levels of detail
+ according to the verbosity. In turn output device and trace
+ usage.
+
+ * main.c (main): Update to use new system
+ * sim_calls.c (sim_open, sim_do_command): Ditto
+
+ * psim.c (psim_options): Add `r' option - ram size.
+ * psim.c (psim_options): Add `o' option - openboot tree entry.
+ * psim.c (psim_options): Add `h'/`H' options - more help.
+
+ * debug.c (trace_usage): Add more detailed help.
+ * device.c (device_usage): New. Output help including a list of
+ the devices currently available in the device table.
+ * device_table.c: Add usage operator to each device.
+
+ * corefile.c (core_create, core_device_create): Adjust so that the
+ core device is created earlier for psim_tree(). Core can later be
+ created from it.
+
+ * psim.c (psim_create): Update to handle above way of creating
+ things. Extract all information from the device tree.
+
+ * device_tree.c (trace_*): New device node, its properties are
+ used to set the value of the trace options. Init this device (in
+ psim_options) when ever the options are updated.
+
+Wed Jan 17 19:46:07 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * debug.h: Add trace_print_info, trace_print_device_tree and
+ trace_dump_device_tree. The first is a replacement for the
+ variable `print_info' found in main.c and sim_calls.c. The latter
+ two enable the dumping of the entire device tree.
+
+ * debug.c: Add to trace_description table.
+
+ * main.c (main): Use above trace instead of local variable
+ * sim_calls.c (sim_close): Ditto
+
+ * device.c (device_tree_print_device): New. Prints the device
+ tree in a format that is consistent with what can be parsed by the
+ device tree load from file code.
+
+ * psim.c (psim_create): Dump device tree if enabled. If nump
+ selected, exit psim immediatly.
+
+Wed Jan 17 19:36:52 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * corefile-n.h (core_map_read_N): When mapping from an address to
+ a device, do not subtract the devices base. The device its self
+ can do this. Brings the behavour into line with OpenBoot.
+ * corefile-n.h (core_map_write_N): Ditto
+ * corefile.c (core_map_read_buffer): Ditto
+ * corefile.c (core_map_write_buffer): Ditto
+
+ * device_table.c (console_io_read_buffer_callback): Adjust to
+ handle biased address.
+ * device_table.c (console_io_write_buffer_callback): Ditto
+
+Wed Jan 17 18:36:09 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * device.c (attach_device_interrupt_edge): New. Interrupt model
+ did not allow interrupts to be wired up as a general net (edges).
+ Re-implement so that interrupt events can be passed to multiple
+ controllers and interrupt controllers can further propogate
+ interrupt events.
+
+ * device.c (attach_device_interrupt_edge) : New, Ditto
+ * device.c (detach_device_interrupt_edge) : New, Ditto
+ * device.c (clean_device_interrupt_edges) : New, Ditto
+ * device.c (device_interrupt_event) : New, Ditto
+ * device.c (device_interrupt_attach) : New, Ditto
+ * device.c (device_interrupt_detach) : New, Ditto
+ * device.c (device_child_interrupt_attach) : New, Ditto
+ * device.c (device_child_interrupt_detach) : New, Ditto
+
+ * device.c (device_attach_interrupt) : Delete old
+ * device.c (device_detach_interrupt) : Delete old
+ * device.c (device_interrupt) : Delete old
+ * device.c (device_interrupt_ack) : Delete old
+
+ * device_table.c (unimp_*) : Update to match
+
+ * device_table.c (icu_io_write_buffer_callback) : Update to use
+ interface.
+ * device_table.c (icu_interrupt_event_callback) : Ditto
+
+Wed Jan 17 18:18:40 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * device.c (external_to_device) : New function that provides a
+ standard mapping between a devices internal representation (a
+ pointer) and its external (or what is passed to a client)
+ representation (a phandle). Implement using the cap object
+ attached to the root node.
+
+ * device.c (device_to_external) : Ditto
+ * device.c (external_to_device_instance) : Ditto but for ihandle
+ and device instance.
+ * device.c (device_instance_to_external) : Ditto
+
+ * Makefile (device.o): Add dependency on cap.
+
+ * emul_chirp.c (struct _emul_chirp_data) : Elimate use of cap. Code
+ needing to translate between internal and external representations
+ changed to use the external_to_device et.al. device operations.
+ * emul_chirp.c (chirp_emul_*) : Ditto
+
+ * Makefile (emul_chirp.o): Remove dependency on cap
+
+Sat Jan 6 10:13:26 1996 Andrew Cagney - aka Noid <cagney@highland.com.au>
+
+ * emul_chirp.c (map_over_chirp_note): Tighten up (and fix) checks
+ on OpenBoot note section.
+
+Fri Jan 5 20:28:53 1996 Andrew Cagney <cagney@hignland.com.au>
+
+ * emul_generic.c (emul_write_buffer): Use vm faulting byte
+ read/write calls for buffer transfers. This will cause a fault to
+ occure if the transfer fails. CHRP catches the fault while the
+ others suffer the consequences.
+ (emul_read_buffer): Ditto.
+ (emul_write_word): Ditto.
+ (emul_read_word): Ditto.
+ (emul_read_string): Ditto.
+
+Fri Jan 5 18:55:34 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * emul_chirp.c (emul_chirp_create, emul_chirp_instruction_call),
+ emul_generic (emul_blr_instruction): Use a real blr instruction to
+ return from a client service call.
+
+ * emul_chirp.c (services): Add all OpenBoot services to table.
+
+ * emul_generic.h, emul_bugapi.c (emul_bugapi_create), emul_chirp.c
+ (emul_chirp_create) : Use names instead of numbers for
+ instructions being stored in memory.
+
+Fri Jan 5 18:52:28 1996 Andrew Cagney <cagney@highland.com.au>
+
+ * Makefile.in (maintainer-clean): Remove .log, core and *.core
+ (From NetBSD) files.
+
+Wed May 29 22:57:40 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * ChangeLog.00, ChangeLog: ChangeLog from gdb-4.16 becomes
+ ChangeLog.00
+
diff --git a/sim/ppc/hw_disk.c b/sim/ppc/hw_disk.c
new file mode 100644
index 0000000..eb4d236
--- /dev/null
+++ b/sim/ppc/hw_disk.c
@@ -0,0 +1,255 @@
+/* This file is part of the program psim.
+
+ Copyright (C) 1994-1996, 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.
+
+ */
+
+
+#ifndef _HW_DISK_C_
+#define _HW_DISK_C_
+
+#include "device_table.h"
+
+#include "pk.h"
+
+#include <stdio.h>
+
+
+/* DEVICE
+
+ cdrom - readable block device
+
+ disk - readable block device that should be writeable
+
+ floppy - readable block device that should be writeable
+
+ DESCRIPTION
+
+ Block I/O devices that model the behavour of a fixed or removable
+ disk device.
+
+ Creating an instance of this device with no arguments will provide
+ access to primative read/write operators. If arguments are
+ specified then the disk-label package is used to perform abstract
+ disk I/O. The disk-label package will then use this devices
+ primatives.
+
+ For hardware I/O, this device would normally be attached to a
+ parent `bus' and that bus would use the I/O methods to read and
+ write raw data. The bus might actually be a SCSI or IDE device.
+ It is assumed that the parent bus can take care of DMA.
+
+ PROPERTIES
+
+ reg = <address> (required)
+
+ <address> is parent bus dependant.
+
+ device_type = "block"
+
+ name = "disk" | "cdrom" | "fd"
+
+ file = <file-name> (required)
+
+ The name of the file that contains the disk image.
+
+ */
+
+typedef struct _hw_disk_device {
+ const char *name;
+ int read_only;
+ unsigned_word size;
+ FILE *image;
+} hw_disk_device;
+
+typedef struct _hw_disk_instance {
+ long pos;
+ hw_disk_device *disk;
+} hw_disk_instance;
+
+
+static void
+hw_disk_init_address(device *me)
+{
+ hw_disk_device *disk = device_data(me);
+ generic_device_init_address(me);
+ if (disk->image != NULL)
+ fclose(disk->image);
+ disk->name = device_find_string_property(me, "file");
+ if (strcmp(device_name(me), "disk") == 0) {
+ disk->read_only = 0;
+ disk->image = fopen(disk->name, "r+");
+ }
+ else {
+ disk->read_only = 1;
+ disk->image = fopen(disk->name, "r");
+ }
+ if (disk->image == NULL) {
+ perror(device_name(me));
+ device_error(me, "open %s failed\n", disk->name);
+ }
+}
+
+static unsigned
+hw_disk_io_read_buffer(device *me,
+ void *dest,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ cpu *processor,
+ unsigned_word cia)
+{
+ hw_disk_device *disk = device_data(me);
+ if (nr_bytes == 0)
+ return 0;
+ if (addr + nr_bytes > disk->size)
+ return 0;
+ if (fseek(disk->image, addr, SEEK_SET) < 0)
+ return 0;
+ if (fread(dest, nr_bytes, 1, disk->image) != 1)
+ return 0;
+ return nr_bytes;
+}
+
+
+static unsigned
+hw_disk_io_write_buffer(device *me,
+ const void *source,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ cpu *processor,
+ unsigned_word cia)
+{
+ hw_disk_device *disk = device_data(me);
+ if (disk->read_only)
+ return 0;
+ if (nr_bytes == 0)
+ return 0;
+ if (addr + nr_bytes > disk->size)
+ return 0;
+ if (fseek(disk->image, addr, SEEK_SET) < 0)
+ return 0;
+ if (fwrite(source, nr_bytes, 1, disk->image) != 1)
+ return 0;
+ return nr_bytes;
+}
+
+
+/* instances of the hw_disk device */
+
+static void
+hw_disk_instance_delete(device_instance *instance)
+{
+ hw_disk_instance *data = device_instance_data(instance);
+ zfree(data);
+}
+
+static int
+hw_disk_instance_read(device_instance *instance,
+ void *buf,
+ unsigned_word len)
+{
+ hw_disk_instance *data = device_instance_data(instance);
+ if (fseek(data->disk->image, data->pos, SEEK_SET) < 0)
+ return -1;
+ if (fread(buf, len, 1, data->disk->image) != 1)
+ return -1;
+ data->pos = ftell(data->disk->image);
+ return len;
+}
+
+static int
+hw_disk_instance_write(device_instance *instance,
+ const void *buf,
+ unsigned_word len)
+{
+ hw_disk_instance *data = device_instance_data(instance);
+ if (data->disk->read_only)
+ return -1;
+ if (fseek(data->disk->image, data->pos, SEEK_SET) < 0)
+ return -1;
+ if (fwrite(buf, len, 1, data->disk->image) != 1)
+ return -1;
+ data->pos = ftell(data->disk->image);
+ return len;
+}
+
+static int
+hw_disk_instance_seek(device_instance *instance,
+ unsigned_word pos_hi,
+ unsigned_word pos_lo)
+{
+ hw_disk_instance *data = device_instance_data(instance);
+ data->pos = pos_lo;
+ return 0;
+}
+
+static const device_instance_callbacks hw_disk_instance_callbacks = {
+ hw_disk_instance_delete,
+ hw_disk_instance_read,
+ hw_disk_instance_write,
+ hw_disk_instance_seek,
+};
+
+static device_instance *
+hw_disk_create_instance(device *me,
+ const char *path,
+ const char *args)
+{
+ device_instance *disk_instance;
+ hw_disk_device *disk = device_data(me);
+ hw_disk_instance *data = ZALLOC(hw_disk_instance);
+ data->disk = disk;
+ data->pos = 0;
+ disk_instance = device_create_instance_from(me, NULL,
+ data,
+ path, args,
+ &hw_disk_instance_callbacks);
+ return pk_disklabel_create_instance(disk_instance, args);
+}
+
+static device_callbacks const hw_disk_callbacks = {
+ { hw_disk_init_address, NULL },
+ { NULL, }, /* address */
+ { hw_disk_io_read_buffer,
+ hw_disk_io_write_buffer, },
+ { NULL, }, /* DMA */
+ { NULL, }, /* interrupt */
+ { NULL, }, /* unit */
+ hw_disk_create_instance,
+};
+
+
+static void *
+hw_disk_create(const char *name,
+ const device_unit *unit_address,
+ const char *args,
+ device *parent)
+{
+ /* create the descriptor */
+ hw_disk_device *hw_disk = ZALLOC(hw_disk_device);
+ return hw_disk;
+}
+
+
+const device_descriptor hw_disk_device_descriptor[] = {
+ { "disk", hw_disk_create, &hw_disk_callbacks },
+ { NULL },
+};
+
+#endif /* _HW_DISK_C_ */
diff --git a/sim/ppc/hw_init.c b/sim/ppc/hw_init.c
new file mode 100644
index 0000000..6d51c7e
--- /dev/null
+++ b/sim/ppc/hw_init.c
@@ -0,0 +1,569 @@
+/* This file is part of the program psim.
+
+ Copyright (C) 1994-1996, 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.
+
+ */
+
+
+#ifndef _HW_INIT_C_
+#define _HW_INIT_C_
+
+#include "device_table.h"
+#include "bfd.h"
+#include "psim.h"
+
+
+/* DMA a file into memory */
+static int
+dma_file(device *me,
+ const char *file_name,
+ unsigned_word addr)
+{
+ int count;
+ int inc;
+ FILE *image;
+ char buf[1024];
+
+ /* get it open */
+ image = fopen(file_name, "r");
+ if (image == NULL)
+ return -1;
+
+ /* read it in slowly */
+ count = 0;
+ while (1) {
+ inc = fread(buf, 1, sizeof(buf), image);
+ if (feof(image) || ferror(image))
+ break;
+ if (device_dma_write_buffer(device_parent(me),
+ buf,
+ 0 /*address-space*/,
+ addr+count,
+ inc /*nr-bytes*/,
+ 1 /*violate ro*/) != inc) {
+ fclose(image);
+ return -1;
+ }
+ count += inc;
+ }
+
+ /* close down again */
+ fclose(image);
+
+ return count;
+}
+
+
+/* DEVICE
+
+ file - load a file into memory
+
+ DESCRIPTION
+
+ Loads the entire contents of <file-name> into memory at starting at
+ <real-address>. Assumes that memory exists for the load.
+
+ PROPERTIES
+
+ file-name = <string>
+
+ Name of the file to be loaded into memory
+
+ real-address = <integer>
+
+ Real address at which the file is to be loaded */
+
+static void
+hw_file_init_data_callback(device *me)
+{
+ int count;
+ const char *file_name = device_find_string_property(me, "file-name");
+ unsigned_word addr = device_find_integer_property(me, "real-address");
+ /* load the file */
+ count = dma_file(me, file_name, addr);
+ if (count < 0)
+ device_error(me, "Problem loading file %s\n", file_name);
+}
+
+
+static device_callbacks const hw_file_callbacks = {
+ { NULL, hw_file_init_data_callback, },
+ { NULL, }, /* address */
+ { NULL, }, /* IO */
+ { NULL, }, /* DMA */
+ { NULL, }, /* interrupt */
+ { NULL, }, /* unit */
+};
+
+
+/* DEVICE
+
+ data - initialize a memory location
+
+ DESCRIPTION
+
+ A word sized quantity of data is written into memory, using the
+ targets byte ordering, at the specified memory location.
+
+ In the future this device will be extended so that it supports
+ initialization using other data types (eg array, ...)
+
+ PROPERTIES
+
+ data = <int>
+
+ Integer value to be loaded into memory
+
+ real-address = <integer>
+
+ Start address for the data. */
+
+
+static void
+hw_data_init_data_callback(device *me)
+{
+ unsigned_word addr = device_find_integer_property(me, "real-address");
+ const device_property *data = device_find_property(me, "data");
+ if (data == NULL)
+ device_error(me, "missing property <data>\n");
+ switch (data->type) {
+ case integer_property:
+ {
+ unsigned32 buf = device_find_integer_property(me, "data");
+ H2T(buf);
+ if (device_dma_write_buffer(device_parent(me),
+ &buf,
+ 0 /*address-space*/,
+ addr,
+ sizeof(buf), /*nr-bytes*/
+ 1 /*violate ro*/) != sizeof(buf))
+ device_error(me, "Problem storing integer 0x%x at 0x%lx\n",
+ (unsigned)buf, (unsigned long)addr);
+ }
+ break;
+ default:
+ device_error(me, "Write of this data is not yet implemented\n");
+ break;
+ }
+}
+
+
+static device_callbacks const hw_data_callbacks = {
+ { NULL, hw_data_init_data_callback, },
+ { NULL, }, /* address */
+ { NULL, }, /* IO */
+ { NULL, }, /* DMA */
+ { NULL, }, /* interrupt */
+ { NULL, }, /* unit */
+};
+
+
+/* DEVICE
+
+ load-binary - load binary segments into memory
+
+ DESCRIPTION
+
+ Each loadable segment of the specified binary is loaded into memory
+ at its required address. It is assumed that the memory at those
+ addresses already exists.
+
+ This device is normally used to load an executable into memory as
+ part of real mode simulation.
+
+ PROPERTIES
+
+ file-name = <string>
+
+ Name of the binary to be loaded.
+
+ DEVICE
+
+ map-binary - map the binary into the users address space
+
+ DESCRIPTION
+
+ Similar to load-binary except that memory for each segment is
+ created before the corresponding data for the segment is loaded.
+
+ This device is normally used to load an executable into a user mode
+ simulation.
+
+ PROPERTIES
+
+ file-name = <string>
+
+ Name of the binary to be loaded.
+
+ */
+
+static void
+update_for_binary_section(bfd *abfd,
+ asection *the_section,
+ PTR obj)
+{
+ unsigned_word section_vma;
+ unsigned_word section_size;
+ access_type access;
+ device *me = (device*)obj;
+
+ /* skip the section if no memory to allocate */
+ if (! (bfd_get_section_flags(abfd, the_section) & SEC_ALLOC))
+ return;
+
+ /* check/ignore any sections of size zero */
+ section_size = bfd_get_section_size_before_reloc(the_section);
+ if (section_size == 0)
+ return;
+
+ /* find where it is to go */
+ section_vma = bfd_get_section_vma(abfd, the_section);
+
+ DTRACE(binary,
+ ("name=%-7s, vma=0x%.8lx, size=%6ld, flags=%3lx(%s%s%s%s%s )\n",
+ bfd_get_section_name(abfd, the_section),
+ (long)section_vma,
+ (long)section_size,
+ (long)bfd_get_section_flags(abfd, the_section),
+ bfd_get_section_flags(abfd, the_section) & SEC_LOAD ? " LOAD" : "",
+ bfd_get_section_flags(abfd, the_section) & SEC_CODE ? " CODE" : "",
+ bfd_get_section_flags(abfd, the_section) & SEC_DATA ? " DATA" : "",
+ bfd_get_section_flags(abfd, the_section) & SEC_ALLOC ? " ALLOC" : "",
+ bfd_get_section_flags(abfd, the_section) & SEC_READONLY ? " READONLY" : ""
+ ));
+
+ /* If there is an .interp section, it means it needs a shared library interpreter. */
+ if (strcmp(".interp", bfd_get_section_name(abfd, the_section)) == 0)
+ error("Shared libraries are not yet supported.\n");
+
+ /* determine the devices access */
+ access = access_read;
+ if (bfd_get_section_flags(abfd, the_section) & SEC_CODE)
+ access |= access_exec;
+ if (!(bfd_get_section_flags(abfd, the_section) & SEC_READONLY))
+ access |= access_write;
+
+ /* if a map, pass up a request to create the memory in core */
+ if (strncmp(device_name(me), "map-binary", strlen("map-binary")) == 0)
+ device_attach_address(device_parent(me),
+ device_name(me),
+ attach_raw_memory,
+ 0 /*address space*/,
+ section_vma,
+ section_size,
+ access,
+ me);
+
+ /* if a load dma in the required data */
+ if (bfd_get_section_flags(abfd, the_section) & SEC_LOAD) {
+ void *section_init = zalloc(section_size);
+ if (!bfd_get_section_contents(abfd,
+ the_section,
+ section_init, 0,
+ section_size)) {
+ bfd_perror("binary");
+ device_error(me, "load of data failed");
+ return;
+ }
+ if (device_dma_write_buffer(device_parent(me),
+ section_init,
+ 0 /*space*/,
+ section_vma,
+ section_size,
+ 1 /*violate_read_only*/)
+ != section_size)
+ device_error(me, "broken transfer\n");
+ zfree(section_init); /* only free if load */
+ }
+}
+
+static void
+hw_binary_init_data_callback(device *me)
+{
+ /* get the file name */
+ const char *file_name = device_find_string_property(me, "file-name");
+ bfd *image;
+
+ /* open the file */
+ image = bfd_openr(file_name, NULL);
+ if (image == NULL) {
+ bfd_perror("binary");
+ device_error(me, "Failed to open file %s\n", file_name);
+ }
+
+ /* check it is valid */
+ if (!bfd_check_format(image, bfd_object)) {
+ bfd_close(image);
+ device_error(me, "The file %s has an invalid binary format\n", file_name);
+ }
+
+ /* and the data sections */
+ bfd_map_over_sections(image,
+ update_for_binary_section,
+ (PTR)me);
+
+ bfd_close(image);
+}
+
+
+static device_callbacks const hw_binary_callbacks = {
+ { NULL, hw_binary_init_data_callback, },
+ { NULL, }, /* address */
+ { NULL, }, /* IO */
+ { NULL, }, /* DMA */
+ { NULL, }, /* interrupt */
+ { NULL, }, /* unit */
+};
+
+
+/* DEVICE
+
+ stack - create an initial stack frame in memory
+
+ DESCRIPTION
+
+ Creates a stack frame of the specified type in memory.
+
+ Due to the startup sequence gdb uses when commencing a simulation,
+ it is not possible for the data to be placed on the stack to be
+ specified as part of the device tree. Instead the arguments to be
+ pushed onto the stack are specified using an IOCTL call.
+
+ The IOCTL takes the additional arguments:
+
+ | unsigned_word stack_end -- where the stack should come down from
+ | char **argv -- ...
+ | char **envp -- ...
+
+ PROPERTIES
+
+ stack-type = <string>
+
+ The form of the stack frame that is to be created.
+
+ */
+
+static int
+sizeof_argument_strings(char **arg)
+{
+ int sizeof_strings = 0;
+
+ /* robust */
+ if (arg == NULL)
+ return 0;
+
+ /* add up all the string sizes (padding as we go) */
+ for (; *arg != NULL; arg++) {
+ int len = strlen(*arg) + 1;
+ sizeof_strings += ALIGN_8(len);
+ }
+
+ return sizeof_strings;
+}
+
+static int
+number_of_arguments(char **arg)
+{
+ int nr;
+ if (arg == NULL)
+ return 0;
+ for (nr = 0; *arg != NULL; arg++, nr++);
+ return nr;
+}
+
+static int
+sizeof_arguments(char **arg)
+{
+ return ALIGN_8((number_of_arguments(arg) + 1) * sizeof(unsigned_word));
+}
+
+static void
+write_stack_arguments(device *me,
+ char **arg,
+ unsigned_word start_block,
+ unsigned_word end_block,
+ unsigned_word start_arg,
+ unsigned_word end_arg)
+{
+ DTRACE(stack,
+ ("write_stack_arguments(device=%s, arg=0x%lx, start_block=0x%lx, end_block=0x%lx, start_arg=0x%lx, end_arg=0x%lx)\n",
+ device_name(me), (long)arg, (long)start_block, (long)end_block, (long)start_arg, (long)end_arg));
+ if (arg == NULL)
+ device_error(me, "Attempt to write a null array onto the stack\n");
+ /* only copy in arguments, memory is already zero */
+ for (; *arg != NULL; arg++) {
+ int len = strlen(*arg)+1;
+ unsigned_word target_start_block;
+ DTRACE(stack,
+ ("write_stack_arguments() write %s=%s at %s=0x%lx %s=0x%lx %s=0x%lx\n",
+ "**arg", *arg, "start_block", (long)start_block,
+ "len", (long)len, "start_arg", (long)start_arg));
+ if (psim_write_memory(device_system(me), 0, *arg,
+ start_block, len,
+ 0/*violate_readonly*/) != len)
+ device_error(me, "Write of **arg (%s) at 0x%lx of stack failed\n",
+ *arg, (unsigned long)start_block);
+ target_start_block = H2T_word(start_block);
+ if (psim_write_memory(device_system(me), 0, &target_start_block,
+ start_arg, sizeof(target_start_block),
+ 0) != sizeof(target_start_block))
+ device_error(me, "Write of *arg onto stack failed\n");
+ start_block += ALIGN_8(len);
+ start_arg += sizeof(start_block);
+ }
+ start_arg += sizeof(start_block); /*the null at the end*/
+ if (start_block != end_block
+ || ALIGN_8(start_arg) != end_arg)
+ device_error(me, "Probable corrpution of stack arguments\n");
+ DTRACE(stack, ("write_stack_arguments() = void\n"));
+}
+
+static void
+create_ppc_elf_stack_frame(device *me,
+ unsigned_word bottom_of_stack,
+ char **argv,
+ char **envp)
+{
+ /* fixme - this is over aligned */
+
+ /* information block */
+ const unsigned sizeof_envp_block = sizeof_argument_strings(envp);
+ const unsigned_word start_envp_block = bottom_of_stack - sizeof_envp_block;
+ const unsigned sizeof_argv_block = sizeof_argument_strings(argv);
+ const unsigned_word start_argv_block = start_envp_block - sizeof_argv_block;
+
+ /* auxiliary vector - contains only one entry */
+ const unsigned sizeof_aux_entry = 2*sizeof(unsigned_word); /* magic */
+ const unsigned_word start_aux = start_argv_block - ALIGN_8(sizeof_aux_entry);
+
+ /* environment points (including null sentinal) */
+ const unsigned sizeof_envp = sizeof_arguments(envp);
+ const unsigned_word start_envp = start_aux - sizeof_envp;
+
+ /* argument pointers (including null sentinal) */
+ const int argc = number_of_arguments(argv);
+ const unsigned sizeof_argv = sizeof_arguments(argv);
+ const unsigned_word start_argv = start_envp - sizeof_argv;
+
+ /* link register save address - alligned to a 16byte boundary */
+ const unsigned_word top_of_stack = ((start_argv
+ - 2 * sizeof(unsigned_word))
+ & ~0xf);
+
+ /* install arguments on stack */
+ write_stack_arguments(me, envp,
+ start_envp_block, bottom_of_stack,
+ start_envp, start_aux);
+ write_stack_arguments(me, argv,
+ start_argv_block, start_envp_block,
+ start_argv, start_envp);
+
+ /* set up the registers */
+ psim_write_register(device_system(me), -1,
+ &top_of_stack, "sp", cooked_transfer);
+ psim_write_register(device_system(me), -1,
+ &argc, "r3", cooked_transfer);
+ psim_write_register(device_system(me), -1,
+ &start_argv, "r4", cooked_transfer);
+ psim_write_register(device_system(me), -1,
+ &start_envp, "r5", cooked_transfer);
+ psim_write_register(device_system(me), -1,
+ &start_aux, "r6", cooked_transfer);
+}
+
+static void
+create_ppc_aix_stack_frame(device *me,
+ unsigned_word bottom_of_stack,
+ char **argv,
+ char **envp)
+{
+ unsigned_word core_envp;
+ unsigned_word core_argv;
+ unsigned_word core_argc;
+ unsigned_word core_aux;
+ unsigned_word top_of_stack;
+
+ /* cheat - create an elf stack frame */
+ create_ppc_elf_stack_frame(me, bottom_of_stack, argv, envp);
+
+ /* extract argument addresses from registers */
+ psim_read_register(device_system(me), 0,
+ &top_of_stack, "r1", cooked_transfer);
+ psim_read_register(device_system(me), 0,
+ &core_argc, "r3", cooked_transfer);
+ psim_read_register(device_system(me), 0,
+ &core_argv, "r4", cooked_transfer);
+ psim_read_register(device_system(me), 0,
+ &core_envp, "r5", cooked_transfer);
+ psim_read_register(device_system(me), 0,
+ &core_aux, "r6", cooked_transfer);
+
+ /* extract arguments from registers */
+ device_error(me, "Unfinished procedure create_ppc_aix_stack_frame\n");
+}
+
+
+
+static int
+hw_stack_ioctl_callback(device *me,
+ cpu *processor,
+ unsigned_word cia,
+ va_list ap)
+{
+ unsigned_word stack_pointer;
+ const char *stack_type;
+ char **argv;
+ char **envp;
+ stack_pointer = va_arg(ap, unsigned_word);
+ argv = va_arg(ap, char **);
+ envp = va_arg(ap, char **);
+ DTRACE(stack,
+ ("stack_ioctl_callback(me=0x%lx:%s processor=0x%lx cia=0x%lx argv=0x%lx envp=0x%lx)\n",
+ (long)me, device_name(me), (long)processor, (long)cia, (long)argv, (long)envp));
+ stack_type = device_find_string_property(me, "stack-type");
+ if (strcmp(stack_type, "ppc-elf") == 0)
+ create_ppc_elf_stack_frame(me, stack_pointer, argv, envp);
+ else if (strcmp(stack_type, "ppc-xcoff") == 0)
+ create_ppc_aix_stack_frame(me, stack_pointer, argv, envp);
+ else if (strcmp(stack_type, "none") != 0)
+ device_error(me, "Unknown initial stack frame type %s\n", stack_type);
+ DTRACE(stack,
+ ("stack_ioctl_callback() = void\n"));
+ return 0;
+}
+
+static device_callbacks const hw_stack_callbacks = {
+ { NULL, },
+ { NULL, }, /* address */
+ { NULL, }, /* IO */
+ { NULL, }, /* DMA */
+ { NULL, }, /* interrupt */
+ { NULL, }, /* unit */
+ NULL, /* instance */
+ hw_stack_ioctl_callback,
+};
+
+const device_descriptor hw_init_device_descriptor[] = {
+ { "file", NULL, &hw_file_callbacks },
+ { "data", NULL, &hw_data_callbacks },
+ { "load-binary", NULL, &hw_binary_callbacks },
+ { "map-binary", NULL, &hw_binary_callbacks },
+ { "stack", NULL, &hw_stack_callbacks },
+ { NULL },
+};
+
+#endif _HW_INIT_C_
diff --git a/sim/ppc/hw_register.c b/sim/ppc/hw_register.c
new file mode 100644
index 0000000..4c812b1
--- /dev/null
+++ b/sim/ppc/hw_register.c
@@ -0,0 +1,125 @@
+/* This file is part of the program psim.
+
+ Copyright (C) 1994-1996, 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.
+
+ */
+
+
+#ifndef _HW_REGISTER_C_
+#define _HW_REGISTER_C_
+
+#include "device_table.h"
+#include <stdlib.h>
+#include "psim.h"
+
+/* DEVICE
+
+ register - dummy device to initialize processor registers
+
+ DESCRIPTION
+
+ The properties of this device are used, during initialization, to
+ specify the initial value of various processor registers. The
+ property name specifying the register to be initialized with the
+ special form <cpu-nr>.<register> being used to initialize a
+ specific processor's register (eg 0.pc).
+
+ Because, when the device tree is created, overriding properties are
+ entered into the tree before any default values, this device must
+ initialize registers in newest (default) to oldest (overriding)
+ property order.
+
+ The actual registers (for a given target) are defined in the file
+ registers.c.
+
+ This device is normally a child of the /openprom/init node.
+
+ EXAMPLE
+
+ Given a device tree containing the entry:
+
+ | /openprom/init/register/pc 0xfff00cf0
+
+ then specifying the command line option:
+
+ | -o '/openprom/init/register/pc 0x0'
+
+ would override the initial value of processor zero's program
+ counter. The resultant device tree tree containing:
+
+ | /openprom/init/register/0.pc 0x0
+ | /openprom/init/register/pc 0xfff00cf0
+
+ and would be processed last to first resulting in the sequence: set
+ all program counters to 0xfff00cf0; set processor zero's program
+ counter to zero. */
+
+static void
+do_register_init(device *me,
+ const device_property *prop)
+{
+ psim *system = device_system(me);
+ if (prop != NULL) {
+ const char *name = prop->name;
+ unsigned32 value = device_find_integer_property(me, name);
+ int processor;
+
+ do_register_init(me, device_next_property(prop));
+
+ if (strchr(name, '.') == NULL) {
+ processor = -1;
+ DTRACE(register, ("%s=0x%lx\n", name, (unsigned long)value));
+ }
+ else {
+ char *end;
+ processor = strtoul(name, &end, 0);
+ ASSERT(end[0] == '.');
+ name = end+1;
+ DTRACE(register, ("%d.%s=0x%lx\n", processor, name,
+ (unsigned long)value));
+ }
+ psim_write_register(system, processor, /* all processors */
+ &value,
+ name,
+ cooked_transfer);
+ }
+}
+
+
+static void
+register_init_data_callback(device *me)
+{
+ const device_property *prop = device_find_property(me, NULL);
+ do_register_init(me, prop);
+}
+
+
+static device_callbacks const register_callbacks = {
+ { NULL, register_init_data_callback, },
+ { NULL, }, /* address */
+ { NULL, }, /* IO */
+ { NULL, }, /* DMA */
+ { NULL, }, /* interrupt */
+ { NULL, }, /* unit */
+};
+
+const device_descriptor hw_register_device_descriptor[] = {
+ { "register", NULL, &register_callbacks },
+ { NULL },
+};
+
+#endif _HW_REGISTER_C_
diff --git a/sim/ppc/hw_vm.c b/sim/ppc/hw_vm.c
new file mode 100644
index 0000000..df861d4
--- /dev/null
+++ b/sim/ppc/hw_vm.c
@@ -0,0 +1,269 @@
+/* This file is part of the program psim.
+
+ Copyright (C) 1994-1996, 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.
+
+ */
+
+
+#ifndef _HW_VM_C_
+#define _HW_VM_C_
+
+#include "device_table.h"
+#include "cpu.h"
+
+#include <signal.h>
+
+/* DEVICE
+
+ vm - virtual memory device for user simulation modes
+
+ DESCRIPTION
+
+ In user mode, mapped text, data and stack addresses are managed by
+ the core. Unmapped addresses are passed onto this device (because
+ it establishes its self as the fallback device) for processing.
+
+ During initialization, children of this device will request the
+ mapping of the initial text and data segments. Those requests are
+ passed onto the core device so that that may establish the initial
+ memory regions.
+
+ Once the simulation has started (as noted above) any access to an
+ unmapped address range will be passed down to this device as an IO
+ access. This device will then either attach additional memory to
+ the core device or signal the access as being invalid.
+
+ The IOCTL function is used to notify this device of any changes to
+ the users `brk' point.
+
+ PROPERTIES
+
+ stack-base = <number>
+
+ Specifies the lower address of the stack segment in the users
+ virtual address space. The initial stack page is defined by
+ stack-base + nr-bytes.
+
+ nr-bytes = <number>
+
+ Specifies the maximum size of the stack segment in the users
+ address space.
+
+ */
+
+typedef struct _hw_vm_device {
+ /* area of memory valid for stack addresses */
+ unsigned_word stack_base; /* min possible stack value */
+ unsigned_word stack_bound;
+ unsigned_word stack_lower_limit;
+ /* area of memory valid for heap addresses */
+ unsigned_word heap_base;
+ unsigned_word heap_bound;
+ unsigned_word heap_upper_limit;
+} hw_vm_device;
+
+
+static void
+hw_vm_init_address_callback(device *me)
+{
+ hw_vm_device *vm = (hw_vm_device*)device_data(me);
+
+ /* revert the stack/heap variables to their defaults */
+ vm->stack_base = device_find_integer_property(me, "stack-base");
+ vm->stack_bound = (vm->stack_base
+ + device_find_integer_property(me, "nr-bytes"));
+ vm->stack_lower_limit = vm->stack_bound;
+ vm->heap_base = 0;
+ vm->heap_bound = 0;
+ vm->heap_upper_limit = 0;
+
+ /* establish this device as the default memory handler */
+ device_attach_address(device_parent(me),
+ device_name(me),
+ attach_callback + 1,
+ 0 /*address space - ignore*/,
+ 0 /*addr - ignore*/,
+ (((unsigned)0)-1) /*nr_bytes - ignore*/,
+ access_read_write /*access*/,
+ me);
+}
+
+
+static void
+hw_vm_attach_address(device *me,
+ const char *name,
+ attach_type attach,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ access_type access,
+ device *who) /*callback/default*/
+{
+ hw_vm_device *vm = (hw_vm_device*)device_data(me);
+ /* update end of bss if necessary */
+ if (vm->heap_base < addr + nr_bytes) {
+ vm->heap_base = addr + nr_bytes;
+ vm->heap_bound = addr + nr_bytes;
+ vm->heap_upper_limit = addr + nr_bytes;
+ }
+ device_attach_address(device_parent(me),
+ device_name(me),
+ attach_raw_memory,
+ 0 /*address space*/,
+ addr,
+ nr_bytes,
+ access,
+ me);
+}
+
+
+static unsigned
+hw_vm_add_space(device *me,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ cpu *processor,
+ unsigned_word cia)
+{
+ hw_vm_device *vm = (hw_vm_device*)device_data(me);
+ unsigned_word block_addr;
+ unsigned block_nr_bytes;
+
+ /* an address in the stack area, allocate just down to the addressed
+ page */
+ if (addr >= vm->stack_base && addr < vm->stack_lower_limit) {
+ block_addr = FLOOR_PAGE(addr);
+ block_nr_bytes = vm->stack_lower_limit - block_addr;
+ vm->stack_lower_limit = block_addr;
+ }
+ /* an address in the heap area, allocate all of the required heap */
+ else if (addr >= vm->heap_upper_limit && addr < vm->heap_bound) {
+ block_addr = vm->heap_upper_limit;
+ block_nr_bytes = vm->heap_bound - vm->heap_upper_limit;
+ vm->heap_upper_limit = vm->heap_bound;
+ }
+ /* oops - an invalid address - abort the cpu */
+ else if (processor != NULL) {
+ cpu_halt(processor, cia, was_signalled, SIGSEGV);
+ return 0;
+ }
+ /* 2*oops - an invalid address and no processor */
+ else {
+ return 0;
+ }
+
+ /* got the parameters, allocate the space */
+ device_attach_address(device_parent(me),
+ "vm@0x0,0", /* stop remap */
+ attach_raw_memory,
+ 0 /*address space*/,
+ block_addr,
+ block_nr_bytes,
+ access_read_write,
+ me);
+ return block_nr_bytes;
+}
+
+
+static unsigned
+hw_vm_io_read_buffer_callback(device *me,
+ void *dest,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ cpu *processor,
+ unsigned_word cia)
+{
+ if (hw_vm_add_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) {
+ memset(dest, 0, nr_bytes); /* always initialized to zero */
+ return nr_bytes;
+ }
+ else
+ return 0;
+}
+
+
+static unsigned
+hw_vm_io_write_buffer_callback(device *me,
+ const void *source,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ cpu *processor,
+ unsigned_word cia)
+{
+ if (hw_vm_add_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) {
+ return device_dma_write_buffer(device_parent(me), source,
+ space, addr,
+ nr_bytes,
+ 0/*violate_read_only*/);
+ }
+ else
+ return 0;
+}
+
+
+static int
+hw_vm_ioctl_callback(device *me,
+ cpu *processor,
+ unsigned_word cia,
+ va_list ap)
+{
+ /* While the caller is notified that the heap has grown by the
+ requested amount, the heap is actually extended out to a page
+ boundary. */
+ hw_vm_device *vm = (hw_vm_device*)device_data(me);
+ unsigned_word requested_break = va_arg(ap, unsigned_word);
+ unsigned_word new_break = ALIGN_8(requested_break);
+ unsigned_word old_break = vm->heap_bound;
+ signed_word delta = new_break - old_break;
+ if (delta > 0)
+ vm->heap_bound = ALIGN_PAGE(new_break);
+ return 0;
+}
+
+
+static device_callbacks const hw_vm_callbacks = {
+ { hw_vm_init_address_callback, },
+ { hw_vm_attach_address,
+ passthrough_device_address_detach, },
+ { hw_vm_io_read_buffer_callback,
+ hw_vm_io_write_buffer_callback, },
+ { NULL, passthrough_device_dma_write_buffer, },
+ { NULL, }, /* interrupt */
+ { generic_device_unit_decode,
+ generic_device_unit_encode, },
+ NULL, /* instance */
+ hw_vm_ioctl_callback,
+};
+
+
+static void *
+hw_vm_create(const char *name,
+ const device_unit *address,
+ const char *args,
+ device *parent)
+{
+ hw_vm_device *vm = ZALLOC(hw_vm_device);
+ return vm;
+}
+
+const device_descriptor hw_vm_device_descriptor[] = {
+ { "vm", hw_vm_create, &hw_vm_callbacks },
+ { NULL },
+};
+
+#endif _HW_VM_C_