/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 36 - (hide annotations)
Mon Oct 8 16:21:34 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 5692 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1497 2007/03/18 03:41:36 debug Exp $
20070224	Minor update to the initialization of the ns16550 in
		machine_walnut.c, to allow that machine type to boot with the
		new interrupt system (although it is still a dummy machine).
		Adding a wdc at 0x14000000 to machine_landisk.c, and fixing
		the SCIF serial interrupts of the SH4 cpu enough to get
		NetBSD/landisk booting from a disk image :-)  Adding a
		preliminary install instruction skeleton to guestoses.html.
20070306	Adding SH-IPL+G PROM emulation, and also passing the "end"
		symbol in r5 on bootup, for Landisk emulation. This is enough
		to get OpenBSD/landisk to install :)  Adding a preliminary
		install instruction skeleton to the documentation. SuperH
		emulation is still shaky, though :-/
20070307	Fixed a strangeness in memory_sh.c (read/write was never
		returned for any page). (Unknown whether this fixes any actual
		problems, though.)
20070308	dev_ram.c fix: invalidate code translations on writes to
		RAM, emulated as separate devices. Linux/dreamcast gets
		further in the boot process than before, but still bugs out
		in userland.
		Fixing bugs in the "stc.l gbr,@-rN" and "ldc.l @rN+,gbr" SuperH 
		instructions (they should NOT check the MD bit), allowing the
		Linux/dreamcast Live CD to reach userland correctly :-)
20070310	Changing the cpu name "Alpha" in src/useremul.c to "21364" to
		unbreak userland syscall emulation of FreeBSD/Alpha binaries.
20070314	Applying a patch from Michael Yaroslavtsev which fixes the
		previous Linux lib64 patch to the configure script.
20070315	Adding a (dummy) sun4v machine type, and SPARC T1 cpu type.
20070316	Creating a new directory, src/disk, and moving diskimage.c
		to it. Separating out bootblock loading stuff from emul.c into
		new files in src/disk.
		Adding some more SPARC registers.
20070318	Preparing/testing for a minirelease, 0.4.4.1.

==============  RELEASE 0.4.4.1  ==============


1 dpavlin 4 /*
2 dpavlin 34 * Copyright (C) 2004-2007 Anders Gavare. All rights reserved.
3 dpavlin 4 *
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 dpavlin 36 * $Id: dev_ram.c,v 1.24 2007/03/08 11:43:44 debug Exp $
29 dpavlin 4 *
30 dpavlin 18 * A generic RAM (memory) device. Can also be used to mirror/alias another
31 dpavlin 4 * 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 dpavlin 18 #include "machine.h"
43 dpavlin 4 #include "memory.h"
44     #include "misc.h"
45    
46    
47     /* #define RAM_DEBUG */
48    
49     struct ram_data {
50 dpavlin 36 uint64_t baseaddress;
51    
52 dpavlin 4 int mode;
53     uint64_t otheraddress;
54    
55 dpavlin 18 /* If mode = DEV_RAM_MIRROR: */
56     uint64_t offset;
57    
58 dpavlin 4 /* If mode = DEV_RAM_RAM: */
59     unsigned char *data;
60     uint64_t length;
61     };
62    
63    
64 dpavlin 22 DEVICE_ACCESS(ram)
65 dpavlin 4 {
66     struct ram_data *d = extra;
67    
68     #ifdef RAM_DEBUG
69     if (writeflag==MEM_READ) {
70     debug("[ ram: read from 0x%x, len=%i ]\n",
71     (int)relative_addr, (int)len);
72     } else {
73     int i;
74     debug("[ ram: write to 0x%x:", (int)relative_addr);
75     for (i=0; i<len; i++)
76     debug(" %02x", data[i]);
77     debug(" (len=%i) ]\n", len);
78     }
79     #endif
80    
81     switch (d->mode) {
82     case DEV_RAM_MIRROR:
83     /* TODO: how about caches? */
84     return cpu->memory_rw(cpu, mem,
85     d->otheraddress + relative_addr, data, len,
86     writeflag, PHYSICAL);
87     case DEV_RAM_RAM:
88 dpavlin 36 if (writeflag == MEM_WRITE) {
89 dpavlin 4 memcpy(&d->data[relative_addr], data, len);
90 dpavlin 36
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 dpavlin 4 memcpy(data, &d->data[relative_addr], len);
99 dpavlin 36 }
100 dpavlin 4 break;
101     default:
102     fatal("dev_ram_access(): unknown mode %i\n", d->mode);
103     exit(1);
104     }
105    
106     return 1;
107     }
108    
109    
110     /*
111     * dev_ram_init():
112 dpavlin 18 *
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 dpavlin 4 */
117 dpavlin 18 void dev_ram_init(struct machine *machine, uint64_t baseaddr, uint64_t length,
118 dpavlin 4 int mode, uint64_t otheraddress)
119     {
120     struct ram_data *d;
121 dpavlin 20 int flags = DM_DEFAULT, points_to_ram = 1;
122 dpavlin 4
123     d = malloc(sizeof(struct ram_data));
124     if (d == NULL) {
125     fprintf(stderr, "out of memory\n");
126     exit(1);
127     }
128    
129     memset(d, 0, sizeof(struct ram_data));
130    
131 dpavlin 18 if (mode & DEV_RAM_MIGHT_POINT_TO_DEVICES) {
132     mode &= ~DEV_RAM_MIGHT_POINT_TO_DEVICES;
133     points_to_ram = 0;
134     }
135    
136 dpavlin 4 d->mode = mode;
137 dpavlin 36 d->baseaddress = baseaddr;
138 dpavlin 4 d->otheraddress = otheraddress;
139    
140     switch (d->mode) {
141 dpavlin 18
142 dpavlin 4 case DEV_RAM_MIRROR:
143 dpavlin 18 /*
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 dpavlin 20 * with dyntrans accesses if DM_EMULATED_RAM is set.
147 dpavlin 18 */
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 dpavlin 20 flags |= DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK
156     | DM_EMULATED_RAM;
157 dpavlin 18
158     memory_device_register(machine->memory, "ram [mirror]",
159     baseaddr, length, dev_ram_access, d, flags
160 dpavlin 20 | DM_READS_HAVE_NO_SIDE_EFFECTS, (void *) &d->offset);
161 dpavlin 4 break;
162 dpavlin 18
163 dpavlin 4 case DEV_RAM_RAM:
164     /*
165     * Allocate zero-filled RAM using mmap(). If mmap() failed,
166     * try malloc(), but then we also have to memset(), which
167     * can be slow for large chunks of memory.
168     */
169     d->length = length;
170     d->data = (unsigned char *) mmap(NULL, length,
171     PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
172     if (d->data == NULL) {
173     d->data = malloc(length);
174     if (d->data == NULL) {
175     fprintf(stderr, "out of memory\n");
176     exit(1);
177     }
178     memset(d->data, 0, length);
179     }
180 dpavlin 18
181     /* Aligned memory? Then it works with dyntrans. */
182     if ((baseaddr & (machine->arch_pagesize - 1)) == 0 &&
183     (length & (machine->arch_pagesize - 1)) == 0)
184 dpavlin 20 flags |= DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK;
185 dpavlin 18
186     memory_device_register(machine->memory, "ram", baseaddr,
187     d->length, dev_ram_access, d, flags
188 dpavlin 20 | DM_READS_HAVE_NO_SIDE_EFFECTS, d->data);
189 dpavlin 4 break;
190 dpavlin 18
191 dpavlin 4 default:
192     fatal("dev_ram_access(): unknown mode %i\n", d->mode);
193     exit(1);
194     }
195     }
196    

  ViewVC Help
Powered by ViewVC 1.1.26