/[gxemul]/upstream/0.3.8/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

Contents of /upstream/0.3.8/src/devices/dev_ram.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Mon Oct 8 16:19:43 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 5435 byte(s)
0.3.8
1 /*
2 * Copyright (C) 2004-2006 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: dev_ram.c,v 1.21 2006/01/01 13:17:17 debug Exp $
29 *
30 * A generic RAM (memory) device. Can also be used to mirror/alias another
31 * part of RAM.
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38 #include <sys/mman.h>
39
40 #include "cpu.h"
41 #include "devices.h"
42 #include "machine.h"
43 #include "memory.h"
44 #include "misc.h"
45
46
47 /* #define RAM_DEBUG */
48
49 struct ram_data {
50 int mode;
51 uint64_t otheraddress;
52
53 /* If mode = DEV_RAM_MIRROR: */
54 uint64_t offset;
55
56 /* If mode = DEV_RAM_RAM: */
57 unsigned char *data;
58 uint64_t length;
59 };
60
61
62 /*
63 * dev_ram_access():
64 */
65 DEVICE_ACCESS(ram)
66 {
67 struct ram_data *d = extra;
68
69 #ifdef RAM_DEBUG
70 if (writeflag==MEM_READ) {
71 debug("[ ram: read from 0x%x, len=%i ]\n",
72 (int)relative_addr, (int)len);
73 } else {
74 int i;
75 debug("[ ram: write to 0x%x:", (int)relative_addr);
76 for (i=0; i<len; i++)
77 debug(" %02x", data[i]);
78 debug(" (len=%i) ]\n", len);
79 }
80 #endif
81
82 switch (d->mode) {
83 case DEV_RAM_MIRROR:
84 /* TODO: how about caches? */
85 return cpu->memory_rw(cpu, mem,
86 d->otheraddress + relative_addr, data, len,
87 writeflag, PHYSICAL);
88 case DEV_RAM_RAM:
89 if (writeflag == MEM_WRITE)
90 memcpy(&d->data[relative_addr], data, len);
91 else
92 memcpy(data, &d->data[relative_addr], len);
93 break;
94 default:
95 fatal("dev_ram_access(): unknown mode %i\n", d->mode);
96 exit(1);
97 }
98
99 return 1;
100 }
101
102
103 /*
104 * dev_ram_init():
105 *
106 * Initializes a RAM or mirror device. Things get a bit complicated because
107 * of dyntrans (i.e. mirrored memory ranges should be entered into the
108 * translation arrays just as normal memory and other devices are).
109 */
110 void dev_ram_init(struct machine *machine, uint64_t baseaddr, uint64_t length,
111 int mode, uint64_t otheraddress)
112 {
113 struct ram_data *d;
114 int flags = DM_DEFAULT, points_to_ram = 1;
115
116 d = malloc(sizeof(struct ram_data));
117 if (d == NULL) {
118 fprintf(stderr, "out of memory\n");
119 exit(1);
120 }
121
122 memset(d, 0, sizeof(struct ram_data));
123
124 if (mode & DEV_RAM_MIGHT_POINT_TO_DEVICES) {
125 mode &= ~DEV_RAM_MIGHT_POINT_TO_DEVICES;
126 points_to_ram = 0;
127 }
128
129 d->mode = mode;
130 d->otheraddress = otheraddress;
131
132 switch (d->mode) {
133
134 case DEV_RAM_MIRROR:
135 /*
136 * Calculate the amount that the mirror memory is offset from
137 * the real (physical) memory. This is used in src/memory_rw.c
138 * with dyntrans accesses if DM_EMULATED_RAM is set.
139 */
140 d->offset = baseaddr - otheraddress;
141
142 /* Aligned RAM? Then it works with dyntrans. */
143 if (points_to_ram &&
144 (baseaddr & (machine->arch_pagesize-1)) == 0 &&
145 (otheraddress & (machine->arch_pagesize - 1)) == 0 &&
146 (length & (machine->arch_pagesize - 1)) == 0)
147 flags |= DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK
148 | DM_EMULATED_RAM;
149
150 memory_device_register(machine->memory, "ram [mirror]",
151 baseaddr, length, dev_ram_access, d, flags
152 | DM_READS_HAVE_NO_SIDE_EFFECTS, (void *) &d->offset);
153 break;
154
155 case DEV_RAM_RAM:
156 /*
157 * Allocate zero-filled RAM using mmap(). If mmap() failed,
158 * try malloc(), but then we also have to memset(), which
159 * can be slow for large chunks of memory.
160 */
161 d->length = length;
162 d->data = (unsigned char *) mmap(NULL, length,
163 PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
164 if (d->data == NULL) {
165 d->data = malloc(length);
166 if (d->data == NULL) {
167 fprintf(stderr, "out of memory\n");
168 exit(1);
169 }
170 memset(d->data, 0, length);
171 }
172
173 /* Aligned memory? Then it works with dyntrans. */
174 if ((baseaddr & (machine->arch_pagesize - 1)) == 0 &&
175 (length & (machine->arch_pagesize - 1)) == 0)
176 flags |= DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK;
177
178 memory_device_register(machine->memory, "ram", baseaddr,
179 d->length, dev_ram_access, d, flags
180 | DM_READS_HAVE_NO_SIDE_EFFECTS, d->data);
181 break;
182
183 default:
184 fatal("dev_ram_access(): unknown mode %i\n", d->mode);
185 exit(1);
186 }
187 }
188

  ViewVC Help
Powered by ViewVC 1.1.26