home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / sim / ppc / emul_generic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-24  |  7.9 KB  |  296 lines

  1. /*  This file is part of the program psim.
  2.  
  3.     Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18.  
  19.     */
  20.  
  21.  
  22. #ifndef _EMUL_GENERIC_C_
  23. #define _EMUL_GENERIC_C_
  24.  
  25. #include "emul_generic.h"
  26.  
  27. #ifndef STATIC_INLINE_EMUL_GENERIC
  28. #define STATIC_INLINE_EMUL_GENERIC STATIC_INLINE
  29. #endif
  30.  
  31.  
  32. STATIC_INLINE_EMUL_GENERIC void
  33. emul_syscall_enter(emul_syscall *emul,
  34.            int call,
  35.            int arg0,
  36.            cpu *processor,
  37.            unsigned_word cia)
  38. {
  39.   printf_filtered("%d:0x%lx:%s(",
  40.           cpu_nr(processor) + 1,
  41.           (long)cia, 
  42.           emul->syscall_descriptor[call].name);
  43. }
  44.  
  45.  
  46. STATIC_INLINE_EMUL_GENERIC void
  47. emul_syscall_exit(emul_syscall *emul,
  48.           int call,
  49.           int arg0,
  50.           cpu *processor,
  51.           unsigned_word cia)
  52. {
  53.   int status = cpu_registers(processor)->gpr[3];
  54.   int error = cpu_registers(processor)->gpr[0];
  55.   printf_filtered(")=%d", status);
  56.   if (error > 0 && error < emul->nr_error_names)
  57.     printf_filtered("[%s]", emul->error_names[error]);
  58.   printf_filtered("\n");
  59. }
  60.  
  61.  
  62. INLINE_EMUL_GENERIC unsigned64
  63. emul_read_gpr64(cpu *processor,
  64.         int g)
  65. {
  66.   unsigned32 hi;
  67.   unsigned32 lo;
  68.   if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) {
  69.     hi = cpu_registers(processor)->gpr[g];
  70.     lo = cpu_registers(processor)->gpr[g+1];
  71.   }
  72.   else {
  73.     lo = cpu_registers(processor)->gpr[g];
  74.     hi = cpu_registers(processor)->gpr[g+1];
  75.   }
  76.   return (INSERTED64(hi, 0, 31) | INSERTED64(lo, 32, 63));
  77. }
  78.  
  79.  
  80. INLINE_EMUL_GENERIC void
  81. emul_write_gpr64(cpu *processor,
  82.          int g,
  83.          unsigned64 val)
  84. {
  85.   unsigned32 hi = EXTRACTED64(val, 0, 31);
  86.   unsigned32 lo = EXTRACTED64(val, 32, 63);
  87.   if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) {
  88.     cpu_registers(processor)->gpr[g] = hi;
  89.     cpu_registers(processor)->gpr[g+1] = lo;
  90.   }
  91.   else {
  92.     cpu_registers(processor)->gpr[g] = lo;
  93.     cpu_registers(processor)->gpr[g+1] = hi;
  94.   }
  95. }
  96.  
  97.  
  98. INLINE_EMUL_GENERIC char *
  99. emul_read_string(char *dest,
  100.          unsigned_word addr,
  101.          unsigned nr_bytes,
  102.          cpu *processor,
  103.          unsigned_word cia)
  104. {
  105.   unsigned nr_moved = 0;
  106.   if (addr == 0)
  107.     return NULL;
  108.   while (1) {
  109.     dest[nr_moved] = vm_data_map_read_1(cpu_data_map(processor),
  110.                     addr + nr_moved,
  111.                     processor, cia);
  112.     if (dest[nr_moved] == '\0' || nr_moved >= nr_bytes)
  113.       break;
  114.     nr_moved++;
  115.   }
  116.   dest[nr_moved] = '\0';
  117.   return dest;
  118. }
  119.  
  120.  
  121. INLINE_EMUL_GENERIC void
  122. emul_write_status(cpu *processor,
  123.           int status,
  124.           int errno)
  125. {
  126.   cpu_registers(processor)->gpr[3] = status;
  127.   if (status < 0)
  128.     cpu_registers(processor)->gpr[0] = errno;
  129.   else
  130.     cpu_registers(processor)->gpr[0] = 0;
  131. }
  132.  
  133.  
  134. INLINE_EMUL_GENERIC unsigned_word
  135. emul_read_word(unsigned_word addr,
  136.            cpu *processor,
  137.            unsigned_word cia)
  138. {
  139.   return vm_data_map_read_word(cpu_data_map(processor),
  140.                    addr,
  141.                    processor, cia);
  142. }
  143.  
  144.  
  145. INLINE_EMUL_GENERIC void
  146. emul_write_word(unsigned_word addr,
  147.         unsigned_word buf,
  148.         cpu *processor,
  149.         unsigned_word cia)
  150. {
  151.   vm_data_map_write_word(cpu_data_map(processor),
  152.              addr,
  153.              buf,
  154.              processor, cia);
  155. }
  156.  
  157.  
  158. INLINE_EMUL_GENERIC void
  159. emul_write_buffer(const void *source,
  160.           unsigned_word addr,
  161.           unsigned nr_bytes,
  162.           cpu *processor,
  163.           unsigned_word cia)
  164. {
  165.   int nr_moved;
  166.   for (nr_moved = 0; nr_moved < nr_bytes; nr_moved++) {
  167.     vm_data_map_write_1(cpu_data_map(processor),
  168.             addr + nr_moved,
  169.             ((const char*)source)[nr_moved],
  170.             processor, cia);
  171.   }
  172. }
  173.  
  174.  
  175. INLINE_EMUL_GENERIC void
  176. emul_read_buffer(void *dest,
  177.          unsigned_word addr,
  178.          unsigned nr_bytes,
  179.          cpu *processor,
  180.          unsigned_word cia)
  181. {
  182.   int nr_moved;
  183.   for (nr_moved = 0; nr_moved < nr_bytes; nr_moved++) {
  184.     ((char*)dest)[nr_moved] = vm_data_map_read_1(cpu_data_map(processor),
  185.                          addr + nr_moved,
  186.                          processor, cia);
  187.   }
  188. }
  189.  
  190.  
  191. INLINE_EMUL_GENERIC void
  192. emul_do_system_call(os_emul_data *emul_data,
  193.             emul_syscall *emul,
  194.             unsigned call,
  195.             const int arg0,
  196.             cpu *processor,
  197.             unsigned_word cia)
  198. {
  199.   emul_syscall_handler *handler = NULL;
  200.   if (call >= emul->nr_system_calls)
  201.     error("do_call() os_emul call %d out-of-range\n", call);
  202.  
  203.   handler = emul->syscall_descriptor[call].handler;
  204.   if (handler == NULL)
  205.     error("do_call() unimplemented call %d\n", call);
  206.  
  207.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  208.     emul_syscall_enter(emul, call, arg0, processor, cia);
  209.  
  210.   cpu_registers(processor)->gpr[0] = 0; /* default success */
  211.   handler(emul_data, call, arg0, processor, cia);
  212.  
  213.   if (WITH_TRACE && ppc_trace[trace_os_emul])
  214.     emul_syscall_exit(emul, call, arg0, processor, cia);
  215. }
  216.  
  217.  
  218. /* default size for the first bank of memory */
  219.  
  220. #ifndef OEA_MEMORY_SIZE
  221. #define OEA_MEMORY_SIZE 0x100000
  222. #endif
  223.  
  224.  
  225. /* Add options to the device tree */
  226.  
  227. INLINE_EMUL_GENERIC void
  228. emul_add_tree_options(device *tree,
  229.               bfd *image,
  230.               const char *emul,
  231.               const char *env,
  232.               int oea_interrupt_prefix)
  233. {
  234.   int little_endian = 0;
  235.  
  236.   /* sort out little endian */
  237.   if (device_find_property(tree, "/options/little-endian?"))
  238.     little_endian = device_find_boolean_property(tree, "/options/little-endian?");
  239.   else {
  240. #ifdef bfd_little_endian    /* new bfd */
  241.     little_endian = (image != NULL && bfd_little_endian(image));
  242. #else
  243.     little_endian = (image != NULL &&
  244.              !image->xvec->byteorder_big_p);
  245. #endif
  246.     device_tree_add_parsed(tree, "/options/little-endian? %s",
  247.                little_endian ? "true" : "false");
  248.   }
  249.  
  250.   /* misc other stuff */
  251.   device_tree_add_parsed(tree, "/openprom/options/oea-memory-size 0x%x",
  252.              OEA_MEMORY_SIZE);
  253.   device_tree_add_parsed(tree, "/openprom/options/oea-interrupt-prefix %d",
  254.              oea_interrupt_prefix);
  255.   device_tree_add_parsed(tree, "/openprom/options/smp 1");
  256.   device_tree_add_parsed(tree, "/openprom/options/env %s", env);
  257.   device_tree_add_parsed(tree, "/openprom/options/os-emul %s", emul);
  258.   device_tree_add_parsed(tree, "/openprom/options/strict-alignment? %s",
  259.              (WITH_ALIGNMENT == STRICT_ALIGNMENT || little_endian)
  260.              ? "true" : "false");
  261.   device_tree_add_parsed(tree, "/openprom/options/floating-point? %s",
  262.              WITH_FLOATING_POINT ? "true" : "false");
  263.   device_tree_add_parsed(tree, "/openprom/options/model \"%s",
  264.              model_name[WITH_DEFAULT_MODEL]);
  265.   device_tree_add_parsed(tree, "/openprom/options/model-issue %d",
  266.              MODEL_ISSUE_IGNORE);
  267. }
  268.  
  269. INLINE_EMUL_GENERIC void
  270. emul_add_tree_hardware(device *root)
  271. {
  272.   /* add some memory */
  273.   if (device_tree_find_device(root, "/memory") == NULL) {
  274.     unsigned_word memory_size =
  275.       device_find_integer_property(root, "/openprom/options/oea-memory-size");
  276.     device_tree_add_parsed(root, "/memory@0/reg { 0x0 0x%lx",
  277.                (unsigned long)memory_size);
  278.     /* what about allocated? */
  279.   }
  280.   /* an eeprom */
  281.   device_tree_add_parsed(root, "/openprom/eeprom@0xfff00000/reg { 0xfff00000 0x3000");
  282.   /* the IO bus */
  283.   device_tree_add_parsed(root, "/iobus@0x80000000/reg { 0x80000000 0x400000");
  284.   device_tree_add_parsed(root, "/iobus/console@0x000000/reg { 0x000000 16");
  285.   device_tree_add_parsed(root, "/iobus/halt@0x100000/reg    { 0x100000  4");
  286.   device_tree_add_parsed(root, "/iobus/icu@0x200000/reg     { 0x200000  8");
  287.   device_tree_add_parsed(root, "/iobus/icu > 0 0 /iobus/icu");
  288.   device_tree_add_parsed(root, "/iobus/icu > 1 1 /iobus/icu");
  289.   /* chosen etc */
  290.   device_tree_add_parsed(root, "/chosen/stdin */iobus/console");
  291.   device_tree_add_parsed(root, "/chosen/stdout !/chosen/stdin");
  292.   device_tree_add_parsed(root, "/chosen/memory */memory");
  293. }
  294.  
  295. #endif /* _SYSTEM_C_ */
  296.