/[gxemul]/trunk/src/devices/dev_vr41xx.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_vr41xx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Mon Oct 8 16:19:37 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 16724 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1121 2006/02/18 21:03:08 debug Exp $
20051126	Cobalt and PReP now work with the 21143 NIC.
		Continuing on Alpha dyntrans things.
		Fixing some more left-shift-by-24 to unsigned.
20051127	Working on OpenFirmware emulation; major cleanup/redesign.
		Progress on MacPPC emulation: NetBSD detects two CPUs (when
		running with -n 2), framebuffer output (for text) works.
		Adding quick-hack Bandit PCI controller and "gc" interrupt
		controller for MacPPC.
20051128	Changing from a Bandit to a Uni-North controller for macppc.
		Continuing on OpenFirmware and MacPPC emulation in general
		(obio controller, and wdc attached to the obio seems to work).
20051129	More work on MacPPC emulation (adding a dummy ADB controller).
		Continuing the PCI bus cleanup (endianness and tag composition)
		and rewriting all PCI controllers' access functions.
20051130	Various minor PPC dyntrans optimizations.
		Manually inlining some parts of the framebuffer redraw routine.
		Slowly beginning the conversion of the old MIPS emulation into
		dyntrans (but this will take quite some time to get right).
		Generalizing quick_pc_to_pointers.
20051201	Documentation update (David Muse has made available a kernel
		which simplifies Debian/DECstation installation).
		Continuing on the ADB bus controller.
20051202	Beginning a rewrite of the Zilog serial controller (dev_zs).
20051203	Continuing on the zs rewrite (now called dev_z8530); conversion
		to devinit style.
		Reworking some of the input-only vs output-only vs input-output
		details of src/console.c, better warning messages, and adding
		a debug dump.
		Removing the concept of "device state"; it wasn't really used.
		Changing some debug output (-vv should now be used to show all
		details about devices and busses; not shown during normal
		startup anymore).
		Beginning on some SPARC instruction disassembly support.
20051204	Minor PPC updates (WALNUT skeleton stuff).
		Continuing on the MIPS dyntrans rewrite.
		More progress on the ADB controller (a keyboard is "detected"
		by NetBSD and OpenBSD).
		Downgrading OpenBSD/arc as a guest OS from "working" to
		"almost working" in the documentation.
		Progress on Algor emulation ("v3" PCI controller).
20051205	Minor updates.
20051207	Sorting devices according to address; this reduces complexity
		of device lookups from O(n) to O(log n) in memory_rw (but no
		real performance increase (yet) in experiments).
20051210	Beginning the work on native dyntrans backends (by making a
		simple skeleton; so far only for Alpha hosts).
20051211	Some very minor SPARC updates.
20051215	Fixing a bug in the MIPS mul (note: not mult) instruction,
		so it also works with non-64-bit emulation. (Thanks to Alec
		Voropay for noticing the problem.)
20051216	More work on the fake/empty/simple/skeleton/whatever backend;
		performance doesn't increase, so this isn't really worth it,
		but it was probably worth it to prepare for a real backend
		later.
20051219	More instr call statistics gathering and analysis stuff.
20051220	Another fix for MIPS 'mul'. Also converting mul and {d,}cl{o,z}
		to dyntrans.
		memory_ppc.c syntax error fix (noticed by Peter Valchev).
		Beginning to move out machines from src/machine.c into
		individual files in src/machines (in a way similar to the
		autodev system for devices).
20051222	Updating the documentation regarding NetBSD/pmax 3.0.
20051223	- " - NetBSD/cats 3.0.
20051225	- " - NetBSD/hpcmips 3.0.
20051226	Continuing on the machine registry redesign.
		Adding support for ARM rrx (33-bit rotate).
		Fixing some signed/unsigned issues (exposed by gcc -W).
20051227	Fixing the bug which prevented a NetBSD/prep 3.0 install kernel
		from starting (triggered when an mtmsr was the last instruction
		on a page). Unfortunately not enough to get the kernel to run
		as well as the 2.1 kernels did.
20051230	Some dyntrans refactoring.
20051231	Continuing on the machine registry redesign.
20060101-10	Continuing... moving more machines. Moving MD interrupt stuff
		from machine.c into a new src/machines/interrupts.c.
20060114	Adding various mvmeppc machine skeletons.
20060115	Continuing on mvme* stuff. NetBSD/mvmeppc prints boot messages
		(for MVME1600) and reaches the root device prompt, but no
		specific hardware devices are emulated yet.
20060116	Minor updates to the mvme1600 emulation mode; the Eagle PCI bus
		seems to work without much modification, and a 21143 can be
		detected, interrupts might work (but untested so far).
		Adding a fake MK48Txx (mkclock) device, for NetBSD/mvmeppc.
20060121	Adding an aux control register for ARM. (A BIG thank you to
		Olivier Houchard for tracking down this bug.)
20060122	Adding more ARM instructions (smulXY), and dev_iq80321_7seg.
20060124	Adding disassembly of more ARM instructions (mia*, mra/mar),
		and some semi-bogus XScale and i80321 registers.
20060201-02	Various minor updates. Moving the last machines out of
		machine.c.
20060204	Adding a -c command line option, for running debugger commands
		before the simulation starts, but after all files have been
		loaded.
		Minor iq80321-related updates.
20060209	Minor hacks (DEVINIT macro, etc).
		Preparing for the generalization of the 64-bit dyntrans address
		translation subsystem.
20060216	Adding ARM ldrd (double-register load).
20060217	Continuing on various ARM-related stuff.
20060218	More progress on the ATA/wdc emulation for NetBSD/iq80321.
		NetBSD/evbarm can now be installed :-)  Updating the docs, etc.
		Continuing on Algor emulation.

==============  RELEASE 0.3.8  ==============


1 dpavlin 4 /*
2 dpavlin 22 * Copyright (C) 2004-2006 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 22 * $Id: dev_vr41xx.c,v 1.35 2006/01/01 13:17:18 debug Exp $
29 dpavlin 4 *
30     * VR41xx (actually, VR4122 and VR4131) misc functions.
31     *
32     * This is just a big hack. TODO: Fix.
33     */
34    
35     #include <stdio.h>
36     #include <stdlib.h>
37     #include <string.h>
38    
39     #include "console.h"
40     #include "cpu.h"
41     #include "device.h"
42     #include "devices.h"
43     #include "machine.h"
44     #include "memory.h"
45     #include "misc.h"
46    
47     #include "bcureg.h"
48     #include "vripreg.h"
49     #include "vrkiureg.h"
50    
51    
52     #define DEV_VR41XX_TICKSHIFT 15
53    
54     /* #define debug fatal */
55    
56    
57     static void recalc_kiu_int_assert(struct cpu *cpu, struct vr41xx_data *d)
58     {
59     if (d->kiu_int_assert != 0)
60     cpu_interrupt(cpu, 8 + d->kiu_irq_nr);
61     else
62     cpu_interrupt_ack(cpu, 8 + d->kiu_irq_nr);
63     }
64    
65    
66     /*
67     * vr41xx_keytick():
68     */
69     static void vr41xx_keytick(struct cpu *cpu, struct vr41xx_data *d)
70     {
71     int keychange = 0;
72    
73     /*
74     * Keyboard input:
75     *
76     * Hardcoded for MobilePro 780. (See NetBSD's hpckbdkeymap.h for
77     * info on other keyboard layouts. mobilepro780_keytrans is the
78     * one used here.)
79     *
80     * TODO: Make this work with "any" keyboard layout.
81     *
82     * (Even MobilePro 770 seems to be different? Hm. TODO)
83     *
84     * ofs 0:
85     * 8000='o' 4000='.' 2000=DOWN 1000=UP
86     * 800=';' 400=''' 200='[' 100=?
87     * 80='l' 40=CR 20=RIGHT 10=LEFT
88     * 8='/' 4='\' 2=']' 1=SPACE
89     * ofs 2:
90     * 8000='a' 4000='s' 2000='d' 1000='f'
91     * 800='`' 400='-' 200='=' 100=?
92     * 80='z' 40='x' 20='c' 10='v'
93     * 8=? 4=? 2=?
94     * ofs 4:
95     * 8000='9' 4000='0' 2000=? 1000=?
96     * 800='b' 400='n' 200='m' 100=','
97     * 80='q' 40='w' 20='e' 10='r'
98     * 8='5' 4='6' 2='7' 1='8'
99     * ofs 6:
100     * 8000=ESC 4000=DEL 2000=CAPS 1000=?
101     * 800='t' 400='y' 200='u' 100='i'
102     * 80='1' 40='2' 20='3' 10='4'
103     * 8='g' 4='h' 2='j' 1='k'
104     * ofs 8:
105     * 200=ALT_L
106     * 80= 40=TAB 20='p' 10=BS
107     * 8= 4= 2= 1=ALT_R
108     * ofs a:
109     * 800=SHIFT 4=CTRL
110     *
111     *
112     * The following are for the IBM WorkPad Z50:
113     * (Not yet implemented, TODO)
114     *
115     * 00 f1 f3 f5 f7 f9 - - f11
116     * 08 f2 f4 f6 f8 f10 - - f12
117     * 10 ' [ - 0 p ; up /
118     * 18 - - - 9 o l . -
119     * 20 left ] = 8 i k , -
120     * 28 h y 6 7 u j m n
121     * 30 - bs num del - \ ent sp
122     * 38 g t 5 4 r f v b
123     * 40 - - - 3 e d c right
124     * 48 - - - 2 w s x down
125     * 50 esc tab ~ 1 q a z -
126     * 58 menu Ls Lc Rc La Ra Rs -
127     */
128    
129     if (d->d0 != 0 || d->d1 != 0 || d->d2 != 0 ||
130     d->d3 != 0 || d->d4 != 0 || d->d5 != 0)
131     keychange = 1;
132    
133     /* Release all keys: */
134     if (!d->dont_clear_next) {
135     d->d0 = d->d1 = d->d2 = d->d3 = d->d4 = d->d5 = 0;
136     } else
137     d->dont_clear_next = 0;
138    
139     if (console_charavail(d->kiu_console_handle)) {
140     char ch = console_readchar(d->kiu_console_handle);
141    
142     if (d->escape_state > 0) {
143     switch (d->escape_state) {
144     case 1: /* expecting a [ */
145     d->escape_state = 0;
146     if (ch == '[')
147     d->escape_state = 2;
148     break;
149     case 2: /* cursor keys etc: */
150     switch (ch) {
151     case 'A': d->d0 = 0x1000; break;
152     case 'B': d->d0 = 0x2000; break;
153     case 'C': d->d0 = 0x20; break;
154     case 'D': d->d0 = 0x10; break;
155     default: fatal("[ vr41xx kiu: "
156     "unimplemented escape 0x%02 ]\n", ch);
157     }
158     d->escape_state = 0;
159     }
160     } else switch (ch) {
161     case '+': console_makeavail(d->kiu_console_handle, '=');
162     d->d5 = 0x800; break;
163     case '_': console_makeavail(d->kiu_console_handle, '-');
164     d->d5 = 0x800; break;
165     case '<': console_makeavail(d->kiu_console_handle, ',');
166     d->d5 = 0x800; break;
167     case '>': console_makeavail(d->kiu_console_handle, '.');
168     d->d5 = 0x800; break;
169     case '{': console_makeavail(d->kiu_console_handle, '[');
170     d->d5 = 0x800; break;
171     case '}': console_makeavail(d->kiu_console_handle, ']');
172     d->d5 = 0x800; break;
173     case ':': console_makeavail(d->kiu_console_handle, ';');
174     d->d5 = 0x800; break;
175     case '"': console_makeavail(d->kiu_console_handle, '\'');
176     d->d5 = 0x800; break;
177     case '|': console_makeavail(d->kiu_console_handle, '\\');
178     d->d5 = 0x800; break;
179     case '?': console_makeavail(d->kiu_console_handle, '/');
180     d->d5 = 0x800; break;
181    
182     case '!': console_makeavail(d->kiu_console_handle, '1');
183     d->d5 = 0x800; break;
184     case '@': console_makeavail(d->kiu_console_handle, '2');
185     d->d5 = 0x800; break;
186     case '#': console_makeavail(d->kiu_console_handle, '3');
187     d->d5 = 0x800; break;
188     case '$': console_makeavail(d->kiu_console_handle, '4');
189     d->d5 = 0x800; break;
190     case '%': console_makeavail(d->kiu_console_handle, '5');
191     d->d5 = 0x800; break;
192     case '^': console_makeavail(d->kiu_console_handle, '6');
193     d->d5 = 0x800; break;
194     case '&': console_makeavail(d->kiu_console_handle, '7');
195     d->d5 = 0x800; break;
196     case '*': console_makeavail(d->kiu_console_handle, '8');
197     d->d5 = 0x800; break;
198     case '(': console_makeavail(d->kiu_console_handle, '9');
199     d->d5 = 0x800; break;
200     case ')': console_makeavail(d->kiu_console_handle, '0');
201     d->d5 = 0x800; break;
202    
203     case '1': d->d3 = 0x80; break;
204     case '2': d->d3 = 0x40; break;
205     case '3': d->d3 = 0x20; break;
206     case '4': d->d3 = 0x10; break;
207     case '5': d->d2 = 0x08; break;
208     case '6': d->d2 = 0x04; break;
209     case '7': d->d2 = 0x02; break;
210     case '8': d->d2 = 0x01; break;
211     case '9': d->d2 = 0x8000; break;
212     case '0': d->d2 = 0x4000; break;
213    
214     case ';': d->d0 = 0x800; break;
215     case '\'': d->d0 = 0x400; break;
216     case '[': d->d0 = 0x200; break;
217     case '/': d->d0 = 0x8; break;
218     case '\\': d->d0 = 0x4; break;
219     case ']': d->d0 = 0x2; break;
220    
221     case 'a': d->d1 = 0x8000; break;
222     case 'b': d->d2 = 0x800; break;
223     case 'c': d->d1 = 0x20; break;
224     case 'd': d->d1 = 0x2000; break;
225     case 'e': d->d2 = 0x20; break;
226     case 'f': d->d1 = 0x1000; break;
227     case 'g': d->d3 = 0x8; break;
228     case 'h': d->d3 = 0x4; break;
229     case 'i': d->d3 = 0x100; break;
230     case 'j': d->d3 = 0x2; break;
231     case 'k': d->d3 = 0x1; break;
232     case 'l': d->d0 = 0x80; break;
233     case 'm': d->d2 = 0x200; break;
234     case 'n': d->d2 = 0x400; break;
235     case 'o': d->d0 = 0x8000; break;
236     case 'p': d->d4 = 0x20; break;
237     case 'q': d->d2 = 0x80; break;
238     case 'r': d->d2 = 0x10; break;
239     case 's': d->d1 = 0x4000; break;
240     case 't': d->d3 = 0x800; break;
241     case 'u': d->d3 = 0x200; break;
242     case 'v': d->d1 = 0x10; break;
243     case 'w': d->d2 = 0x40; break;
244     case 'x': d->d1 = 0x40; break;
245     case 'y': d->d3 = 0x400; break;
246     case 'z': d->d1 = 0x80; break;
247    
248     case ',': d->d2 = 0x100; break;
249     case '.': d->d0 = 0x4000; break;
250     case '-': d->d1 = 0x400; break;
251     case '=': d->d1 = 0x200; break;
252    
253     case '\r':
254     case '\n': d->d0 = 0x40; break;
255     case ' ': d->d0 = 0x01; break;
256     case '\b': d->d4 = 0x10; break;
257    
258     case 27: d->escape_state = 1; break;
259    
260     default:
261     /* Shifted: */
262     if (ch >= 'A' && ch <= 'Z') {
263     console_makeavail(d->kiu_console_handle,
264     ch + 32);
265     d->d5 = 0x800;
266     d->dont_clear_next = 1;
267     break;
268     }
269    
270     /* CTRLed: */
271     if (ch >= 1 && ch <= 26) {
272     console_makeavail(d->kiu_console_handle,
273     ch + 96);
274     d->d5 = 0x4;
275     d->dont_clear_next = 1;
276     break;
277     }
278     }
279    
280     if (d->escape_state == 0)
281     keychange = 1;
282     }
283    
284     if (keychange) {
285     /* 4=lost data, 2=data complete, 1=key input detected */
286     d->kiu_int_assert |= 3;
287     recalc_kiu_int_assert(cpu, d);
288     }
289     }
290    
291    
292     /*
293     * dev_vr41xx_tick():
294     */
295     void dev_vr41xx_tick(struct cpu *cpu, void *extra)
296     {
297     struct vr41xx_data *d = extra;
298    
299     /*
300     * UGLY! TODO: fix this.
301     *
302     * Interrupts should be triggered if the corresponding unit (for
303     * example the RTC unit) is activated.
304     */
305     {
306     static unsigned int x = 0;
307     x++;
308    
309     if (x > 100 && (x&3)==0) {
310     if (d->cpumodel == 4121 || d->cpumodel == 4181)
311     cpu_interrupt(cpu, 3);
312     else
313     cpu_interrupt(cpu, 8 + VRIP_INTR_ETIMER);
314     }
315     }
316    
317     if (cpu->machine->use_x11)
318     vr41xx_keytick(cpu, d);
319     }
320    
321    
322     /*
323     * vr41xx_kiu():
324     *
325     * Keyboard Interface Unit. Return value is "odata".
326     * (See NetBSD's vrkiu.c for more info.)
327     */
328     static uint64_t vr41xx_kiu(struct cpu *cpu, int ofs, uint64_t idata,
329     int writeflag, struct vr41xx_data *d)
330     {
331     uint64_t odata = 0;
332    
333     switch (ofs) {
334     case KIUDAT0:
335     odata = d->d0; break;
336     case KIUDAT1:
337     odata = d->d1; break;
338     case KIUDAT2:
339     odata = d->d2; break;
340     case KIUDAT3:
341     odata = d->d3; break;
342     case KIUDAT4:
343     odata = d->d4; break;
344     case KIUDAT5:
345     odata = d->d5; break;
346     case KIUSCANREP:
347     if (writeflag == MEM_WRITE) {
348     debug("[ vr41xx KIU: setting KIUSCANREP to 0x%04x ]\n",
349     (int)idata);
350     /* TODO */
351     } else
352     fatal("[ vr41xx KIU: unimplemented read from "
353     "KIUSCANREP ]\n");
354     break;
355     case KIUSCANS:
356     if (writeflag == MEM_WRITE) {
357     debug("[ vr41xx KIU: write to KIUSCANS: 0x%04x: TODO"
358     " ]\n", (int)idata);
359     /* TODO */
360     } else
361     debug("[ vr41xx KIU: unimplemented read from "
362     "KIUSCANS ]\n");
363     break;
364     case KIUINT:
365     /* Interrupt. A wild guess: zero-on-write */
366     if (writeflag == MEM_WRITE) {
367     d->kiu_int_assert &= ~idata;
368     } else {
369     odata = d->kiu_int_assert;
370     }
371     recalc_kiu_int_assert(cpu, d);
372     break;
373     case KIURST:
374     /* Reset. */
375     break;
376     default:
377     if (writeflag == MEM_WRITE)
378     debug("[ vr41xx KIU: unimplemented write to offset "
379     "0x%x, data=0x%016llx ]\n", ofs, (long long)idata);
380     else
381     debug("[ vr41xx KIU: unimplemented read from offset "
382     "0x%x ]\n", ofs);
383     }
384    
385     return odata;
386     }
387    
388    
389     /*
390     * dev_vr41xx_access():
391     */
392 dpavlin 22 DEVICE_ACCESS(vr41xx)
393 dpavlin 4 {
394     struct vr41xx_data *d = (struct vr41xx_data *) extra;
395     uint64_t idata = 0, odata = 0;
396     int regnr;
397     int revision = 0;
398    
399 dpavlin 18 if (writeflag == MEM_WRITE)
400     idata = memory_readmax64(cpu, data, len);
401    
402 dpavlin 4 regnr = relative_addr / sizeof(uint64_t);
403    
404     /* KIU ("Keyboard Interface Unit") is handled separately. */
405     if (relative_addr >= d->kiu_offset &&
406     relative_addr < d->kiu_offset + 0x20) {
407     odata = vr41xx_kiu(cpu, relative_addr - d->kiu_offset,
408     idata, writeflag, d);
409     goto ret;
410     }
411    
412     /* TODO: Maybe these should be handled separately as well? */
413    
414     switch (relative_addr) {
415     /* BCU: 0x00 .. 0x1c */
416     case BCUREVID_REG_W: /* 0x010 */
417     case BCU81REVID_REG_W: /* 0x014 */
418     /*
419     * TODO? Linux seems to read 0x14. The lowest bits are
420     * a divisor for PClock, bits 8 and up seem to be a
421     * divisor for VTClock (relative to PClock?)...
422     */
423     switch (d->cpumodel) {
424     case 4131: revision = BCUREVID_RID_4131; break;
425     case 4122: revision = BCUREVID_RID_4122; break;
426     case 4121: revision = BCUREVID_RID_4121; break;
427     case 4111: revision = BCUREVID_RID_4111; break;
428     case 4102: revision = BCUREVID_RID_4102; break;
429     case 4101: revision = BCUREVID_RID_4101; break;
430     case 4181: revision = BCUREVID_RID_4181; break;
431     }
432     odata = (revision << BCUREVID_RIDSHFT) | 0x020c;
433     break;
434     case BCU81CLKSPEED_REG_W: /* 0x018 */
435     /*
436     * TODO: Implement this for ALL cpu types:
437     */
438     odata = BCUCLKSPEED_DIVT4 << BCUCLKSPEED_DIVTSHFT;
439     break;
440    
441     /* DMAAU: 0x20 .. 0x3c */
442    
443     /* DCU: 0x40 .. 0x5c */
444    
445     /* CMU: 0x60 .. 0x7c */
446    
447     /* ICU: 0x80 .. 0xbc */
448     case 0x80: /* Level 1 system interrupt reg 1... */
449     if (writeflag == MEM_READ)
450     odata = d->sysint1;
451     else {
452     /* TODO: clear-on-write-one? */
453     d->sysint1 &= ~idata;
454     d->sysint1 &= 0xffff;
455     }
456     break;
457     case 0x88:
458     if (writeflag == MEM_READ)
459     odata = d->giuint;
460     else
461     d->giuint &= ~idata;
462     break;
463     case 0x8c:
464     if (writeflag == MEM_READ)
465     odata = d->msysint1;
466     else
467     d->msysint1 = idata;
468     break;
469     case 0x94:
470     if (writeflag == MEM_READ)
471     odata = d->giumask;
472     else
473     d->giumask = idata;
474     break;
475     case 0xa0: /* Level 1 system interrupt reg 2... */
476     if (writeflag == MEM_READ)
477     odata = d->sysint2;
478     else {
479     /* TODO: clear-on-write-one? */
480     d->sysint2 &= ~idata;
481     d->sysint2 &= 0xffff;
482     }
483     break;
484     case 0xa6:
485     if (writeflag == MEM_READ)
486     odata = d->msysint2;
487     else
488     d->msysint2 = idata;
489     break;
490    
491     /* PMU: 0xc0 .. 0xfc */
492     /* RTC: 0x100 .. ? */
493    
494     case 0x108:
495     if (writeflag == MEM_READ)
496     odata = d->giuint;
497     else
498     d->giuint &= ~idata;
499     break;
500     /* case 0x10a:
501     "High" part of GIU?
502     break;
503     */
504    
505     case 0x13e: /* on 4181? */
506     /* RTC interrupt register... */
507     /* Ack. timer interrupts? */
508     cpu_interrupt_ack(cpu, 8 + VRIP_INTR_ETIMER);
509     break;
510    
511     case 0x1de: /* on 4121? */
512     /* RTC interrupt register... */
513     /* Ack. timer interrupts? */
514     cpu_interrupt_ack(cpu, 3);
515     break;
516    
517     default:
518     if (writeflag == MEM_WRITE)
519     debug("[ vr41xx: unimplemented write to address "
520     "0x%llx, data=0x%016llx ]\n",
521     (long long)relative_addr, (long long)idata);
522     else
523     debug("[ vr41xx: unimplemented read from address "
524     "0x%llx ]\n", (long long)relative_addr);
525     }
526    
527     ret:
528     /* Recalculate interrupt assertions: */
529     cpu_interrupt_ack(cpu, 8 + 31); /* TODO: hopefully nothing
530     useful at irq 15 in
531     sysint2 */
532    
533     if (writeflag == MEM_READ)
534     memory_writemax64(cpu, data, len, odata);
535    
536     return 1;
537     }
538    
539    
540     /*
541     * dev_vr41xx_init():
542     */
543     struct vr41xx_data *dev_vr41xx_init(struct machine *machine,
544     struct memory *mem, int cpumodel)
545     {
546     uint64_t baseaddr = 0;
547 dpavlin 12 char tmps[100];
548 dpavlin 4 struct vr41xx_data *d = malloc(sizeof(struct vr41xx_data));
549 dpavlin 12
550 dpavlin 4 if (d == NULL) {
551     fprintf(stderr, "out of memory\n");
552     exit(1);
553     }
554     memset(d, 0, sizeof(struct vr41xx_data));
555    
556     d->cpumodel = cpumodel;
557    
558     /* TODO: VRC4173 has the KIU at offset 0x100? */
559     d->kiu_offset = 0x180;
560 dpavlin 22 d->kiu_console_handle = console_start_slave_inputonly(
561     machine, "kiu", 1);
562 dpavlin 4 d->kiu_irq_nr = VRIP_INTR_KIU;
563    
564     switch (cpumodel) {
565     case 4101:
566     case 4102:
567     case 4111:
568     case 4121:
569     baseaddr = 0xb000000;
570     break;
571     case 4181:
572     baseaddr = 0xa000000;
573 dpavlin 18 dev_ram_init(machine, 0xb000000, 0x1000000, DEV_RAM_MIRROR,
574 dpavlin 4 0xa000000);
575     break;
576     case 4122:
577     case 4131:
578     baseaddr = 0xf000000;
579     break;
580     default:
581     printf("Unimplemented VR cpu model\n");
582     exit(1);
583     }
584    
585     memory_device_register(mem, "vr41xx", baseaddr, DEV_VR41XX_LENGTH,
586 dpavlin 20 dev_vr41xx_access, (void *)d, DM_DEFAULT, NULL);
587 dpavlin 4
588     /*
589     * TODO: Find out which controllers are at which addresses on
590     * which chips.
591     */
592     if (cpumodel == 4131) {
593 dpavlin 12 snprintf(tmps, sizeof(tmps), "ns16550 irq=%i addr=0x%llx "
594     "name2=siu", 8+VRIP_INTR_SIU, (long long)(baseaddr+0x800));
595     device_add(machine, tmps);
596 dpavlin 4 } else {
597     /* This is used by Linux and NetBSD: */
598 dpavlin 12 snprintf(tmps, sizeof(tmps), "ns16550 irq=%i addr=0x%x "
599     "name2=serial", 8+VRIP_INTR_SIU, 0xc000000);
600     device_add(machine, tmps);
601 dpavlin 4 }
602    
603     /* Hm... maybe this should not be here. TODO */
604     device_add(machine, "pcic addr=0x140003e0");
605    
606     machine_add_tickfunction(machine, dev_vr41xx_tick, d,
607     DEV_VR41XX_TICKSHIFT);
608    
609     /* Some machines (?) use ISA space at 0x15000000 instead of
610     0x14000000, eg IBM WorkPad Z50. */
611 dpavlin 18 dev_ram_init(machine, 0x15000000, 0x1000000, DEV_RAM_MIRROR,
612     0x14000000);
613 dpavlin 4
614     return d;
615     }
616    

  ViewVC Help
Powered by ViewVC 1.1.26