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

Contents of /trunk/src/devices/dev_vr41xx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations)
Mon Oct 8 16:20:40 2007 UTC (16 years, 6 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 /*
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_vr41xx.c,v 1.38 2006/07/23 19:36:04 debug Exp $
29 *
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 DEVICE_TICK(vr41xx)
293 {
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 "0x%x, data=0x%016"PRIx64" ]\n", ofs,
377 (uint64_t) idata);
378 else
379 debug("[ vr41xx KIU: unimplemented read from offset "
380 "0x%x ]\n", ofs);
381 }
382
383 return odata;
384 }
385
386
387 DEVICE_ACCESS(vr41xx)
388 {
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 if (writeflag == MEM_WRITE)
395 idata = memory_readmax64(cpu, data, len);
396
397 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 "0x%"PRIx64", data=0x%016"PRIx64" ]\n",
516 (uint64_t) relative_addr, (uint64_t) idata);
517 else
518 debug("[ vr41xx: unimplemented read from address "
519 "0x%"PRIx64" ]\n", (uint64_t) relative_addr);
520 }
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 char tmps[100];
543 struct vr41xx_data *d = malloc(sizeof(struct vr41xx_data));
544
545 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 d->kiu_console_handle = console_start_slave_inputonly(
556 machine, "kiu", 1);
557 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 dev_ram_init(machine, 0xb000000, 0x1000000, DEV_RAM_MIRROR,
569 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 dev_vr41xx_access, (void *)d, DM_DEFAULT, NULL);
582
583 /*
584 * TODO: Find out which controllers are at which addresses on
585 * which chips.
586 */
587 if (cpumodel == 4131) {
588 snprintf(tmps, sizeof(tmps), "ns16550 irq=%i addr=0x%"PRIx64" "
589 "name2=siu", 8+VRIP_INTR_SIU, (uint64_t) (baseaddr+0x800));
590 device_add(machine, tmps);
591 } else {
592 /* This is used by Linux and NetBSD: */
593 snprintf(tmps, sizeof(tmps), "ns16550 irq=%i addr=0x%x "
594 "name2=serial", 8+VRIP_INTR_SIU, 0xc000000);
595 device_add(machine, tmps);
596 }
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 DEV_VR41XX_TICKSHIFT, 0.0);
603
604 /* Some machines (?) use ISA space at 0x15000000 instead of
605 0x14000000, eg IBM WorkPad Z50. */
606 dev_ram_init(machine, 0x15000000, 0x1000000, DEV_RAM_MIRROR,
607 0x14000000);
608
609 return d;
610 }
611

  ViewVC Help
Powered by ViewVC 1.1.26