/[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 30 - (hide annotations)
Mon Oct 8 16:20:40 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 16668 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1325 2006/08/15 15:38:37 debug Exp $
20060723	More Transputer instructions (pfix, nfix, opr, mint, ldl, ldlp,
		eqc, rev, ajw, stl, stlf, sthf, sub, ldnl, ldnlp, ldpi, move,
		wcnt, add, bcnt).
		Adding more SPARC instructions (andcc, addcc, bl, rdpr).
		Progress on the igsfb framebuffer used by NetBSD/netwinder.
		Enabling 8-bit fills in dev_fb.
		NetBSD/netwinder 3.0.1 can now run from a disk image :-)
20060724	Cleanup/performance fix for 64-bit virtual translation table
		updates (by removing the "timestamp" stuff). A full NetBSD/pmax
		3.0.1 install for R4400 has dropped from 667 seconds to 584 :)
		Fixing the igsfb "almost vga" color (it is 24-bit, not 18-bit).
		Adding some MIPS instruction combinations (3*lw, and 3*addu).
		The 8048 keyboard now turns off interrupt enable between the
		KBR_ACK and the KBR_RSTDONE, to work better with Linux 2.6.
		Not causing PPC DEC interrupts if PPC_NO_DEC is set for a
		specific CPU; NetBSD/bebox gets slightly further than before.
		Adding some more SPARC instructions: branches, udiv.
20060725	Refreshing dev_pckbc.c a little.
		Cleanups for the SH emulation mode, and adding the first
		"compact" (16-bit) instructions: various simple movs, nop,
		shll, stc, or, ldc.
20060726	Adding dummy "pcn" (AMD PCnet NIC) PCI glue.
20060727	Various cleanups; removing stuff from cpu.h, such as
		running_translated (not really meaningful anymore), and
		page flags (breaking into the debugger clears all translations
		anyway).
		Minor MIPS instruction combination updates.
20060807	Expanding the 3*sw and 3*lw MIPS instruction combinations to
		work with 2* and 4* too, resulting in a minor performance gain.
		Implementing a usleep hack for the RM52xx/MIPS32/MIPS64 "wait"
		instruction (when emulating 1 cpu).
20060808	Experimenting with some more MIPS instruction combinations.
		Implementing support for showing a (hardcoded 12x22) text
		cursor in igsfb.
20060809	Simplifying the NetBSD/evbmips (Malta) install instructions
		somewhat (by using a NetBSD/pmax ramdisk install kernel).
20060812	Experimenting more with the MIPS 'wait' instruction.
		PCI configuration register writes can now be handled, which
		allow PCI IDE controllers to work with NetBSD/Malta 3.0.1 and
		NetBSD/cobalt 3.0.1. (Previously only NetBSD 2.1 worked.)
20060813	Updating dev_gt.c based on numbers from Alec Voropay, to enable
		Linux 2.6 to use PCI on Malta.
		Continuing on Algor interrupt stuff.
20060814	Adding support for routing ISA interrupts to two different
		interrupts, making it possible to run NetBSD/algor :-)
20060814-15	Testing for the release.

==============  RELEASE 0.4.2  ==============


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 30 * $Id: dev_vr41xx.c,v 1.38 2006/07/23 19:36:04 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 dpavlin 30 DEVICE_TICK(vr41xx)
293 dpavlin 4 {
294     struct vr41xx_data *d = extra;
295    
296     /*
297     * UGLY! TODO: fix this.
298     *
299     * Interrupts should be triggered if the corresponding unit (for
300     * example the RTC unit) is activated.
301     */
302     {
303     static unsigned int x = 0;
304     x++;
305    
306     if (x > 100 && (x&3)==0) {
307     if (d->cpumodel == 4121 || d->cpumodel == 4181)
308     cpu_interrupt(cpu, 3);
309     else
310     cpu_interrupt(cpu, 8 + VRIP_INTR_ETIMER);
311     }
312     }
313    
314     if (cpu->machine->use_x11)
315     vr41xx_keytick(cpu, d);
316     }
317    
318    
319     /*
320     * vr41xx_kiu():
321     *
322     * Keyboard Interface Unit. Return value is "odata".
323     * (See NetBSD's vrkiu.c for more info.)
324     */
325     static uint64_t vr41xx_kiu(struct cpu *cpu, int ofs, uint64_t idata,
326     int writeflag, struct vr41xx_data *d)
327     {
328     uint64_t odata = 0;
329    
330     switch (ofs) {
331     case KIUDAT0:
332     odata = d->d0; break;
333     case KIUDAT1:
334     odata = d->d1; break;
335     case KIUDAT2:
336     odata = d->d2; break;
337     case KIUDAT3:
338     odata = d->d3; break;
339     case KIUDAT4:
340     odata = d->d4; break;
341     case KIUDAT5:
342     odata = d->d5; break;
343     case KIUSCANREP:
344     if (writeflag == MEM_WRITE) {
345     debug("[ vr41xx KIU: setting KIUSCANREP to 0x%04x ]\n",
346     (int)idata);
347     /* TODO */
348     } else
349     fatal("[ vr41xx KIU: unimplemented read from "
350     "KIUSCANREP ]\n");
351     break;
352     case KIUSCANS:
353     if (writeflag == MEM_WRITE) {
354     debug("[ vr41xx KIU: write to KIUSCANS: 0x%04x: TODO"
355     " ]\n", (int)idata);
356     /* TODO */
357     } else
358     debug("[ vr41xx KIU: unimplemented read from "
359     "KIUSCANS ]\n");
360     break;
361     case KIUINT:
362     /* Interrupt. A wild guess: zero-on-write */
363     if (writeflag == MEM_WRITE) {
364     d->kiu_int_assert &= ~idata;
365     } else {
366     odata = d->kiu_int_assert;
367     }
368     recalc_kiu_int_assert(cpu, d);
369     break;
370     case KIURST:
371     /* Reset. */
372     break;
373     default:
374     if (writeflag == MEM_WRITE)
375     debug("[ vr41xx KIU: unimplemented write to offset "
376 dpavlin 24 "0x%x, data=0x%016"PRIx64" ]\n", ofs,
377     (uint64_t) idata);
378 dpavlin 4 else
379     debug("[ vr41xx KIU: unimplemented read from offset "
380     "0x%x ]\n", ofs);
381     }
382    
383     return odata;
384     }
385    
386    
387 dpavlin 22 DEVICE_ACCESS(vr41xx)
388 dpavlin 4 {
389     struct vr41xx_data *d = (struct vr41xx_data *) extra;
390     uint64_t idata = 0, odata = 0;
391     int regnr;
392     int revision = 0;
393    
394 dpavlin 18 if (writeflag == MEM_WRITE)
395     idata = memory_readmax64(cpu, data, len);
396    
397 dpavlin 4 regnr = relative_addr / sizeof(uint64_t);
398    
399     /* KIU ("Keyboard Interface Unit") is handled separately. */
400     if (relative_addr >= d->kiu_offset &&
401     relative_addr < d->kiu_offset + 0x20) {
402     odata = vr41xx_kiu(cpu, relative_addr - d->kiu_offset,
403     idata, writeflag, d);
404     goto ret;
405     }
406    
407     /* TODO: Maybe these should be handled separately as well? */
408    
409     switch (relative_addr) {
410     /* BCU: 0x00 .. 0x1c */
411     case BCUREVID_REG_W: /* 0x010 */
412     case BCU81REVID_REG_W: /* 0x014 */
413     /*
414     * TODO? Linux seems to read 0x14. The lowest bits are
415     * a divisor for PClock, bits 8 and up seem to be a
416     * divisor for VTClock (relative to PClock?)...
417     */
418     switch (d->cpumodel) {
419     case 4131: revision = BCUREVID_RID_4131; break;
420     case 4122: revision = BCUREVID_RID_4122; break;
421     case 4121: revision = BCUREVID_RID_4121; break;
422     case 4111: revision = BCUREVID_RID_4111; break;
423     case 4102: revision = BCUREVID_RID_4102; break;
424     case 4101: revision = BCUREVID_RID_4101; break;
425     case 4181: revision = BCUREVID_RID_4181; break;
426     }
427     odata = (revision << BCUREVID_RIDSHFT) | 0x020c;
428     break;
429     case BCU81CLKSPEED_REG_W: /* 0x018 */
430     /*
431     * TODO: Implement this for ALL cpu types:
432     */
433     odata = BCUCLKSPEED_DIVT4 << BCUCLKSPEED_DIVTSHFT;
434     break;
435    
436     /* DMAAU: 0x20 .. 0x3c */
437    
438     /* DCU: 0x40 .. 0x5c */
439    
440     /* CMU: 0x60 .. 0x7c */
441    
442     /* ICU: 0x80 .. 0xbc */
443     case 0x80: /* Level 1 system interrupt reg 1... */
444     if (writeflag == MEM_READ)
445     odata = d->sysint1;
446     else {
447     /* TODO: clear-on-write-one? */
448     d->sysint1 &= ~idata;
449     d->sysint1 &= 0xffff;
450     }
451     break;
452     case 0x88:
453     if (writeflag == MEM_READ)
454     odata = d->giuint;
455     else
456     d->giuint &= ~idata;
457     break;
458     case 0x8c:
459     if (writeflag == MEM_READ)
460     odata = d->msysint1;
461     else
462     d->msysint1 = idata;
463     break;
464     case 0x94:
465     if (writeflag == MEM_READ)
466     odata = d->giumask;
467     else
468     d->giumask = idata;
469     break;
470     case 0xa0: /* Level 1 system interrupt reg 2... */
471     if (writeflag == MEM_READ)
472     odata = d->sysint2;
473     else {
474     /* TODO: clear-on-write-one? */
475     d->sysint2 &= ~idata;
476     d->sysint2 &= 0xffff;
477     }
478     break;
479     case 0xa6:
480     if (writeflag == MEM_READ)
481     odata = d->msysint2;
482     else
483     d->msysint2 = idata;
484     break;
485    
486     /* PMU: 0xc0 .. 0xfc */
487     /* RTC: 0x100 .. ? */
488    
489     case 0x108:
490     if (writeflag == MEM_READ)
491     odata = d->giuint;
492     else
493     d->giuint &= ~idata;
494     break;
495     /* case 0x10a:
496     "High" part of GIU?
497     break;
498     */
499    
500     case 0x13e: /* on 4181? */
501     /* RTC interrupt register... */
502     /* Ack. timer interrupts? */
503     cpu_interrupt_ack(cpu, 8 + VRIP_INTR_ETIMER);
504     break;
505    
506     case 0x1de: /* on 4121? */
507     /* RTC interrupt register... */
508     /* Ack. timer interrupts? */
509     cpu_interrupt_ack(cpu, 3);
510     break;
511    
512     default:
513     if (writeflag == MEM_WRITE)
514     debug("[ vr41xx: unimplemented write to address "
515 dpavlin 24 "0x%"PRIx64", data=0x%016"PRIx64" ]\n",
516     (uint64_t) relative_addr, (uint64_t) idata);
517 dpavlin 4 else
518     debug("[ vr41xx: unimplemented read from address "
519 dpavlin 24 "0x%"PRIx64" ]\n", (uint64_t) relative_addr);
520 dpavlin 4 }
521    
522     ret:
523     /* Recalculate interrupt assertions: */
524     cpu_interrupt_ack(cpu, 8 + 31); /* TODO: hopefully nothing
525     useful at irq 15 in
526     sysint2 */
527    
528     if (writeflag == MEM_READ)
529     memory_writemax64(cpu, data, len, odata);
530    
531     return 1;
532     }
533    
534    
535     /*
536     * dev_vr41xx_init():
537     */
538     struct vr41xx_data *dev_vr41xx_init(struct machine *machine,
539     struct memory *mem, int cpumodel)
540     {
541     uint64_t baseaddr = 0;
542 dpavlin 12 char tmps[100];
543 dpavlin 4 struct vr41xx_data *d = malloc(sizeof(struct vr41xx_data));
544 dpavlin 12
545 dpavlin 4 if (d == NULL) {
546     fprintf(stderr, "out of memory\n");
547     exit(1);
548     }
549     memset(d, 0, sizeof(struct vr41xx_data));
550    
551     d->cpumodel = cpumodel;
552    
553     /* TODO: VRC4173 has the KIU at offset 0x100? */
554     d->kiu_offset = 0x180;
555 dpavlin 22 d->kiu_console_handle = console_start_slave_inputonly(
556     machine, "kiu", 1);
557 dpavlin 4 d->kiu_irq_nr = VRIP_INTR_KIU;
558    
559     switch (cpumodel) {
560     case 4101:
561     case 4102:
562     case 4111:
563     case 4121:
564     baseaddr = 0xb000000;
565     break;
566     case 4181:
567     baseaddr = 0xa000000;
568 dpavlin 18 dev_ram_init(machine, 0xb000000, 0x1000000, DEV_RAM_MIRROR,
569 dpavlin 4 0xa000000);
570     break;
571     case 4122:
572     case 4131:
573     baseaddr = 0xf000000;
574     break;
575     default:
576     printf("Unimplemented VR cpu model\n");
577     exit(1);
578     }
579    
580     memory_device_register(mem, "vr41xx", baseaddr, DEV_VR41XX_LENGTH,
581 dpavlin 20 dev_vr41xx_access, (void *)d, DM_DEFAULT, NULL);
582 dpavlin 4
583     /*
584     * TODO: Find out which controllers are at which addresses on
585     * which chips.
586     */
587     if (cpumodel == 4131) {
588 dpavlin 24 snprintf(tmps, sizeof(tmps), "ns16550 irq=%i addr=0x%"PRIx64" "
589     "name2=siu", 8+VRIP_INTR_SIU, (uint64_t) (baseaddr+0x800));
590 dpavlin 12 device_add(machine, tmps);
591 dpavlin 4 } else {
592     /* This is used by Linux and NetBSD: */
593 dpavlin 12 snprintf(tmps, sizeof(tmps), "ns16550 irq=%i addr=0x%x "
594     "name2=serial", 8+VRIP_INTR_SIU, 0xc000000);
595     device_add(machine, tmps);
596 dpavlin 4 }
597    
598     /* Hm... maybe this should not be here. TODO */
599     device_add(machine, "pcic addr=0x140003e0");
600    
601     machine_add_tickfunction(machine, dev_vr41xx_tick, d,
602 dpavlin 24 DEV_VR41XX_TICKSHIFT, 0.0);
603 dpavlin 4
604     /* Some machines (?) use ISA space at 0x15000000 instead of
605     0x14000000, eg IBM WorkPad Z50. */
606 dpavlin 18 dev_ram_init(machine, 0x15000000, 0x1000000, DEV_RAM_MIRROR,
607     0x14000000);
608 dpavlin 4
609     return d;
610     }
611    

  ViewVC Help
Powered by ViewVC 1.1.26