Latest changes from Andrew
This commit is contained in:
parent
911026aa8b
commit
8477437c17
6 changed files with 1708 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
255
sim/ppc/hw_disk.c
Normal file
255
sim/ppc/hw_disk.c
Normal file
|
@ -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_ */
|
569
sim/ppc/hw_init.c
Normal file
569
sim/ppc/hw_init.c
Normal file
|
@ -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_
|
125
sim/ppc/hw_register.c
Normal file
125
sim/ppc/hw_register.c
Normal file
|
@ -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, ®ister_callbacks },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#endif _HW_REGISTER_C_
|
269
sim/ppc/hw_vm.c
Normal file
269
sim/ppc/hw_vm.c
Normal file
|
@ -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_
|
Loading…
Reference in a new issue