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 / corefile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-22  |  11.5 KB  |  509 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 _CORE_C_
  23. #define _CORE_C_
  24.  
  25. #include "basics.h"
  26. #include "device_table.h"
  27. #include "corefile.h"
  28.  
  29.  
  30. typedef struct _core_mapping core_mapping;
  31. struct _core_mapping {
  32.   /* ram map */
  33.   int free_buffer;
  34.   void *buffer;
  35.   /* device map */
  36.   device *device;
  37.   /* common */
  38.   int space;
  39.   unsigned_word base;
  40.   unsigned_word bound;
  41.   unsigned nr_bytes;
  42.   core_mapping *next;
  43. };
  44.  
  45. struct _core_map {
  46.   core_mapping *first;
  47.   core_mapping *default_map;
  48. };
  49.  
  50. typedef enum {
  51.   core_read_map,
  52.   core_write_map,
  53.   core_execute_map,
  54.   nr_core_map_types,
  55. } core_map_types;
  56.  
  57. struct _core {
  58.   core_map map[nr_core_map_types];
  59. };
  60.  
  61.  
  62. INLINE_CORE\
  63. (core *)
  64. core_create(device *root)
  65. {
  66.   root = device_tree_find_device(root, "/");
  67.   ASSERT(strcmp(device_name(root), "core") == 0);
  68.   return device_data(root);
  69. }
  70.  
  71.  
  72. STATIC_INLINE_CORE\
  73. (void)
  74. core_init(core *memory)
  75. {
  76.   core_map_types access_type;
  77.   for (access_type = 0;
  78.        access_type < nr_core_map_types;
  79.        access_type++) {
  80.     core_map *map = memory->map + access_type;
  81.     /* blow away old mappings */
  82.     core_mapping *curr = map->first;
  83.     while (curr != NULL) {
  84.       core_mapping *tbd = curr;
  85.       curr = curr->next;
  86.       if (tbd->free_buffer) {
  87.     ASSERT(tbd->buffer != NULL);
  88.     zfree(tbd->buffer);
  89.       }
  90.       zfree(tbd);
  91.     }
  92.     map->first = NULL;
  93.     /* blow away the default */
  94.     if (map->default_map != NULL) {
  95.       ASSERT(map->default_map->buffer == NULL);
  96.       zfree(map->default_map);
  97.     }
  98.     map->default_map = NULL;
  99.   }
  100. }
  101.  
  102.  
  103.  
  104. /* the core has three sub mappings that the more efficient
  105.    read/write fixed quantity functions use */
  106.  
  107. INLINE_CORE\
  108. (core_map *)
  109. core_readable(core *memory)
  110. {
  111.   return memory->map + core_read_map;
  112. }
  113.  
  114. INLINE_CORE\
  115. (core_map *)
  116. core_writeable(core *memory)
  117. {
  118.   return memory->map + core_write_map;
  119. }
  120.  
  121. INLINE_CORE\
  122. (core_map *)
  123. core_executable(core *memory)
  124. {
  125.   return memory->map + core_execute_map;
  126. }
  127.  
  128.  
  129.  
  130. STATIC_INLINE_CORE\
  131. (core_mapping *)
  132. new_core_mapping(attach_type attach,
  133.          int space,
  134.          unsigned_word addr,
  135.          unsigned nr_bytes,
  136.          device *device,
  137.          void *buffer,
  138.          int free_buffer)
  139. {
  140.   core_mapping *new_mapping = ZALLOC(core_mapping);
  141.   switch (attach) {
  142.   case attach_default:
  143.   case attach_callback:
  144.     new_mapping->device = device;
  145.     break;
  146.   case attach_raw_memory:
  147.     new_mapping->buffer = buffer;
  148.     new_mapping->free_buffer = free_buffer;
  149.     break;
  150.   default:
  151.     error("new_core_mapping() - internal error - unknown attach type %d\n",
  152.       attach);
  153.   }
  154.   /* common */
  155.   new_mapping->space = space;
  156.   new_mapping->base = addr;
  157.   new_mapping->nr_bytes = nr_bytes;
  158.   new_mapping->bound = addr + (nr_bytes - 1);
  159.   return new_mapping;
  160. }
  161.  
  162.  
  163. STATIC_INLINE_CORE\
  164. (void)
  165. core_map_attach(core_map *access_map,
  166.         attach_type attach,
  167.         int space,
  168.         unsigned_word addr,
  169.         unsigned nr_bytes, /* host limited */
  170.         device *device, /*callback/default*/
  171.         void *buffer, /*raw_memory*/
  172.         int free_buffer) /*raw_memory*/
  173. {
  174.   if (attach == attach_default) {
  175.     if (access_map->default_map != NULL)
  176.       error("core_map_attach() default mapping already in place\n");
  177.     ASSERT(buffer == NULL);
  178.     access_map->default_map = new_core_mapping(attach, 
  179.                            space, addr, nr_bytes,
  180.                            device, buffer, free_buffer);
  181.   }
  182.   else {
  183.     /* find the insertion point for this additional mapping and insert */
  184.     core_mapping *next_mapping;
  185.     core_mapping **last_mapping;
  186.  
  187.     /* actually do occasionally get a zero size map */
  188.     if (nr_bytes == 0)
  189.       error("core_map_attach() size == 0\n");
  190.  
  191.     /* find the insertion point (between last/next) */
  192.     next_mapping = access_map->first;
  193.     last_mapping = &access_map->first;
  194.     while(next_mapping != NULL && next_mapping->bound < addr) {
  195.       /* assert: next_mapping->base > all bases before next_mapping */
  196.       /* assert: next_mapping->bound >= all bounds before next_mapping */
  197.       last_mapping = &next_mapping->next;
  198.       next_mapping = next_mapping->next;
  199.     }
  200.  
  201.     /* check insertion point correct */
  202.     if (next_mapping != NULL && next_mapping->base < (addr + (nr_bytes - 1))) {
  203.       error("core_map_attach() map overlap\n");
  204.     }
  205.  
  206.     /* create/insert the new mapping */
  207.     *last_mapping = new_core_mapping(attach,
  208.                      space, addr, nr_bytes,
  209.                      device, buffer, free_buffer);
  210.     (*last_mapping)->next = next_mapping;
  211.   }
  212. }
  213.  
  214.  
  215. INLINE_CORE\
  216. (void)
  217. core_attach(core *memory,
  218.         attach_type attach,
  219.         int space,
  220.         access_type access,
  221.         unsigned_word addr,
  222.         unsigned nr_bytes, /* host limited */
  223.         device *device) /*callback/default*/
  224. {
  225.   core_map_types access_map;
  226.   int free_buffer = 0;
  227.   void *buffer = NULL;
  228.   ASSERT(attach == attach_default || nr_bytes > 0);
  229.   if (attach == attach_raw_memory)
  230.     buffer = zalloc(nr_bytes);
  231.   for (access_map = 0; 
  232.        access_map < nr_core_map_types;
  233.        access_map++) {
  234.     switch (access_map) {
  235.     case core_read_map:
  236.       if (access & access_read)
  237.     core_map_attach(memory->map + access_map,
  238.             attach,
  239.             space, addr, nr_bytes,
  240.             device, buffer, !free_buffer);
  241.       free_buffer ++;
  242.       break;
  243.     case core_write_map:
  244.       if (access & access_write)
  245.     core_map_attach(memory->map + access_map,
  246.             attach,
  247.             space, addr, nr_bytes,
  248.             device, buffer, !free_buffer);
  249.       free_buffer ++;
  250.       break;
  251.     case core_execute_map:
  252.       if (access & access_exec)
  253.     core_map_attach(memory->map + access_map,
  254.             attach,
  255.             space, addr, nr_bytes,
  256.             device, buffer, !free_buffer);
  257.       free_buffer ++;
  258.       break;
  259.     default:
  260.       error("core_attach() internal error\n");
  261.       break;
  262.     }
  263.   }
  264.   ASSERT(free_buffer > 0); /* must attach to at least one thing */
  265. }
  266.  
  267.  
  268. STATIC_INLINE_CORE\
  269. (core_mapping *)
  270. core_map_find_mapping(core_map *map,
  271.               unsigned_word addr,
  272.               unsigned nr_bytes,
  273.               cpu *processor,
  274.               unsigned_word cia,
  275.               int abort) /*either 0 or 1 - helps inline */
  276. {
  277.   core_mapping *mapping = map->first;
  278.   ASSERT((addr & (nr_bytes - 1)) == 0); /* must be aligned */
  279.   ASSERT((addr + (nr_bytes - 1)) >= addr); /* must not wrap */
  280.   while (mapping != NULL) {
  281.     if (addr >= mapping->base
  282.     && (addr + (nr_bytes - 1)) <= mapping->bound)
  283.       return mapping;
  284.     mapping = mapping->next;
  285.   }
  286.   if (map->default_map != NULL)
  287.     return map->default_map;
  288.   if (abort)
  289.     error("core_find_mapping() - access to unmaped address, attach a default map to handle this - addr=0x%x nr_bytes=0x%x processor=0x%x cia=0x%x\n",
  290.       addr, nr_bytes, processor, cia);
  291.   return NULL;
  292. }
  293.  
  294.  
  295. STATIC_INLINE_CORE\
  296. (void *)
  297. core_translate(core_mapping *mapping,
  298.              unsigned_word addr)
  299. {
  300.   return (void *)(((char *)mapping->buffer) + addr - mapping->base);
  301. }
  302.  
  303.  
  304. INLINE_CORE\
  305. (unsigned)
  306. core_map_read_buffer(core_map *map,
  307.              void *buffer,
  308.              unsigned_word addr,
  309.              unsigned len)
  310. {
  311.   unsigned count;
  312.   unsigned_1 byte;
  313.   for (count = 0; count < len; count++) {
  314.     unsigned_word raddr = addr + count;
  315.     core_mapping *mapping =
  316.       core_map_find_mapping(map,
  317.                 raddr, 1,
  318.                 NULL, /*processor*/
  319.                 0, /*cia*/
  320.                 0); /*dont-abort*/
  321.     if (mapping == NULL)
  322.       break;
  323.     if (mapping->device != NULL) {
  324.       if (device_io_read_buffer(mapping->device,
  325.                 &byte,
  326.                 mapping->space,
  327.                 raddr,
  328.                 1, /* nr_bytes */
  329.                 0, /*processor*/
  330.                 0 /*cpu*/) != 1)
  331.     break;
  332.     }
  333.     else
  334.       byte = *(unsigned_1*)core_translate(mapping,
  335.                         raddr);
  336.     ((unsigned_1*)buffer)[count] = T2H_1(byte);
  337.   }
  338.   return count;
  339. }
  340.  
  341.  
  342. INLINE_CORE\
  343. (unsigned)
  344. core_map_write_buffer(core_map *map,
  345.               const void *buffer,
  346.               unsigned_word addr,
  347.               unsigned len)
  348. {
  349.   unsigned count;
  350.   unsigned_1 byte;
  351.   for (count = 0; count < len; count++) {
  352.     unsigned_word raddr = addr + count;
  353.     core_mapping *mapping = core_map_find_mapping(map,
  354.                           raddr, 1,
  355.                           NULL, /*processor*/
  356.                           0, /*cia*/
  357.                           0); /*dont-abort*/
  358.     if (mapping == NULL)
  359.       break;
  360.     byte = H2T_1(((unsigned_1*)buffer)[count]);
  361.     if (mapping->device != NULL) {
  362.       if (device_io_write_buffer(mapping->device,
  363.                  &byte,
  364.                  mapping->space,
  365.                  raddr,
  366.                  1, /*nr_bytes*/
  367.                  0, /*processor*/
  368.                  0 /*cpu*/) != 1)
  369.     break;
  370.     }
  371.     else
  372.       *(unsigned_1*)core_translate(mapping, raddr) = byte;
  373.   }
  374.   return count;
  375. }
  376.  
  377.  
  378. /* define the read/write 1/2/4/8/word functions */
  379.  
  380. #define N 1
  381. #include "corefile-n.h"
  382. #undef N
  383.  
  384. #define N 2
  385. #include "corefile-n.h"
  386. #undef N
  387.  
  388. #define N 4
  389. #include "corefile-n.h"
  390. #undef N
  391.  
  392. #define N 8
  393. #include "corefile-n.h"
  394. #undef N
  395.  
  396. #define N word
  397. #include "corefile-n.h"
  398. #undef N
  399.  
  400.  
  401. /* Top level core(root) device: core@garbage
  402.  
  403.    The core device captures incomming dma requests and changes them to
  404.    outgoing io requests. */
  405.  
  406. STATIC_INLINE_CORE\
  407. (void)
  408. core_init_address_callback(device *me,
  409.                psim *system)
  410. {
  411.   core *memory = (core*)device_data(me);
  412.   core_init(memory);
  413. }
  414.  
  415.  
  416. STATIC_INLINE_CORE\
  417. (void)
  418. core_attach_address_callback(device *me,
  419.                  const char *name,
  420.                  attach_type attach,
  421.                  int space,
  422.                  unsigned_word addr,
  423.                  unsigned nr_bytes,
  424.                  access_type access,
  425.                  device *who) /*callback/default*/
  426. {
  427.   core *memory = (core*)device_data(me);
  428.   if (space != 0)
  429.     error("core_attach_address_callback() invalid address space\n");
  430.   core_attach(memory,
  431.           attach,
  432.           space,
  433.           access,
  434.           addr,
  435.           nr_bytes,
  436.           who);
  437. }
  438.  
  439.  
  440. STATIC_INLINE_CORE\
  441. (unsigned)
  442. core_dma_read_buffer_callback(device *me,
  443.                   void *dest,
  444.                   int space,
  445.                   unsigned_word addr,
  446.                   unsigned nr_bytes)
  447. {
  448.   core *memory = (core*)device_data(me);
  449.   return core_map_read_buffer(core_readable(memory),
  450.                   dest,
  451.                   addr,
  452.                   nr_bytes);
  453. }
  454.  
  455.  
  456. STATIC_INLINE_CORE\
  457. (unsigned)
  458. core_dma_write_buffer_callback(device *me,
  459.                    const void *source,
  460.                    int space,
  461.                    unsigned_word addr,
  462.                    unsigned nr_bytes,
  463.                    int violate_read_only_section)
  464. {
  465.   core *memory = (core*)device_data(me);
  466.   core_map *map = (violate_read_only_section
  467.            ? core_readable(memory)
  468.            : core_writeable(memory));
  469.   return core_map_write_buffer(map,
  470.                    source,
  471.                    addr,
  472.                    nr_bytes);
  473. }
  474.  
  475. static device_callbacks const core_callbacks = {
  476.   core_init_address_callback,
  477.   ignore_device_init,
  478.   core_attach_address_callback,
  479.   unimp_device_detach_address,
  480.   unimp_device_io_read_buffer,
  481.   unimp_device_io_write_buffer,
  482.   core_dma_read_buffer_callback,
  483.   core_dma_write_buffer_callback,
  484.   unimp_device_interrupt_event,
  485.   unimp_device_child_interrupt_event,
  486.   generic_device_unit_decode,
  487.   generic_device_unit_encode,
  488.   unimp_device_instance_create,
  489.   unimp_device_instance_delete,
  490.   unimp_device_instance_read,
  491.   unimp_device_instance_write,
  492.   unimp_device_instance_seek,
  493.   unimp_device_ioctl,
  494. };
  495.  
  496.  
  497. INLINE_CORE\
  498. (device *)
  499. core_device_create(void)
  500. {
  501.   core *memory = ZALLOC(core);
  502.   device_unit unit_address = { 0 };
  503.   return device_create_from("core", &unit_address,
  504.                 memory, &core_callbacks, NULL);
  505. }
  506.  
  507.  
  508. #endif /* _CORE_C_ */
  509.