/[gxemul]/trunk/src/devices/dev_ram.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_ram.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 6 by dpavlin, Mon Oct 8 16:18:11 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_ram.c,v 1.14 2005/05/23 14:22:02 debug Exp $   *  $Id: dev_ram.c,v 1.22 2006/09/19 10:50:08 debug Exp $
29   *     *  
30   *  A generic RAM (memory) device.  Can also be used to mirror/alias another   *  A generic RAM (memory) device. Can also be used to mirror/alias another
31   *  part of RAM.   *  part of RAM.
32   */   */
33    
# Line 37  Line 37 
37  #include <sys/types.h>  #include <sys/types.h>
38  #include <sys/mman.h>  #include <sys/mman.h>
39    
 #include "console.h"  
40  #include "cpu.h"  #include "cpu.h"
41  #include "devices.h"  #include "devices.h"
42    #include "machine.h"
43  #include "memory.h"  #include "memory.h"
44  #include "misc.h"  #include "misc.h"
45    
# Line 50  struct ram_data { Line 50  struct ram_data {
50          int             mode;          int             mode;
51          uint64_t        otheraddress;          uint64_t        otheraddress;
52    
53            /*  If mode = DEV_RAM_MIRROR:  */
54            uint64_t        offset;
55    
56          /*  If mode = DEV_RAM_RAM:  */          /*  If mode = DEV_RAM_RAM:  */
57          unsigned char   *data;          unsigned char   *data;
58          uint64_t        length;          uint64_t        length;
59  };  };
60    
61    
62  /*  DEVICE_ACCESS(ram)
  *  dev_ram_access():  
  */  
 int dev_ram_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
63  {  {
64          struct ram_data *d = extra;          struct ram_data *d = extra;
65    
# Line 101  int dev_ram_access(struct cpu *cpu, stru Line 99  int dev_ram_access(struct cpu *cpu, stru
99    
100  /*  /*
101   *  dev_ram_init():   *  dev_ram_init():
102     *
103     *  Initializes a RAM or mirror device. Things get a bit complicated because
104     *  of dyntrans (i.e. mirrored memory ranges should be entered into the
105     *  translation arrays just as normal memory and other devices are).
106   */   */
107  void dev_ram_init(struct memory *mem, uint64_t baseaddr, uint64_t length,  void dev_ram_init(struct machine *machine, uint64_t baseaddr, uint64_t length,
108          int mode, uint64_t otheraddress)          int mode, uint64_t otheraddress)
109  {  {
110          struct ram_data *d;          struct ram_data *d;
111            int flags = DM_DEFAULT, points_to_ram = 1;
112    
113          d = malloc(sizeof(struct ram_data));          d = malloc(sizeof(struct ram_data));
114          if (d == NULL) {          if (d == NULL) {
# Line 115  void dev_ram_init(struct memory *mem, ui Line 118  void dev_ram_init(struct memory *mem, ui
118    
119          memset(d, 0, sizeof(struct ram_data));          memset(d, 0, sizeof(struct ram_data));
120    
121            if (mode & DEV_RAM_MIGHT_POINT_TO_DEVICES) {
122                    mode &= ~DEV_RAM_MIGHT_POINT_TO_DEVICES;
123                    points_to_ram = 0;
124            }
125    
126          d->mode         = mode;          d->mode         = mode;
127          d->otheraddress = otheraddress;          d->otheraddress = otheraddress;
128    
129          switch (d->mode) {          switch (d->mode) {
130    
131          case DEV_RAM_MIRROR:          case DEV_RAM_MIRROR:
132                    /*
133                     *  Calculate the amount that the mirror memory is offset from
134                     *  the real (physical) memory. This is used in src/memory_rw.c
135                     *  with dyntrans accesses if DM_EMULATED_RAM is set.
136                     */
137                    d->offset = baseaddr - otheraddress;
138    
139                    /*  Aligned RAM? Then it works with dyntrans.  */
140                    if (points_to_ram &&
141                        (baseaddr & (machine->arch_pagesize-1)) == 0 &&
142                        (otheraddress & (machine->arch_pagesize - 1)) == 0 &&
143                        (length & (machine->arch_pagesize - 1)) == 0)
144                            flags |= DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK
145                                | DM_EMULATED_RAM;
146    
147                    memory_device_register(machine->memory, "ram [mirror]",
148                        baseaddr, length, dev_ram_access, d, flags
149                        | DM_READS_HAVE_NO_SIDE_EFFECTS, (void *) &d->offset);
150                  break;                  break;
151    
152          case DEV_RAM_RAM:          case DEV_RAM_RAM:
153                  /*                  /*
154                   *  Allocate zero-filled RAM using mmap(). If mmap() failed,                   *  Allocate zero-filled RAM using mmap(). If mmap() failed,
# Line 138  void dev_ram_init(struct memory *mem, ui Line 166  void dev_ram_init(struct memory *mem, ui
166                          }                          }
167                          memset(d->data, 0, length);                          memset(d->data, 0, length);
168                  }                  }
169    
170                    /*  Aligned memory? Then it works with dyntrans.  */
171                    if ((baseaddr & (machine->arch_pagesize - 1)) == 0 &&
172                        (length & (machine->arch_pagesize - 1)) == 0)
173                            flags |= DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK;
174    
175                    memory_device_register(machine->memory, "ram", baseaddr,
176                        d->length, dev_ram_access, d, flags
177                        | DM_READS_HAVE_NO_SIDE_EFFECTS, d->data);
178                  break;                  break;
179    
180          default:          default:
181                  fatal("dev_ram_access(): unknown mode %i\n", d->mode);                  fatal("dev_ram_access(): unknown mode %i\n", d->mode);
182                  exit(1);                  exit(1);
183          }          }
   
         memory_device_register(mem, d->mode == DEV_RAM_MIRROR?  
             "ram [mirror]" : "ram", baseaddr, length,  
             dev_ram_access, d, MEM_DEFAULT | MEM_READING_HAS_NO_SIDE_EFFECTS,  
             NULL);  
184  }  }
185    

Legend:
Removed from v.6  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26