/[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 36 by dpavlin, Mon Oct 8 16:21:34 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2007  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.24 2007/03/08 11:43:44 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 47  Line 47 
47  /*  #define RAM_DEBUG  */  /*  #define RAM_DEBUG  */
48    
49  struct ram_data {  struct ram_data {
50            uint64_t        baseaddress;
51    
52          int             mode;          int             mode;
53          uint64_t        otheraddress;          uint64_t        otheraddress;
54    
55            /*  If mode = DEV_RAM_MIRROR:  */
56            uint64_t        offset;
57    
58          /*  If mode = DEV_RAM_RAM:  */          /*  If mode = DEV_RAM_RAM:  */
59          unsigned char   *data;          unsigned char   *data;
60          uint64_t        length;          uint64_t        length;
61  };  };
62    
63    
64  /*  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)  
65  {  {
66          struct ram_data *d = extra;          struct ram_data *d = extra;
67    
# Line 85  int dev_ram_access(struct cpu *cpu, stru Line 85  int dev_ram_access(struct cpu *cpu, stru
85                      d->otheraddress + relative_addr, data, len,                      d->otheraddress + relative_addr, data, len,
86                      writeflag, PHYSICAL);                      writeflag, PHYSICAL);
87          case DEV_RAM_RAM:          case DEV_RAM_RAM:
88                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE) {
89                          memcpy(&d->data[relative_addr], data, len);                          memcpy(&d->data[relative_addr], data, len);
90                  else  
91                            /*  Invalidate any code translations on a write:  */
92                            if (cpu->invalidate_code_translation != NULL) {
93                                    cpu->invalidate_code_translation(
94                                        cpu, d->baseaddress + relative_addr,
95                                        INVALIDATE_PADDR);
96                            }
97                    } else {
98                          memcpy(data, &d->data[relative_addr], len);                          memcpy(data, &d->data[relative_addr], len);
99                    }
100                  break;                  break;
101          default:          default:
102                  fatal("dev_ram_access(): unknown mode %i\n", d->mode);                  fatal("dev_ram_access(): unknown mode %i\n", d->mode);
# Line 101  int dev_ram_access(struct cpu *cpu, stru Line 109  int dev_ram_access(struct cpu *cpu, stru
109    
110  /*  /*
111   *  dev_ram_init():   *  dev_ram_init():
112     *
113     *  Initializes a RAM or mirror device. Things get a bit complicated because
114     *  of dyntrans (i.e. mirrored memory ranges should be entered into the
115     *  translation arrays just as normal memory and other devices are).
116   */   */
117  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,
118          int mode, uint64_t otheraddress)          int mode, uint64_t otheraddress)
119  {  {
120          struct ram_data *d;          struct ram_data *d;
121            int flags = DM_DEFAULT, points_to_ram = 1;
122    
123          d = malloc(sizeof(struct ram_data));          d = malloc(sizeof(struct ram_data));
124          if (d == NULL) {          if (d == NULL) {
# Line 115  void dev_ram_init(struct memory *mem, ui Line 128  void dev_ram_init(struct memory *mem, ui
128    
129          memset(d, 0, sizeof(struct ram_data));          memset(d, 0, sizeof(struct ram_data));
130    
131            if (mode & DEV_RAM_MIGHT_POINT_TO_DEVICES) {
132                    mode &= ~DEV_RAM_MIGHT_POINT_TO_DEVICES;
133                    points_to_ram = 0;
134            }
135    
136          d->mode         = mode;          d->mode         = mode;
137            d->baseaddress  = baseaddr;
138          d->otheraddress = otheraddress;          d->otheraddress = otheraddress;
139    
140          switch (d->mode) {          switch (d->mode) {
141    
142          case DEV_RAM_MIRROR:          case DEV_RAM_MIRROR:
143                    /*
144                     *  Calculate the amount that the mirror memory is offset from
145                     *  the real (physical) memory. This is used in src/memory_rw.c
146                     *  with dyntrans accesses if DM_EMULATED_RAM is set.
147                     */
148                    d->offset = baseaddr - otheraddress;
149    
150                    /*  Aligned RAM? Then it works with dyntrans.  */
151                    if (points_to_ram &&
152                        (baseaddr & (machine->arch_pagesize-1)) == 0 &&
153                        (otheraddress & (machine->arch_pagesize - 1)) == 0 &&
154                        (length & (machine->arch_pagesize - 1)) == 0)
155                            flags |= DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK
156                                | DM_EMULATED_RAM;
157    
158                    memory_device_register(machine->memory, "ram [mirror]",
159                        baseaddr, length, dev_ram_access, d, flags
160                        | DM_READS_HAVE_NO_SIDE_EFFECTS, (void *) &d->offset);
161                  break;                  break;
162    
163          case DEV_RAM_RAM:          case DEV_RAM_RAM:
164                  /*                  /*
165                   *  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 177  void dev_ram_init(struct memory *mem, ui
177                          }                          }
178                          memset(d->data, 0, length);                          memset(d->data, 0, length);
179                  }                  }
180    
181                    /*  Aligned memory? Then it works with dyntrans.  */
182                    if ((baseaddr & (machine->arch_pagesize - 1)) == 0 &&
183                        (length & (machine->arch_pagesize - 1)) == 0)
184                            flags |= DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK;
185    
186                    memory_device_register(machine->memory, "ram", baseaddr,
187                        d->length, dev_ram_access, d, flags
188                        | DM_READS_HAVE_NO_SIDE_EFFECTS, d->data);
189                  break;                  break;
190    
191          default:          default:
192                  fatal("dev_ram_access(): unknown mode %i\n", d->mode);                  fatal("dev_ram_access(): unknown mode %i\n", d->mode);
193                  exit(1);                  exit(1);
194          }          }
   
         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);  
195  }  }
196    

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

  ViewVC Help
Powered by ViewVC 1.1.26