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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Oct 8 16:17:48 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 170061 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.676 2005/04/07 15:14:55 debug Exp $

Changelog for GXemul:
---------------------

20030829	Skeleton. ELF stuff. Some instructions.
20030830	Simple test programs using +-*/^|&%, function calls,
		loops, and stuff like that work.
20030903	Adding more instructions, fixing some bugs.
20030907	Making adding of memory mapped devices easier, although
		the framework isn't built for speed.
		Adding a -q switch to turn of debug output.
20030911	Trying to fix some bugs. Minor changes. Some COP0
		registers are now meaningful.
20030919	Making APs (non-bootstrap cpus) available via a simple
		'mp' device. Implementing ll/lld and sc/scd (for atomic
		memory updates, needed by MP operating systems).
20030923	Minor updates: more instructions (divu, mulu, lwu,
		perhaps some more), and opcode usage statistics.
20030924	If the next instruction is nullified (for 'branch
		likely' type of instructions), counters for delays etc
		are now decreased as they should.
		Adding some comments.
		Adding instructions: movz, movn.
		Adding a simple mandelbrot test to mipstest.c.
20030925	Adding instructions: bltzl, bgezl, lh, lhu, sh, mfc*,
		mtc*.
		Adding a dummy instructions: sync, cache.
		Adding minimal DECstation PROM functionality: printf()
		and getsysid() callback functions.
		Beginning work on address translation.
20030927	Adding some more cop0 functionality (tlb stuff).
		Adding mc146818 real-time clock. (Skeleton stuff.)
20030928	Adding a dc7085 serial console device (dummy, but enough
		to output chars to the screen). NetBSD uses this for
		the MIPSMATE 5100.
20030929	Working on the TLB stuff.
		Adding instructions: srlv, tlbwr, tlbr, tlbp, eret.
20030930	Trying to find a bug which causes NetBSD to bug out, but
		it is really hard.
		Adding some a.out support (for loading an old
		OpenBSD 2.8/pmax kernel image).
		Adding instructions: lwc*, ldc*, swc1 and swc3.
		Beginning to add special code to handle the differences
		between R4000 (the default emulation) and R2000/R3000.
20031001	Symbol listings produced by 'nm -S' can be used to
		show symbolic names for addresses. (-S)
20031002	Fixing the i/d fake cache for R2000/R3000. It's still
		just an ugly hack, though.
		Fixing minor bugs to make the 3100 emulation use the
		dc device (serial console) correctly. So far, 5100 and
		3100 are the only ones that get far enough to print
		stuff, when booting NetBSD.
20031004	Adding skeleton Cobalt machine emulation (-E).
		Adding a dummy ns16550 serial controller, used by the
		Cobalt machine emulation.
20031006	Adding unaligned load/store instructions (lwl, lwr,
		ldl, ldr, swl, swr, sdl, sdr), although they are not
		tested yet.
		Fixed a "data modified on freelist" bug when running
		NetBSD/cobalt: setting the top bit of the index register
		when a tlbp fails (as the R4000 manual says) isn't
		sufficient, I had to clear the low bits as well.
		Adding break and syscall instructions, but they are not
		tested yet.
		Adding a 'gt' device, faking a PCI bus, for the Cobalt
		emulation.
20031008	Adding initial support for HPCmips (-F), a framebuffer
		device using X11. NetBSD/hpcmips can output pixels to
		the framebuffer, but that's about it.
20031009	Fixing the NetBSD/pmax bug: the "0/tftp/netbsd" style
		bootstring was only passed correctly in the bootinfo
		block, it needs to be passed as argv[0] as well.
		Adding instructions: mtlo, mthi.
		Rearrangning the source tree layout.
		Adding console input functionality. The NetBSD/cobalt
		kernel's ddb can now be interacted with.
20031010	Adding experimental (semi-useless) -t option, to show
		a function call tree while a program runs.
		Linux/cobalt now prints a few messages, but then hangs
		at "Calibrating delay loop..." unless an ugly hack is
		used (setting a word of memory at 0x801e472c to non-zero).
20031013	Adding a framebuffer device used in DECstation 3100;
		VFB01 for mono is implemented so far, not yet the
		VFB02 (color) variant.  Rewriting the framebuffer
		device so that it is usable by both HPCmips and DECstation
		emulation.
20031014	Minor fixes. Everything should compile and run ok
		both with and without X11.
20031015	Adding support for ECOFF binary images; text, data,
		and symbols are loaded. (Playing around with ultrixboot
		and ultrix kernels.)
20031016	The DECstation argv,argc stuff must be at 0xa0000000,
		not 0x80000000, or Ultrix kernels complain.
		Adding R2000/R3000 'rfe' instruction.
		Implementing more R2K/R3K tlb specific stuff, so that
		NetBSD boots and uses the tlb correctly, but much of
		it is ugly. (Needs to be separated in a cleaner way.)
		ECOFF symbols sizes are now calculated, so that offsets
		within symbols are usable.
20031017	DECstation bootstrings now automatically include the
		correct name of the kernel that is booting.
		Ultrix boots a bit.
20031018	ELF symbols are now read automatically from the binary.
		-t trace looks a bit better (string arguments are shown).
		Trying to get initial R5900 stuff working (the 128-bit
		CPU used in Playstation 2).
		Fixing a minor bug to make the VFB02 (color framebuffer)
		device work better, but it is still just 256 grayscales,
		not real color. Ultrix can now use the framebuffer (it
		calls it PMAX-CFB).
		A machine can now consist of CPUs of different types.
		Adding instructions: daddi, mov_xxx, mult_xx. The xxx
		instructions are not documented MIPS64 instructions,
		but NetBSD/playstation2 uses them. Perhaps VR5432
		instructions?
		Adding sign-extension to 32-bit mult.
		Adding Playstation 2 devices: dmac (DMA controller),
		gs (Graphic something?), and gif (graphics something
		else, which has access to the PS2's framebuffer).
		NetBSD/playstation2 works a bit, and prints a few
		bootup messages.
20031020	The cpu_type field of the cpu struct now contains
		usable values in a much better form than before. This
		simplifies adding of new CPU types.
20031021	Fixing an interrupt related bug: pc_last was used, but
		for interrupts this was incorrect. Fixed now.
		Fixing a load/store related bug: if a load into a
		register was aborted due to an exception, the register
		was still modified.
		The mc146818 rtc now reads its time from the system's
		time() function.
		Fixing another exception bug: if loading an instruction
		caused an exception, something bogus happened as the
		emulator tried to execute the instruction anyway. This
		has been fixed now.
20031023	Adding a quick hack which skips "while (reg --) ;"
		kind of loops.
		NetBSD/pmax suddenly reached userland (!), but only
		once and attempts to repeat it have failed. I believe
		it is problems with my interrupt handling system.
20031024	Adding 8-bit color palette support to the framebuffer.
		Connecting the pmax vdac device to the framebuffer's
		rgb palette.
		Fixing a bug in the dc device, so that console input
		is possible; interaction with NetBSD/pmax's built-in
		kernel debugger works now.
		Symbol sizes for file formats where symbol size isn't
		included are now calculated regardless of file format.
		Physical memory space can now be smaller than 64 bits,
		improving emulation speed a bit.
		Doing other minor performance enhancements by moving
		around some statements in critical parts of the code.
20031025	Minor changes to the dc device.
20031026	Adding support for reading symbols directly from
		a.out files. (Works with OpenBSD/pmax binaries.)
		Hardware devices may now register "tick functions" at
		specific cycle intervals in a generic fashion.
		All four channels of the dc serial controller device
		should now work; playing around with keyboard scan
		code generation when using the DECstation framebuffer.
		Making various (speed) improvements to the framebuffer
		device.
20031027	Playing around with the sii SCSI controller.
20031028	Minor fixes.
		Adding an SGI emulation mode (-G), and some ARCBIOS
		stuff, which SGIs seem to use.
		Adding getbitmap() to the DEC prom emulation layer,
		so some more -D x models become more usable.
		Adding a dummy 'ssc' serial console device for
		DECsystem 5400 emulation.
		Playing around with TURBOchannel stuff.
20031030	Minor fixes.
		Adding the sub instruction. (Not tested yet?)
		Sign-extending the results of multu, addi,addiu,
		add,addu,sub,subu,mfcZ.
		Adding a colorplanemask device for DECstation 3100.
		Fixed the NetBSD/pmax bug: I had forgotten to reset
		asid_match to 0 between tlb entry checks. :-)  Now
		userland runs nicely...
20031031	Fixing more bugs:  unaligned load/store could fail
		because of an exception, but registers could be "half
		updated". This has been fixed now.  (As a result,
		NetBSD/pmax can now run with any of r2000,r3000,r4000,
		r4400, or r5000.)
		Adding some R5K and R10000 stuff.  (Note: R5K is NOT
		R5000. Weird.)
		Adding dummy serial console (scc) for MAXINE.
		MAXINE also works with framebuffer, but there is no
		color palette yet (only black and white output).
20031101	Moving code chunks around to increase performance by
		a few percent.
		The opcode statistics option (-s) now shows opcode
		names, and not just numbers. :-)
		Fixing the bug which caused NetBSD/pmax to refuse
		input in serial console mode, but not in keyboard/
		framebuffer mode: the osconsole environment variable
		wasn't set correctly.
		Adding DEC PROM getchar() call.
		The transmitter scanner of the dc device now scans
		all four channels at once, for each tick, so serial
		output is (approximately) 4 times faster.
20031103	Adding a dummy BT459 vdac device, which does nothing
		but allows a PMAG-BA turbochannel graphics card to be
		used as framebuffer.
		Several DECstation machines (-D 2, 3, and 4) can now
		use TURBOchannel option card framebuffers as console,
		for output. (Keyboard input is still not implemented
		for those models.)  Only PMAG-AA (1280x1024x8) and
		PMAG-BA (1024x864x8), both using BT459 vdac, have
		been tested so far.
		Modifying the X11 routines so that several framebuffer
		windows now can be used simultaneously (if several
		graphics option cards are to be emulated concurrently).
20031104	DEC MIPSMATE 5100 (KN230) interrupts are shared
		between devices. I've added an ugly hack to allow
		that to work, which makes it possible to boot NetBSD
		into userland with serial console.
20031106	Removing the -S (symbol) option, as symbol files can
		now be given in any order together with other file
		names to be loaded.
		cookin tipped me about using (int64_t) (int32_t)
		casts instead of manually sign-extending values.
		Casting sometimes increases performance, sometimes
		decreases. It's tricky.
		Importing mips64emul into CVS.
20031107	Adding a generic ARC emulation mode.
		Increasing performance of the framebuffer by not
		updating it (or the XImage) if a write to the
		framebuffer contains exactly what is already in it.
		(This improves scrolling speed and initialization.)
		Adding initial MIPS16 support.
		Adding initial disk image support (-d command line
		option), but this will not be used until I get some
		kind of SCSI-controller emulation working.
20031108	Adding the first MIPS16 instructions: "move y,X",
		"ld y,D(x)", and "daddiu S,K" (but the last one
		doesn't work yet).
		Fixing the console environment variable for
		Enough of the 'asc' controller is now implemented
		to let NetBSD get past scsi disk detection when
		no disk images are used.
		DECstation machine type 2; both serial console and
		graphical console work now.
		Other X-windows bit-depths than 24 bits work now,
		but colors are still not correct in non-24 bit modes.
		Keypresses in X framebuffer windows are now
		translated into console keypresses. (Normal keys, but
		not cursor keys or other special keys.)
20031111	Adding support for X11 using non-24-bit output.
20031120	Adding X11 mouse event to emulated mouse event
		translation, but it's not tested yet.
		Trying to get more of the SCSI controller emulation
		to work.
20031124	Raw binaries can now be loaded into memory.
20031204	Adding srec binary support.
20031220	Adding some super-ugly arcbios emulation code.
		Making some progress on the SGI and ARC machine
		emulations.
20031222	SGI and ARC progress. Multiple CPUs are now added to
		the arcbios component tree (although NetBSD cannot
		actually use more than one).
20031228	Adding 'crime' and 'macepci' fake devices for SGI
		emulation.
		Finally implementing the cop0 'compare' register.
		Improvements to the ns16550 device, but it is still
		incomplete.
		SGI userland is now reached, but interaction is broken
		(due to the buggy ns16550).
20031229	Adding some more instructions: teq, dsllv
		Adding a Nintendo 64 emulation mode (skeleton).
		Adding R4300 and R12000 to the cpu list.
20031230	Adding bltzal, bltzall, bgezal, bgezall (not really
		tested yet).
		Fixing the 16550 serial controller device (by not
		supporting fifo, so in fact it emulates a 16450
		instead).  This causes NetBSD/sgimips to run nicely
		into userland, sysinst, and so on.
		Some ARC/RD94 interrupts seem to work ok now, but
		i/o interrupts are still not correctly implemented.
		NetBSD/arc userland is reached and can be interacted
		with, but there's no sysinst (?).
20040103	Trying to get some Irix stuff to work, but it's hard.
		Fixing some Cobalt/linux problems.
20040104	Adding a dummy 8250 device, so that Linux/sgimips can output
		console messages.
		Adding dmultu. (The same as dmult, so I'm not sure it's correct.
		Perhaps dmultu is correct and dmult is wrong...)
		Fixing a bug in unaligned load/stores of 64-bit values (a cast
		was needed).
		Linux/sgimips in 64-bit works a bit more than before.
		Adding simple (polled) input functionality to dev_zs.
		Making some progress on SGI-IP22 (IP32 still works best,
		though).
		Fixing the mc146818 clock device in ARC/NEC and SGI emulation
		modes, the year field was not correct.
		Adding a fake 'pref' instruction (lwc3).
20040106	Separating out memory.h from misc.h.
		Refactoring of a lot of small code fragments.
		The PCI bus device is now shared between Cobalt, SGI, and ARC.
		Support for RAM mirroring (dev_ram.c, not really tested yet).
		Ugly hack to select the largest of ELF string symbol tables,
		if there are more than one.
		Memory hole fix for ARCBIOS, and a fix for very large (>= 4GB)
		amounts of emulated RAM.
		TGA (DEC 21030) PCI graphics device. NetBSD/arc can boot with
		this card and use it as a framebuffer console.
20040107	Adding a fix (partly incorrect) to daddi, to allow Linux/sgimips
		to boot in 64-bit mode.
20040108	Fixing a sll/nop bug (rd==0 for nop, not sa==0 as before).
20040109	Trying to get an SGI-IP32 PROM image to boot.
20040110	Faking R10000 cache things.
		The PROM image boots, although it takes almost forever for it
		to realize that there is no keyboard.
		The 'gbe' SGI-IP32 graphics device works enough to display the
		Linux framebuffer penguin in the upper left corner :-)
20040111	-p and -P addresses can now be given as symbol names, not just
		numeric values.
		Experimenting with adding a PCIIDE (dev_wdc) controller to the
		Cobalt emulation.
20040120	Adding src/bintrans.c. No code yet, but this is a place for
		ideas to be written down.
		Increasing performance a little bit by inlining the check for
		interrupts (which occurs for every instruction).
20040124	Experimenting with pure userland (syscall) emulation.
20040127	Fixes for compiling under Solaris.
20040206	Some bintrans experiments.
20040209	Adding some simple Ultrix userland emulation syscalls.
20040211	Adding decprom_dump_txt_to_bin.c to the experiments/ dir.
		Adding a section to doc/ on how to use DECstation PROM dumps.
		Adding a hello world example to doc/ as well.
20040218	TURBOchannel slots that are empty now return a DBE exception,
		so that Ultrix and DECstation PROMs don't complain about
		broken TURBOchannel ROMs.
		Working some more on the machine-dependant interrupt stuff.
20040219	Trying out some Linux/DECstation kernels (semi-successfully).
20040222	YES! I finally found the bug that caused Linux/SGI-IP32 to only
		work on Alpha, not on 32-bit machines.  It was a shift left,
		probably done using 6 bits on alpha, 5 bits on 32-bit machines.
20040223	Some minimal DEC KN5800 progress; Ultrix prints some boot
		messages, detects 16 XMI R3000 cpus, and get a NULL panic.
		It's all fake, though, the CPUs don't actually work.
		Still, better than nothing :-)
20040225	An Ultrix OSF1 kernel with a ramdisk now boots :-)  (It was
		a problem with ultrixboot not giving the same arguments as
		NetBSD's boot program.)
20040225(later)	Fixing a bug in the DECstation dc serial device; digits 0-9
		were translated to numeric keypad 0-9, not the normal 0-9.
		(This caused Ultrix to print escape sequences instead of
		digits.)
20040226	Some progress on machine-dependant interrupt delivery
		for -D7 (Maxine) and -D4, and some more 'scc' serial
		controller featuers are implemented (but no interrupts/
		dma/keyboard/mouse stuff yet).
20040228	Progress on the scc controller; -D4 works in both serial
		console mode and with keyboard (graphical console), but no
		mouse yet.
20040301	SGI mace interrupts are now done using the new machine-
		independant interrupt system.
20040303	Fixing an R5900 bug; the lowest 6 bits have special meaning
		for coprocessor functions, not just 5 bits as on non-R5900
		CPUs. (This fixes a bug which caused NetBSD to crash.)
20040304	Adding enough (fake) DMA capabilities to the ioasic device
		to allow Ultrix to print boot messages in the -D3, -D4,
		and -D7 modes, and also print graphical console messages
		in -D4 and -D7 modes.
		-D11 (DEC5500) polled getchar added (to the 'ssc' device).
		Adding the 'madd' instruction (including R5900 weird stuff).
20040304(later)	Playstation 2's GIF can now copy 640x16 pixel chunks, allowing
		NetBSD to scroll up the framebuffer.  The cursor also works
		better now.
		Playstation 2 bootinfo RTC data should now be passed correctly
		to the running kernel.
		DECstation rtc year should be either 72 or 73, anything else
		will cause Ultrix to give a warning about invalid year.
20040306	Combining playstation2's dmac, interrupt, and timer devices
		into one (ps2_stuff).
		Adding some R5900 instructions: mfsa, mtsa, pmfhi, pmflo, por,
		lq, and sq.  (Most of them are just guesses, though.)
		Implementing my own XImage putpixel routine, which can be
		inlined... significantly faster than normal XPutPixel. :-)
20040307	Implementing the basic functionality of a "PMAG-CA" pixelstamp
		accellerated framebuffer device. Works with NetBSD and
		Ultrix, but no cursor or color support.
20040308	PMAG-CA, -DA, and -FA pixelstamps seem to work now.
		Adding a hack to allow a pmax/mach kernel to be loaded (it's
		a COFF file with 0 (!) sections).
		Initial test of bt459 + framebuffer cursor support.
20040309	Fixes/updates of dev_dec5800 and dev_ssc (and dev_decxmi) allow
		a KN5800 Ultrix-OSF1-ramdisk kernel to boot all the way into
		userland and be interacted with.
		The bt459 cursor should now look semi-nice, but it is still
		a bit fake.
20040310	Moving the DEC CCA stuff from src/machine.c into a separate
		device file (devices/dev_deccca.c).
		An ugly hack added to allow some more OSF/1 kernels (almost
		a.out, but without many of the header fields) to load.
20040314	Adding PMAG-JA and PMAG-RO (1280x1024 x 8-bit) TURBOchannel
		graphics devices. They work in Ultrix, but only monochrome
		and no cursor, because there are no ramdacs or such yet.
20040315	Pixelstamp solid fill now supports colors other than just
		zero-fill.
		Adding a (new) regression test skeleton.
20040321	Some really minor updates.
20040323	Fixes to allow SGI-IP20 and IP22 to work a bit better
		(aliased memory), and adding "private" firmware-like vectors
		to arcbios emul. An IP22 Irix kernel gets far enough to
		print an assertion warning (and then double panics). :-)
20040324	Adding a generalization hack to the SCC serial controller
		to work with SGI-IP19 (in addition to DECstations).
		Adding the 'sdc1' instruction.
		Some progress on various SGI emulation modes.
20040325	Minor updates.
20040326	Fixed a 'madd' bug (r5900). NetBSD/playstation2 now reaches
		userland correctly.  And a simple fix which allows NetBSD
		timer interrupts to be triggered; NetBSD uses T_MODE_CMPE
		(compare), while Linux uses _OVFE (overflow).
20040328	Linux on Playstation 2 boots a bit. The Playstation 2
		graphics controller has been extended to work better with
		NetBSD, and to include some Linux support as well.
		Some interrupt handling enhancements on Playstation 2,
		needed for Linux' dma.
		128-bit loads and stores (lq and sq) are allowed, although
		the top half of quadwords are not modified by other
		instructions. (Linux uses lq and sq.)
		Big-endian X Windows servers now display correct rgb color,
		not bgr as before.
20040330	Some minor updates to the documentation.
20040401	Adding a dummy ps2 OHCI device.
20040402	Progress on the asc SCSI controller.
20040406	Hack to allow ./configure, make to work on HP-UX B.11.00
		on HPPA-RISC, gcc 3.3.2. (Does not work with HP's cc.)
		More progress on the asc SCSI controller. Fixing INQUIRY,
		adding READ_CAPACITY, adding READ. Works a bit with NetBSD
		and some (but not all) Ultrix kernels, on DECstation type 2.
		Adding WRITE, SYNCRONIZE_CACHE.
		Mounting disks works in NetBSD :-)  It is a bit buggy,
		though. Or something else is buggy.
20040407	The bug is triggered by gunzip during NetBSD/pmax install.
20040408	Fixing a bug (non-nul-terminated string) which caused X11
		cursors to not display on Solaris.
		Unnecessary X11 redraws are skipped (removes some weird
		delays that existed before), and cursors are redrawn on
		window exposure. (The cursor functionality has been moved
		from dev_fb.c to x11.c.)
20040411	Fixing the DC7085 device so that Ultrix doesn't behave weird
		if both tx and rx interrupts occur at the same time.
		More advancements on the asc SCSI controller.
		More disk image filename prefixes are now recognized; c (for
		CD-ROM, as before), d for disk, b for boot device, r for
		read-only, and 0-7 for scsi id.
		Mounting disks works in Ultrix. Installing to disk usually
		crashes for various reasons, but an OSF/1 install gets
		relatively far (similar to the NetBSD/pmax install).
20040412	Trying to find the bug.
20040415	Finally found and fixed the bug; SCSI reads and writes
		(actually, any data in or data out) can be split up into
		multiple DMA transfers. That stuff was only partially
		implemented, and the part that was implemented was buggy.
		It works now. NetBSD/pmax and Ultrix 4.3 seems to like
		the SCSI stuff enough to install almost all the way.
20040415 (more)	Adding a hack which allows a host's cdrom device to be used as
		a cdrom device inside the emulator, eg /dev/cd0c.
		Making the cycle counter int64_t instead of long, as a 'long'
		overflows too easily on 32-bit machines. (The bug is still
		there, though.)
		I've now verified that a full NetBSD/pmax install can be done.
		If using a PMAG-AA graphics board, startx brings up X :-)
		mips64emul can be compiled inside NetBSD inside mips64emul,
		and it can run NetBSD in that environment. (I'm getting
		dizzy... :-)
20040417	Moving some coprocessor stuff from cpu.c to coproc.c.
20040424	Adding a BT455 vdac for PMAG-AA. Black and white are now
		rendered correctly in Xpmax.
		Adding colormap support to the BT459 device, for PMAG-BA.
20040425	Fixing a buffer length bug, which caused an Ultrix 4.5
		install to bug out on an i386 host.
20040429	FPU experiments.
20040502	More FPU experiments.
		Speedup for exception debug messages:  in quiet mode, debug
		messages were still evaluated, which took a relatively
		large amount of time.
20040503	Most FPU stuff fixed, but there is at least one known bug
		left; ps axu in NetBSD triggers it (ps loops forever).
20040504	A default install of Ultrix 4.5 succeeded! It boots up with
		a graphical login.
		Fixing the keyboard repetition bug (a lk201 "up" (release)
		scancode is now sent after every key).
20040505	Both CR and LF now produce the same lk201 scancode, so that
		pressing 'enter' works as expected in Ultrix.
20040506	Adding a vaddr to paddr translation cache, causing a speedup
		of perhaps 50% or more.
20040507	Fixing PMAG-BA color for Ultrix. (Ultrix relies on interrupts
		coming from the TURBOchannel slot to update the palette.)
20040508	Fixing cursor positioning for PMAG-BA.
20040511	Prints current nr of instructions per seconds, not only
		average, when using -N.
20040515	Some more bintrans experiments.
20040606	Adding ARCBIOS GetReadStatus() and Read().
		Adding some instructions: tlt, tltu, tge, tgeu, tne.
20040607	Adding the dsub instruction.
		Some minimal progress on SGI-IP30 emulation.
		Applying a patch from Juli Mallett to src/file.c (I'm not
		sure yet if it breaks or fixes anything).
		Some minor fixes for SGI-IP22 (such as faked board revision
		numbers).
20040608	ll/sc should now fail if any unrelated load/store occurs.
		Minor changes to the configure script.
		Adding some ifdefs around code which is not often used
		(the mfhi/mflo delay, and the last_used TLB experimental
		code); this might cause a tiny speedup.
20040609	Minor fixes.
20040610	Various minor SGI fixes (64-bit ARCS stuff, progress on the
		CRIME/MACE interrupt system, and some other random things).
20040611	More crime/mace progress, and some more work on pckbc.
		KN5800 progress: adding a XMI->BI adapter device; a disk
		controller is detected (but it is just a dummy so far).
20040612	Adding "dev_unreadable", which simplifies making memory
		areas unreadable. (NetBSD on SGI-IP22 no longer detects
		non-existant hpc1 and hpc2 busses.)
		Implementing rudimentary support for IP22 "local0" and
		"local1" interrupts, and "mappable" local interrupts.
		Some progress on the WDSC SCSI controller on IP22, enough
		to let NetBSD get past the disk detection and enter
		userland!  :-)
		The zs (zilog serial) device now works well enough to let
		NetBSD/sgimips be interacted with on IP22. :-)  (Though
		it is very ugly and hardcoded.)
20040613	IP32 didn't work last night, because there were too many
		tick functions registered. That has been increased now.
		Trying out NetBSD/sgimips 2.0 beta kernels. There are some
		differences compared to 1.6.2, which I'm trying to solve.
		Interrupt fixes for IP32: _serial and _misc are different.
		Separation of IP22 (Full-house) and IP24 (Guiness).
20040614	Modifying the memory layout for IP20,22,24,26 (RAM is now
		offset by 128MB, leaving room for EISA registers and such),
		and moving around some code chunks. This is not well
		tested yet, but seems to work.
		Moving parts of the tiny translation cache, as suggested
		by Juli Mallett.  It seems that the speedup isn't as
		apparent as it was a few weeks ago, though. :-(
		Speedups due to not translating addresses into symbol
		names unless the symbol name is actually printed.
		Added support for loading old big-endian (Irix) ECOFF
		kernels (0x60 0x01 as the first two bytes).
20040615 (late)	Adding enough SGI IP20 (Indigo) support to let NetBSD 2.0
		enter userland :-)  No interrupt specifics are implemented
		yet, so it hangs while doing terminal output.
20040618	Experimenting with the WDSC SCSI controller for IP20,22,24.
20040620	Adding a program which converts SGI prom dumps from text
		capture to binary, and some hacks to try to make such an
		IP22 PROM to work better in the emulator.
20040621	Removing the Nintendo 64 emulation mode, as it is too
		uninteresting to support.
		Adding SCSI tape device support (read-only, so far).
		Fixing a bug which caused the cursor to be corrupted if new
		data was written to the framebuffer, but the cursor wasn't
		moved.
20040622(early)	Finally! Making progress on the SCSI tape stuff; when going
		past the end of a file, automagically switch to the beginning
		of the next.
20040622(late)	Trying to track down the last SCSI tape bugs.
		Removing _all_ dynamic binary translation code (bintrans),
		starting from scratch again.
20040623(early)	Performing a general code cleanup (comments, fixing stuff
		that led to compiler warnings, ...).
		Disabling MIPS16 support by default, and making it a
		configure time option to enable it (--mips16). This gives
		a few percent speed increase overall.
		Increasing performance by assuming that instruction loads
		(reading from memory) will be at the same page as the last
		load.  (Several percent speedup.)
		Moving the list of kernels that can be found on the net from
		README to doc/.
20040624	Finally! I found and fixed the bug which caused 'ps', 'top',
		'xclock', and other programs in NetBSD/pmax to behave weird.
		Increasing performance by a few percent by running as many
		instructions in a row as possible, before checking for
		hardware ticks.
		When booting from SCSI tapes on DECstation, the bootstring
		now contains 'tz' instead of 'rz'.
		Adding a second ARC machine mode, "Acer PICA-61", -A2.
		Disabling the support for "instruction delays" by default
		(it has to be enabled manually in misc.h now, but is never
		used anywhere anyway).
		Other minor optimizations (moving around stuff in the
		cpu struct in misc.h, and caching cpu->pc in cpu.c).
		Separating the tiny translation cache into two, one for
		code and one for data. This gives a few percent speed
		increase.
20040625(early)	I think now is a good time for a "feature freeze",
		to let the code stabilize and then make some kind of
		first release.
20040625(later)	Adding a -v (verbose) command line option. If -v is not
		specified, the emulator goes into -q (quiet) mode just before
		it starts to execute MIPS code.
20040627	The configure script now adds -fomit-frame-pointer to the
		compile flags if the $CC seems to be able to handle that.
		Found and fixed a serious interrupt bug in BT459 (Ultrix'
		behaviour required a hack, which was incorrect), so
		performance for machines using the PMAG-BA framebuffer is
		now improved.
		For X11 bitdepths other than 8 or 24, a warning message
		is printed at startup.
		A number of other minor fixes, optimizations, updated
		comments and so on.
		Adding a BUGS file, a list of known bugs.
		Adding a minimal man page, doc/mips64emul.1.
20040628	Hacks for faking the existance of a second level cache
		(ARCBIOS and other places).
		An important fix for dc7085: tx interrupts should happen
		before rx interrupts, not the other way around as it was
		before. (This speeds up NetBSD boot on DECstation, and
		fixes a bug which Ultrix triggered on heavy keyboard input.)
		A couple of other minor fixes.
		Framebuffer fix: there was a bug which caused the rightmost/
		bottom pixel to sometimes not be updated, when running in
		scaledown mode. This is now fixed.
		Adding a small program which removes "zero holes" from
		harddisk image files.
20040629	More minor fixes.
20040629(later)	Adding -A3 (NEC RISCstation 2200) (this is similar to
		the 2250 model that NetBSD/arc can already boot all the
		way into userland and be interacted with), and -A4
		(Deskstation Tyne).
		Some more minor fixes.
20040630	Adding support for 15 and 16 bits X11 framebuffers,
		and converting from XYPixmap to ZPixmap (this fixes the
		problem of updates appearing in "layers" on some X
		servers).
		The pixels in the mouse cursor (for BT459) are now colored
		as the emulated OS sets them, although no transparency
		masking is done on the edges of the cursor yet. (In plain
		English:  the mouse cursor is no longer just a white solid
		square, you can actually see the mouse cursor image
		on the white square.)

==============  RELEASE 0.1  ==============

20040701	The -j option now takes a name, the of the kernel as passed
		on to the bootloader.  ("netbsd" is the default name.)
		Adding support to load bootstrap code directly from a disk
		image, for DECstation.  Both NetBSD/pmax and Ultrix boot
		straight of a disk image now, with no need to supply a
		kernel filename on the command line.  (Ultrix still needs
		-j vmunix, though, to boot from /vmunix instead of /netbsd.)
20040702	Minor bugfix (some new untested code for X11 keypresses was
		incorrect).
20040702(later)	Adding an ugly hack for CDROMs in FreeBSD; if an fread() isn't
		done at a 2048-byte aligned offset, it will fail. The hack
		tries to read at 2048-byte aligned offsets and move around
		buffers to make it work.
		Adding video off (screen blanking) support to BT459.

==============  RELEASE 0.1.1  ==============

20040702(later)	Cleanup to remove compiler warnings (Compaq's cc, Solaris' cc,
		and gcc 3.3.3/3.3.4 in Linux), mostly by putting ULL on large
		numeric constants.
		Better support for scaledown of BT459 cursors, but still not
		color-averaging.
		Beginning the work on adding better memory latency support
		(instruction delays), enabled by the --delays configure option.
20040703	Modifications to the configure script so that a config.h file
		is created, containing things that were passed along as
		-Dxxx on each cc command line before.
		More work on instruction latency support; trying to separate
		the concepts of nr of cycles and nr of instructions.
20040704	Working on R2000/R3000 caches.
		Adding a '--caches' option to the configure script.
		Various small optimizations.
		R3000 caches finally work. (I know that there is at least one
		bug, regarding interrupt response.)
20040705	Working on the 'le' device, and on a generic (device
		independant) networking framework. le can transmit and receive
		packets, and the network framework fakes ARP responses from a
		fake gateway machine (at a fixed ip address, 10.0.0.254).
		Adding a '-c' command line option, which makes emulated_hz
		automatically adjust itself to the current number of emulated
		cycles per host CPU second (measured at regular intervals).
20040707	Removing the '-c' option again, and making it the default
		behaviour of the emulator to automatically adjust clock
		interrupts to runtime speed (as long as it is above 1 MHz).
		(This can be overridden by specifying a static clock rate with
		the -I option.)
		Updating the doc/ stuff a bit.
		Generalization of the DECstation bootblock loading, to work
		with Sprite/pmax. Lots of other minor modifications to make
		Sprite work, such as adding support for DECstation "jump table"
		PROM functions, in addition to the old callback functions.
		Sprite boots from a disk image, starting the kernel if the
		argument "-j vmsprite" is used, but it seems to not like the
		DBE exceptions caused by reading empty TURBOchannel slots. :-/
20040708	Minor changes and perhaps some tiny speed improvements.
		The Lance chip is (apparently) supposed to set the length of
		received packets to len+4. (I've not found this in any 
		documentation, but this is what NetBSD expects.) So now, ICMP
		echo replies work :-)  UDP works in the outgoing direction,
		in the incoming direction, tcpdump can see the packets but they
		seem to be ignored anyway. (Weird.)
		Adding a separate virtual-address-to-host-page translation
		cache, 1-entry for loads, 1-entry for stores. (For now, it
		only works on R4000 as there are conflicts with cache usage
		on R3000).
		Changing the lower clock speed bound from 1 MHz to 1.5 MHz.
20040709	Incoming UDP checksums were wrong, but are now set to zero
		and NetBSD inside the emulator now accepts the packets (eg.
		nameserver responses).  Host lookups and even tftp file
		transfers (using UDP) work now :-)
		Adding a section on Networking to the Technical documentation,
		and a preliminary NetBSD/pmax install instruction for network
		installs to the User documentation.
		Some updates to the man page.
20040709(later)	Fix to the TURBOchannel code to allow Sprite to get past the
		card detection. Seems to still work with Ultrix and NetBSD.
		This also makes Linux/DECstation properly recognize both the
		Lance controller and the SCSI controller. Linux 2.4.26 from
		Debian boots nicely in framebuffer mode :-)
20040710	Some bits in the KN02 CSR that were supposed to be readonly
		weren't. That has been fixed, and this allows Linux/DECstation
		to get past SCSI detection. :-)
		Minor updates to the ASC controller, which makes Linux and
		OpenBSD/pmax like the controller enough to be able to access
		SCSI devices. OpenBSD/pmax boots from a disk image for the
		first time. :-)  Linux detects SCSI disks, but I have no
		bootable Linux diskimage to test this with.
		Updating the doc/ to include instructions on how to install
		OpenBSD/pmax onto a disk image.
		Naively added a PMAGB-BA (1280x1024x8) in hopes that it would
		basically be a PMAG-BA (1024x864x8) in higher resolution,
		but it didn't work that way. I'll have to look into this later.
		Adding a -o option, useful for selecting '-s' (single user
		mode) during OpenBSD install and other things.
		After a lot of debugging, a serious bug related to the tiny
		cache was found; Linux just changes the ASID and returns when
		switching between processes in some occasions without actually
		_writing_ to the TLB, and I had forgotten to invalidate the
		tiny cache on such a change.
20040711(early)	I've been trying to repeat the OpenBSD install from yesterday,
		but appart from the first initial install (which was
		successful), I've only been able to do one more. Several
		attempts have failed with a filesystem panic in the middle
		of install. I'm not sure why.
20040711	I found the "bug": wget downloaded the simpleroot28.fs.gz file
		as read-only, and gunzip preserved those flags. Thus, OpenBSD's
		installer crashed as it didn't get its writes through to the
		disk.
		Parts of the 1280x1024x8 PMAGB-BA graphics card has been
		implemented, it works (unaccelerated) in NetBSD and OpenBSD,
		but Ultrix does not seem to like it.
		Cleaned up the BT459 cursor offset stuff a bit.
		Trying to make the emulated mouse coordinates follow the host's
		mouse' coordinates (for lk201, DECstation), by
		"de-accelerating" the data sent to the emulated OS.
20040711(later)	Fix so that Sprite detects the PMAG-BA correctly.
		Adding some stuff about NFS via UDP to the documentation.
		Fixed the 'update flag' for seconds, so now Sprite doesn't
		crash because of timer-related issues anymore.
		Fixing KN02 interrupt masks a bit more, to make Sprite not
		crash. Sprite now runs quite well.
20040712	Working on IP/UDP fragementation issues. Incoming UDP packets
		from the outside world can now be broken up into fragments
		for the guest OS. (This allows, for example, OpenBSD/pmax to
		be installed via nfs.)  Outgoing fragmented packets are NOT
		yet handled.
		Linux doesn't use 64-bit file offsets by default, which is
		needed when using large disk images (more than 2GB), so the
		configure script has now been modified to add necessary
		compiler flags for Linux.
20040713	Trying out some minor optimizations.
		Refreshing the UDP implementation in src/net.c a little.
20040714	Updating the documentation a little on how to experiment
		with a Debian Linux install kernel for DECstations.
		A 'mini.iso' Linux image for DECstation has different fields
		at offsets 0x10 and 0x14, so I'm guessing that the first is
		the load address and the second is the initial PC value.
		Hopefully this doesn't break anything.
		Some initial TCP hacks, but not much is working yet.
		Some updates for IP30:  The load/store 1-entry cache didn't
		work too well with IP30 memory, so it's only turned on for
		"MMU4K" now. (This needs to be fixed some better way.)
		Adding a hack which allows Linux/Octane to use ARC write()
		and getchild() on IP30. Linux uses ARCBIOS_SPB_SIGNATURE as a
		64-bit field, it was 32-bit before.
		Making ugly hacks to the arcbios emulation to semi-support
		64-bit equivalents of 32-bit structures.
20040716	Minor fixes to the configure script (and a few other places)
		to make the sources compile out-of-the-box on HP-UX (ia64
		and HPPA), old OpenBSD/pmax (inside the emulator itself), and
		Tru64 (OSF/1) on Alpha.
		A couple of other minor fixes.
20040717	A little TCP progress; OpenBSD/pmax likes my SYN+ACK replies,
		and tries to send out data, but NetBSD/pmax just drops the
		SYN+ACK packets.
		Trial-and-error led me to change the 64-bit ARCS component
		struct again (Linux/IP30 likes it now). I'm not sure about all 
		of the offsets yet, but some things seem to work.
		More 64-bit ARCS updates (memory descriptors etc).
		Better memory offset fix for IP30, similar to how I did it for
		IP22 etc. (Hopefully this doesn't break anything else.)
		Adding a MardiGras graphics controller skeleton for SGI-IP30
		(dev_sgi_mardigras.c).
		Thanks to Stanislaw Skowronek for dual-licensing mgras.h.
		Finally rewrote get_symbol_name() to O(log n) instead of O(n)
		(Stanislaw's Linux kernel had so many symbols that tracing
		with the old get_symbol_name() was unbareably slow).
		Removing all of the experimental tlbmod tag optimization code
		(the 1-entry load/store cache), as it causes more trouble than
		the performance gain was worth.
20040718	The MardiGras device works well enough to let Linux draw the
		SGI logo and output text.
		A bunch of other minor changes.
20040719	Trying to move out all of the instruction_trace stuff from the
		main cpu loop (for two reasons: a little performance gain,
		and to make it easier to add a GUI later on).
20040720	Finally found and fixed the ethernet/tcp bug. The hardware
		address is comprised of 6 bytes, where the _first_ byte should
		have a zero as the lowest bit, not the last byte. (This causes
		NetBSD and Linux running in the emulator to accept my SYN+ACK
		packets.)
		Getting the first nameserver address from /etc/resolv.conf.
		(This is not used yet, but could be useful if/when I add
		internal DHCP support.)
		Working more on the TCP stuff; TCP seems to be almost working,
		the only immediate problem left is that the guest OS gets
		stuck in the closing and last-ack states, when it shouldn't.
		It is now possible to install NetBSD and OpenBSD via ftp. :-)
20040721	Trying to fix the last-ack bug, by sending an RST after the
		end of a connection. (Probably not a correct fix, but seems
		to work?)
		Adding a my_fseek() function, which works like fseek() but
		with off_t instead of long, so that large disk images can
		be used on systems where long is 32 bits.
20040722	Trying to fix some more TCP related bugs.
20040725	Changing the inlined asm statement in bintrans_alpha.c into
		a call to a hardcoded array of bytes that do the same thing
		(an instruction cache invalidation). This allows the same
		invalidation code to be used regardless of compiler.
		Some other minor changes.
20040726	Minor updates. The configure script is now more verbose.
		A Debian/IP22 Linux tftp boot kernel requires ARCS memory to
		be FreeMemory, not FreeContiguous. (This should still work with
		other SGI and ARC OSes.)
		Fix for ARCS write(), so it returns good write count and
		success result (0).
		Some hacks to the IP22 memory controller, to fake 72MB RAM
		in bank 0.
		The IP22 Debian kernel reaches userland (ramdisk) when run
		with -G24 -M72 -CR4400, if a special hack is done to the
		zs device.
20040730	Removing mgras.h, as I'm not sure a file dual-licensed this way
		would work. (Dual-licensing as two separate files would work
		though.)
		Preparing for the upcoming release (0.2).
20040801	Fixing the 512 vs 2048 cdrom sector size bug; I hadn't 
		implemented the mode select SCSI command. (It still isn't
		really implemented.)
		A bug which crashes the emulator is triggered when run with
		new NetBSD 2.0_BETA snapshots on a Linux/i386 host. I'm not
		sure why.
		UDP packets sent to the gateway (at 10.0.0.254) are now
		forwarded to the machine that the host uses as its nameserver.
		Some other minor fixes.

==============  RELEASE 0.2  ==============

20040803	A post-3.5 OpenBSD/sgimips kernel snapshot with ramdisk seems
		to boot fine in the emulator, all the way to userland, and
		can be interacted with.
		Adding a -y option, used to set how many (random) instructions
		to run from each CPU at max (useful for SMP instruction
		interleave experiments).
		Importing a 8x16 console font from FreeBSD (vt220l.816).
		Adding a skeleton for a 80x25 text console device (dev_vga),
		useful for some ARC modes. (Character output is possible, but
		no cursor yet.)
		Adding a dev_zero device (returns zeroes on read).
		OpenBSD/arc 2.3 can get all the way to userland with -A4 (if
		the wdc devices are commented out) but bugs out there, probably
		because of interrupt issues.
		Adding a -A5 ARC emulation mode (Microsoft-Jazz, "MIPS Magnum")
		which NetBSD seems to like. No interrupt specifics yet, so
		it hangs while waiting for SCSI.
20040804	Some dev_mp updates.
		The -y switch has to do with number of cycles, not number
		of instructions; variable names have been changed to reflect
		this.
20040805	Minor updates. Adding some more CPU types/names, but they
		are probably bogus.
		Adding a MeshCube emulation mode. Just a skeleton so far, but
		enough to let a Linux kernel print some boot messages.
		Adding the 'deret' instruction.
20040806	Adding include/impactsr-bsd.h (a newer version of what was in
		mgras.h before, and this time with only a BSD-style license),
		but it is not used yet.
20040810	Some Au1500 updates.
20040811	Adding the 'clz', 'clo', 'dclz', and 'dclo' special2 (MIPS32
		and MIPS64) instructions.
		More Au1500 updates.
20040812	Using fseeko(), when it is available.
		Other minor updates.
		Adding a NetGear WG602 emulation mode skeleton (-g); after
		a lot of trial and error, a Linux kernel (WG602_V1715.img)
		gets all the way to userland, but hangs there.
20040818	Adding signal handlers to better cope with CTRL-Z and CTRL-C.
		Adding a simple interactive single-step debugger which is
		activated by CTRL-C. (Commands so far: continue, dump, help,
		itrace, quit, registers, step, trace, version)
20040818(later)	Adding a 'tlbdump' debugger command, and some other minor
		fixes.
20040819	Minor updates. Adding an 'unassemble' debugger command.
20040822	Minor updates to the regression testing framework.
20040824	Minor updates based on feedback from Alec Voropay
		(configure script updates for Cygwin and documentation).
20040826	Minor updates.
		Adding a cursor to the VGA text console device.
		Changing all old 11:22:..55:66 ethernet macs to 10:20..60,
		still hardcoded though.
20040828	Minor updates.
20040829	mips64emul is 1 year old today :-)
20040901	tests/README now lists "all" MIPS opcodes. This list should
		be updated whenever a new opcode is implemented, or when a
		regression test is added. (A combination of instructions from
		the TX79 manual, the GNU assembler, and the MIPS64 manual).
		Hopefully I haven't missed too many.
		Adding a section on regression testing to doc/technical.html.
20040902	Finally beginning the work on separating out the stuff from
		main.c into a "struct emul". Very time-consuming.
		Some minor fixes for LL/SC on R10000.
20040905	Moving more stuff from main.c into struct emul. Unfortunately,
		it seems that this causes a slowdown of the emulator.
		Userland emulation is now only used if --userland is used
		when running configure.
		Modifying src/symbol.c to not use global variables.
20040906	Minor update.
20040914	Using $COPTIM when detecting which compiler flags to use in
		the configure script. (This makes sure that combinations of
		flags should work.)
		There'll probably be a 0.2.1 release some time soon, but I'll
		do some more clean-up first.
		Minor update to the detection of ECOFF files, but I don't like
		it; sometimes the endianness of the magic value seems to be
		swapped, but it doesn't have to do with endianness of the
		actual data?
20040916	Minor updates. Adding an Example section to the manpage, but
		as I'm not really familiar with manpage formatting, it will
		need to be rewritten later.
20040917	Finally making the coprocessor instructions disassemblable
		even when not running.
		Doing some testing for the 0.2.1 release.

==============  RELEASE 0.2.1  ==============

20040923	Updating the documentation about how to (try to) install
		Debian GNU/Linux.
20040924	Some more updates to the documentation.
20040925	Adding overflow stuff to 'add' and 'sub'.
20040926	Minor updates: possibly a fix to 'sltiu' (the imm value
		should be treated as signed, and then converted to unsigned,
		according to the MIPS64 manual), and removing the
		'last_was_rfe' stuff (again).
		OpenBSD/arc used speed-hack jumps with other deltas than just
		+/- 1 (it used -3 iirc), so the jump speedhack should now
		support any delta. Also adding bgtzl and blezl as possible
		instructions for the speed-hack jumps. (This needs to be
		tested more.)
20040928	Minor updates. Some ARC stuff ("arcdiag" runs now).
		cpu_register_dump() now also dumps coprocessor registers.
20040929	More ARC updates. Making the code look a tiny bit nicer
		than before. "arcdiag.ip22" works for -G22 (SGI-IP22).
		Apparently the overflow support in the 'add' instruction
		was incorrect, so I disabled it.
20041002	Trying to install Ultrix in the emulator, but the installer
		crashes; found (and fixed) the bug rather quickly: the "fix"
		I implemented a few days ago for the 'sub' instruction
		(according to the MIPS64 manual) caused the bug.
20041004	Changing the behaviour of the -j command line option. The
		default is now "" (or taken from the last filename given on
		the command line), not "netbsd". In practice, this doesn't
		change much, except that -j netbsd.pmax is no longer needed
		when installing NetBSD.
		Adding a COMPILE_DATE string to config.h.
20041007	Adding a NEC RISCserver 4200 model (-A6), and some more
		updates to the ARC component tree generator.
20041008	The 'll' instruction should be signed, not unsigned as before.
		This (and some other minor fixes) causes Irix on SGI-IP32 (O2)
		to actually boot far enough to print its first boot messages :)
		Working on some new dynamic bintrans code. Enough is now
		implemented so that the 'nop' instruction is translated
		and there is support for Alpha, i386 and UltraSparc backends,
		but performance is about 50% worse than when running without
		bintrans. (This is as expected, though.)
20041009	Minor updates to the documentation.
		Using mprotect() to make sure that the code created dynamically
		by the bintrans subsystem is allowed to be executed. (This
		affects newer OpenBSD systems, and possibly others.)
		The translated code chunks now only get one argument passed to
		them, the (struct cpu *) of the current cpu.
20041010	Hack to dev_le.c which makes Ultrix accept the initialization
		of the LANCE controller. (This goes against the LANCE
		documentation though.)
		In src/net.c, a fix for Ultrix (which seems to send larger
		ethernet packets than the actual TCP/IP contents). The hack to
		dev_le.c and this fix is enough to let Ultrix access the
		Internet.
		For DECstation, when booting without a disk image (or when
		"-O" is used on the command line), use "tftp" instead of "rzX"
		for the boot string.
20041011	Adding cache size variables to the emul struct, so that these
		can be set on a per-machine basis (or potentially manually
		on the command line).
20041012	Mach/PMAX now passes the LK201 keyboard self-test (although
		the keyboard ID is still bogus).
20041013	Minor updates.
		Hacks to the ASC SCSI controller for Mach/PMAX, hopefully this
		will not break support for other OSes.
20041014	Minor fix to src/emul.c for reading bootblocks at the end of
		a disk or cdrom image (thanks to Alexandru Lazar for making me
		aware of this).
		Adding "gets()" to src/dec_prom.c.
		Working a bit on ARC stuff. Importing pica.h from NetBSD.
		Minor updates to the ARC component tree for PICA-61.
		Adding a dev_jazz.c (mostly for PICA-61).
		Renaming dev_jazz.c into dev_pica.c. Working on PICA timer
		and interrupt specifics.
20041016	Adding some dummy entries to lk201.c to reduce debug output.
		Some bintrans updates (don't run in delay slots or nullified
		slots, read directly from host memory and not via memory_rw(),
		try mmap() before malloc() at startup, and many other minor
		updates).
		Adding bintrans_mips.c for 64-bit MIPS hosts, but it is not
		used yet.
20041017	Minor updates.
20041018	Update to dev_mc146818 to allow Mach to boot a bit further.
		The "hardware random" in dev_mp.c now returns up to 64 bits
		of random.
20041019	Minor updates to the way cache sizes are used throughout the
		code. Should be mostly ok for R[234]x00.
		src/file.c now loads files using NO_EXCEPTIONS. Whether this
		is good or bad, I'm not sure.
20041020	Adding a Linksys WRT54G emulation skeleton (-H).
20041021	Minor updates.
		R1[024]000 cache size bits in the config register should now
		be ok.
		Trying to make dev_asc.c work better with PICA.
		More work on PICA interrupts (but they are broken now).
20041022	Generalizing the dev_vga text console device so that it can be
		used in other resolutions than just 80x25. Works with
		OpenBSD/arc.
		emul->boot_string_argument is now empty by default (except
		for DECstation modes, where it is "-a").
		Speedup of dev_ram by using mmap() instead of malloc().
		Using mmap() in memory.c as well, which reduces memory usage
		when emulating large memory sizes if the memory isn't actually
		written to.
20041023	Minor updates.
20041024	Updates to the PC-style keyboard controller, used by PICA.
		Updates to the PICA (Jazz) interrupt system. Both NetBSD/arc
		and OpenBSD/arc now reach userland with PICA emulation, and
		can be interacted with (there are a few programs on the
		INSTALL kernel ramdisks). In the case of OpenBSD, a VGA text
		console and PC-style keyboard controller is used, NetBSD
		runs on serial console.
		Adding a framework for DMA transfer for the ASC SCSI
		controller.
		Implementing a R4030 DMA controller for PICA, enough to let
		OpenBSD/arc and NetBSD/arc be installed on an emulated
		Pica. :-)
		Updates to the documentation.
20041025	Working on ISA interrupts for PICA.
		Adding an Olivetti M700 emulation mode (-A7).
		Better separation of PICA and M700 stuff (which I accidentally
		mixed up before, I thought the M700 Linux kernel would 
		also work on PICA because it almost booted).
		Writing a skeleton G364 framebuffer for M700, enough to show
		the Linux penguin and some text, although scrolling isn't
		correctly implemented yet.
		Adding a dummy SONIC (ethernet) device, dev_sn, for PICA.
		Fixing the passing of OSLOADOPTIONS for ARC, the default is
		now "-aN" which works fine with OpenBSD/arc and NetBSD/arc.
20041027	Minor updates.
20041029	Adding a Sony NeWS "newsmips" emulation mode skeleton (-f).
		Found and fixed a bug which prevented Linux/IP32 from running
		(the speed-hack-jump-optimization fix I made a few weeks ago
		was buggy).
		Adding the trunc.w.fmt and trunc.l.fmt instructions, although
		the are probably not really tested yet.
		Changes to how floating point values are handled in
		src/coproc.c, but right now it is probably very unstable.
20041101	I had accidentally removed the instructions on how to install
		Ultrix from doc/index.html. They are back now.
		Adding a -Z option, which makes it easier to run dual- or
		tripple-head with Ultrix. (Default nr of graphics cards
		without -X is 0, with -X is 1.)
		Minor update which makes it possible to switch to the left
		monitor when running tripple-head, not just right as before.
		When using more than one framebuffer window, and the host's
		mouse cursor is in a different window than the emulated mouse
		cursor, the emulated mouse will now try to move "very far",
		so that it in practice changes screen.
		Running Ultrix with dual- and tripple-head now feels really
		great.
20041101(later)	OpenBSD/arc and Linux/Olivetti-M700 don't both work at the
		same time with the speed-hack stuff. So, from now on, you
		need to add -J for Linux, and add nothing for openbsd.
20041102	Minor update for OSF/1 V4.0 (include sys/time.h in src/net.c
		and add -D_POSIX_PII_SOCKET to the C compiler flags).
20041103	Minor updates for the release.
		For some reason, Mach/PMAX caused the emulator to bug out on
		SunOS/sparc64 (compiled in 64-bit mode); a minor update/hack
		to dev_asc fixed this.

==============  RELEASE 0.2.2  ==============

20041103	Minor updates.
20041104	Minor updates.
20041105	Running with different framebuffer windows on different X11
		displays works now (even with different bit depths and
		endiannesses on different displays). A new command line option
		(-z) adds DISPLAYs that should be used.
		Update regarding how DECstation BT459 cursors are used;
		transparency :-) and some other bug fixes.
20041106	More bt459 updates. The cursor color seems to be correct for
		NetBSD, OpenBSD, Ultrix, and Sprite.
		Some minor bintrans updates (redesigning some things).
20041107	More bintrans updates (probably broken for non-Alpha targets).
		Moving doc/mips64emul.1 to man/.
20041108	Some updates.
20041109	More updates. Bintrans experiments mostly.
20041110	Some minor bintrans updates.
20041111	Minor updates.
20041112	A little rewrite of the bintrans system (again :-), this time
		a lot more naďve and non-optimizing, in order to support delay
		slots in a much simpler way.
		Ultrix 4.5 boots into a usable desktop on my home machine in
		3min 28sec, compared to 6-8 minutes without bintrans.
20041113	Some minor bintrans updates.
20041114	More bintrans updates. Ultrix now boots in exactly 3 minutes
		on my home machine.
20041115	More bintrans updates.
20041116	Bintrans updates.
20041117	Working on dev_dec_ioasic and related issues.
		Adding support for letting translated code access devices in
		some cases (such as framebuffers).
20041118	Moving some MIPS registers into Alpha registers, which gives
		a speed improvement.
		Beginning to write an i386 bintrans backend. Skeleton stuff
		works, lui, jr/jalr, addiu/daddiu/andi/ori/xori, j/jal,
		addu/daddu/subu/xor/or/nor/and.
20041119	dsubu/sll/srl/sra, rfe,mfc0,dmfc0, beq,bne, delayed branches.
		Some load/store (but not for bigendian emulation yet.)
		Time to reach Ultrix 4.5's graphical login on a 2.8 GHz Xeon
		host is now down to 20 seconds!
		Adding bgez, bltz, bgtz, and blez to the i386 backend.
20041120	Minor updates (bintrans related mostly).
		Time to reach Ultrix login on the Xeon is now 11 seconds.
		Adding 'mult', 'multu' and a some parts of mtc0 to the Alpha
		backend.
		The transparency updates to the X11 cursor support made the
		OpenBSD/arc cursor disappear; that has been fixed now.
		Unfortunately, something with Acer Pica emulation is broken
		when bintrans is enabled.
20041121	Making tlbwr, tlbwi, tlbp, tlbr callable directly from
		translated code.
		Adding sltiu, slti, slt, and sltu to the i386 backend.
20041122	More bintrans updates.
		With the Alpha backend, the status and entryhi registers
		can (in some cases) be written without exiting to the main
		loop. Ultrix boot time until a usable desktop is reached
		is about 1 min 35 seconds on the 533 MHz pca56.
		Adding srlv, srav, and sllv to the i386 backend.
20041123	Removing the special handling of high physical addresses for
		DECstation emulation from the main memory handling code, and
		replacing it with a mirror device instead. (This results in
		a tiny increase in performance, and cleaner code.)
		Various minor updates.
20041124	Ripping out _all_ bintrans load/store code, because I have
		a new idea I'd like to try out.
		A total rewrite of the load/store system. It works when
		emulating 32-bit MIPS, but not for 64-bit code yet.
		Some minor updates to the dev_fb, but no speed improvement.
		Making the 'le' ethernet device' SRAM work with bintrans.
20041125	Various updates.
		Adding a little "bootup logo" to the framebuffer.
		There is now one translate_address() for R3000-style MMUs,
		and one for the other types. (This gives a tiny speed
		improvement.)
20041126	Minor updates, bintrans.
		Fixing the bug which caused OpenBSD/arc (R4000) to bug out;
		it was introduced between the 7:th and 10:th of November
		when moving up the check for interrupts to above the code
		which runs bintrans code, in src/cpu.c.
		Adding movn and movz to the Alpha bintrans backend.
20041127	Various minor updates.
20041128	Making the R2000/R3000 caches work with bintrans, even in
		isolated mode. (Not true cache emulation, but it works with
		NetBSD/pmax, OpenBSD/pmax, and Ultrix.)
		Making the default cache size for R3000 4KB instr, 4 KB data;
		a real R3000 could have 64KB each, but emulated OSes run
		faster when they think the cache is smaller :-)
		Updates to the i386 backend: the nr of executed instructions
		is now placed in ebp at all times, and some support for
		mtc0 similar to how it is done in the Alpha backend has been
		added. A full NetBSD/pmax 1.6.2 install can now be done in
		5 minutes 35 seconds, on a 2.8 GHz Xeon host (with -bD2 -M20).
		Adding mult and multu to the i386 bintrans backend.
		Reducing the number of malloc/free calls used by the
		diskimage subsystem.
20041129	Minor updates to the Alpha bintrans backend.
20041130	Trying to fix the bug which prevents Linux from working
		with bintrans. It _seems_ to work now. (Pages could in some
		cases be written to after they were translated, but that
		has been fixed now.)
		A couple of other minor fixes.
		Minor updates to the Alpha backend (directly using Alpha
		registers in some cases, instead of loading into temporaries).
		Updates to the i386 backend (special hacks for 32-bit
		MIPS emulation, which are fast on i386, for example only
		updating half of the pc register).
20041201	More updates to the i386 backend, similar to those yesterday.
		Preparing for release 0.2.3.
		Adding a generic load/store mechanism, which is used when the
		32-bit optimized version cannot be used (for R4000 etc).

==============  RELEASE 0.2.3  ==============

20041202	If ALWAYS_SIGNEXTEND_32 is defined in misc.h, and an
		incorrectly extended register is detected, the emulator now
		exits instead of continues.
		Removing the LAST_USED_TLB_EXPERIMENT stuff.
		Minor updates to work better with Windows NT's ARCINST.EXE;
		printing 0x9b via arcbios becomes ESC + '[', and the ARC
		memory descriptor stuff has been generalized a bit more.
		Adding arbios hacks for Open(), Seek(), GetRelativeTime(),
		and Read() to allow WinNT's SETUPLDR to read the filesystem
		on the diskimage used for booting.
20041203	Adding a terminal emulation layer which converts arcbios
		stdout writes to "VGA text console" cell characters. Seems
		to work with Windows NT and arcdiag.
		Adding a 8x8 font to dev_vga.
		Adding more ARC components to the component tree (for PICA
		emulation).
20041204	Minor updates.
		More updates to dev_vga. Adding a 8x10 font.
		Adding a hack so that the framebuffer logo is visible at
		startup with dev_vga. (It disappears at the first scroll.)
		A minor fix for a bug which was triggered when running
		dual- or tripple-head, on 2 or 3 actual X11 displays.
20041205	Fixing a bintrans bug.
		Some other minor updates (some of them bintrans related).
20041206	Moving the web page to http://gavare.se.
		Adding a hack for mmap() which supports anonymous mapping
		using /dev/zero, but not using MAP_ANON{,YMOUS}.
		Separating out opcodes.h, cop0.h, and cpu_types.h from misc.h.
20041207	Minor bintrans update. (In some cases, it isn't necessary
		to return to the main loop, when translating from a new page.)
		Some other minor i386 bintrans backend optimizations.
		And some other minor updates.
		i386 backend update: the lowest 32 bits of the pc register
		are now placed in an i386 register.
20041208	Adding GetConfigurationData() and some support for config
		data, to src/arcbios.c.
		Adding a bogus 0xbd SCSI command (used by Windows NT). It is
		not listed in http://www.danbbs.dk/~dino/SCSI/SCSI2-D.html.
		If the framebuffer cursor contains more than 1 color, then
		the host's X11 cursor disappears. (Nice for DECstation
		emulation with emulated X.)
		For ARC and SGI emulation, if an exception occurs before an
		exception handler is installed, the emulator now exits
		nicely (as suggested by Alec Voropay).
		A couple of minor updates to the ARCBIOS emulation subsystem.
		The single step debugger is now automatically entered when
		all CPUs have stopped running, unless there was a clean
		shutdown of some kind (PROM halt() call, or similar).
		Adding a -V option for starting up in a paused state, into
		the single-step debugger.
		Adding a note about 'mmon' to the documentation
		(http://www.brouhaha.com/~eric/software/mmon/).
20041209	Fixes to devices/console.c which makes cursor keys and such
		a bit more reliable.
		ARCBIOS hack/update which creates memory descriptors _after_
		loading the executable. (Seems to work with OpenBSD/arc,
		NetBSD/arc, arcdiag, IRIX, NetBSD/sgimips, OpenBSD/sgi, and
		some Windows NT executables.)
		ARCBIOS support for cursor keys (ESC + '[' ==> 0x9b).
		A bintrans update (for 32-bit emulation) which speeds up
		jumps between pages, if code is already translated.
		Changing the default bintrans cache from 20 to 24 MB.
20041210	Optimizing unaligned load/stores a little bit in src/cpu.c.
		Omiting the check for nr of executed bintrans instructions
		on some forward jumps.
		Adding the 'syscall' and 'break' instructions to the
		bintrans backends.
		Allowing more bits of the status register to be written to
		from within inside translated code, on R3000.
		Getting rid of the final pixel when hiding the host's mouse
		cursor.
		store_buf() now copies data 8 or 4 bytes at a time, when
		possible. (This speeds up emulated ROM disk reads, etc.)
		Tiny bug fix: coprocessor unusable exceptions are now also
		generated (for coproc 1..3) even when in kernel mode, if the
		coprocessors are not enabled. This allows a Debian installation
		to proceed further than before. (It's still very unstable,
		though.)
20041212	Updating doc/index.html with better Debian installation
		instructions.
		If SLOWSERIALINTERRUPTS is defined at compile time, interrupts
		from the dc7085 device will not come as often as they normally
		do. This makes Debian seem more stable.
		Decreasing the bintrans cache to 20 MB again.
		Updating some files in preparation for a 0.2.4 release.
20041213	Updating the docs on how to install NetBSD 2.0/pmax, and also
		some updates to the section on installing Debian.
		32-bit bintrans backend optimization: don't inline large
		chunks of code, such as general jumps.
20041214	Minor fix for coproc unusable for R4000 (it's the PC that,
		matters, not the KSU bits).
		Separating out the debugger from emul.c into debugger.c.
		Rewriting parts of the debugger.
		Removing the -U command line option, as it wasn't really
		useful. Also removing the -P option.
		Renaming all instances of dumppoint to breakpoint, as that
		is what it really is.
		When a breakpoint is reached, the single-step debugger is
		entered, instead of just turning on instruction trace.
		Adding a 'breakpoints' debugger command.
		Better fix for coproc unusable on R4000: the KSU bits matter,
		but the ERL and EXL bits override that.
		Fix which allows Debian to boot directly from a disk image
		(with DELO). (It reads multiple separate areas from disk.)
		Update to the SLOWSERIALINTERRUPTS stuff, making it even
		slower.
		Fixes based on feedback from Alec Voropay (-Q with ARC
		emulation skips the setup of arcbios data structures in
		memory, and no sign-extension _after_ writing a 32-bit
		value to a 64-bit coproc 0 register).
		Adding a 'devices' command to the debugger.
		The 'registers' and 'tlbdump' commands now take an optional
		argument (a cpu id).
		Adding rudimentary tab-completion and cursor key stuff to
		debugger_readline().
		Adding some more debugger commands: 'bintrans' and 'machine'.
20041215	Adding a 'devstate' command; implementing a skeleton for a
		state function for the bt459 device.
		Implementing yet another variant of the SLOWSERIALINTERRUPTS
		stuff.
		Implementing more of the different exception offsets (taking
		CAUSE_IV and STATUS_BEV into account).
		hpc_bootinfo should now be correctly filled on big-endian
		hosts.
		Always shift left by 12, not by pageshift, to get physical
		addresses on MMU4K etc. (Thanks to Alec Voropay for noticing
		this.)
20041216	The KN02's CSR can now be read from bintranslated code.
		Adding a dummy dev_sgi_mec.
20041217	The default framebuffer and model settings for -F (hpcmips)
		should now be almost like Cassiopeia E-500.
		Changing -DSLOWSERIALINTERRUPTS into a command line option, -U.
20041218	Continuing a little bit on the mec controller.
		Removing lots of #include <math.h> that weren't really used.
20041219	Fixing stuff that broke because of the pageshift bugfix.
		Adding an argument to the s (step) debugger command, for doing
		more than 1 step at a time.
		ARCBIOS components representing disk images are now created
		to actually match the disk images in use, and some other
		arcbios-related updates; adding a dummy GetComponent().
		Adding a 'lookup' command to the debugger, for symbol lookups.
		Adding a "NEC Express RISCserver" mode (NEC-R96, -A8).
		Adding a dummy ARCBIOS GetFileInformation(), GetTime(), and
		SetEnvironmentVariable().
20041220	Improved command line editing (including command history)
		in the debugger.
		Separating some more .h files from each other, and fixing
		some Solaris compiler warnings.
20041221	Minor updates.
20041222	Minor updates; hpcmips (BE300, VR41xx) stuff.
		The 'register' debugger command is now 'reg', and it can
		be used to modify registers, not just read them.
		The syntax for hpcmips (-F) is now -F xx, where xx is a
		machine model identifier. (1 = BE300.)
20041223	Some really minor updates.
20041226	Minor updates to doc/index.html (NetBSD 1.6.2 -> 2.0, and
		some other rearrangements).
		Many updates to the debugger (better register manipulation,
		breakpoint manipulation, and other updates).
		Fix to dev_cons.c to allow the regression tests to work again.
		The configure script now tries to detect the presence of a
		MIPS cross compiler. (Used by "make regtest".)
		Regression tests are now run both with and without bintrans.
20041227	Some hacks to the VR41xx code to allow Linux for BE300 to
		get far enough to show the penguin on the framebuffer.
20041228	Merging dev_kn01_csr.c and dev_vdac.c into dev_kn01.c.
20041229	Various updates to the debugger (nicer tlb output and other
		things).
		Some floating point fixes in src/coproc.c (mov is not
		an arithmetic instruction), and in src/cpu.c (ldcX/sdcX in
		32-bit mode uses register pairs).
		'-O' now also affects the bootstring for SGI and ARC emulation.
		Bintrans updates (slightly faster 32-bit load/store on alpha).
		Updates to the i386 backend too, but no real speed improvement.
20041230	Cleaning up parts of the 64-bit virtual-to-physical code for
		R10000, and per-machine default TLB entries can now be set
		for SGI and ARC machines.
		Fix: SGI-IP27 is ARC64, not ARCS.
20050101	Minor updates.
20050102	Minor updates.
		Fixing a 32-bit 'addu' bug in the bintrans backends.
		Allowing fast load/stores even in 64-bit bintrans mode, if
		the top 32 bits are either 0x00000000 or 0xffffffff (for Alpha
		only).
		Re-enabling ctc0/cfc0 (but what do they do?).
		Adding beql, bnel, blezl, and bgtzl to the Alpha backend.
20050103	Adding fast 32-bit load/store for 64-bit mode emulation to
		the i386 backend too (similar to the Alpha code). Not really
		tested yet, though.
		Adding an incomplete regression test case for lwl/lwr/ldl/ldr.
		Playing around with bintranslated lwl and lwr for Alpha.
20040104	Changing many occurances of pica to jazz.
		Various other updates.
20050105	Fixing some more bintrans bugs (both Alpha and i386).
		Unaligned stores that cause tlb refill exceptions should now
		cause TLBS exceptions, not TLBL.
		Adding experimental swl and swr to the Alpha backend.
		Adding lwl, lwr, swl, and swr to the i386 backend.
20050106	Adding another hpcmips model (Casio E-105, -F2), and doing
		some updates to the VR41xx code. NetBSD/hpcmips prints some
		boot messages.
20050108	Minor updates.
20050109	dev_dec5500_ioboard.c and dev_sgec.c => dev_kn220.c.
		dev_crime.c, _mace.c, and _macepci.c => dev_sgi_ip32.c.
		Also adding dev_sgi_mec, _ust, and _mte into dev_sgi_ip32.c.
		A slight license change. Still revised BSD-style, though.
		memory_v2p.c is now included separately for MMU10K and
		MMU8K.
		Fixing a NS16550 bug, triggered by NetBSD 2.0, but not 1.6.2.
		Refreshing the UltraSPARC bintrans backend skeleton.
		Merging dev_decbi, _deccca, and _decxmi into dev_dec5800.c.
		Sparc backend instructions done so far: mthi/mtlo/mfhi/mflo,
		lui, addu, daddu, subu, dsubu, and, or, nor, xor, sll, dsll,
		srl, and sra.
		Adding more sparc backend instructions: addiu, daddiu, xori,
		ori, andi, srlv, srav, sllv, slt, sltu, slti, sltiu.
20050110	Changing the default bintrans cache to 16 MB, and some other
		minor updates.
		Adding div and divu to the i386 backend (but not Alpha yet).
		More work on ARCBIOS emulation.
		Trying to find a bug which affects Linux on Playstation 2 in
		bintrans mode.
20050111	Moving around some Playstation 2 stuff, but I haven't found
		the bug yet. It is triggered by load/stores.
		More ARCBIOS updates, enough to let Windows NT partition
		disks in some rudimentary fashion.
20050112	Testing for release 0.2.4.
		Fixes to suppress compiler warnings.

==============  RELEASE 0.2.4  ==============

20050113	Minor updates.
20050114	Fix to the Alpha bintrans backend to allow compilation with
		old versions of gcc (2.95.4).

==============  RELEASE 0.2.4.1  ==============

20050115	Various updates and fixes: some IP32 stuff, the debugger,
		ns16550 loopback tx isn't transmitted out anymore, ...
		Removing old/broken R10000 cache hacks, which weren't really
		used.
20050116	Minor updates to the documentation on using PROM images.
		Adding ARCBIOS function 0x100 (used by IRIX when returning
		from main, but undocumented).
		MC146818 updates (mostly SGI-related).
		ARCS64 updates (testing with an OpenBSD snapshot in IP27
		mode). This causes Linux/IP30 to not work. Maybe IP27 and
		IP30 differ, even though both are 64-bit?
		Removing some nonsensical ARCS64 code from machine.c.
		Better handling of 128MB and 512MB memory offsets used by
		various SGI models.
		Trying to revert the ARCS64 changes (OpenBSD/sgi does
		seem to be aware of 64-bit vs 32-bit data structures in
		_some_ places, but not all), to make Linux/IP30 work again.
		Adding "power off" capability to the RTC, as used on IP32
		(and possibly IP30 and others).
		Some IP30 updates.
20050117	Debugger updates (symbolic register names instead of just rX,
		and using %08x instead of %016llx when emulating 32-bit CPUs
		in more places than before).
		Removing the dummy sgi_nasid and sgi_cpuinfo devices.
		Also using symbolic names for coprocessor 0 registers.
		Adding DEV_MP_MEMORY to dev_mp.c.
		Adding a 'put' command to the debugger.
		ARCBIOS function 0x100 used by IRIX seems to _NOT_ be a
		ReturnFromMain(), but something else undocumented.
		The count and compare registers are now 32-bit in all
		places, as they should be. (This causes, among other things,
		OpenBSD/sgi to not hang randomly in userspace anymore.)
		On breakpoints, the debugger is now entered _at_ the
		instruction at the breakpoint, not after it.
		Some cursor keys now work when inputed via X.
		Refreshing the MC146818 device a bit more.
20050118	Trying to add some support for less-than-4KB virtual pages,
		used by at least VR4131. Thanks to Alexander Yurchenko for
		noticing this. (I'm assuming for now that all R41xx work
		this way, which is not necessarily true.) It doesn't really
		work yet though.
		Renicing the "loading files" messages and other things
		displayed during startup.
		Changing the disassembly output of ori, xori, and andi to
		unsigned hex immediate, instead of decimal (as suggested
		by Alec Voropay).
		configure-script update for HP-UX, and switching from using
		inet_aton() to inet_pton() (as suggested by Nils Weller).
		Also adding -lnsl on Solaris, if required by inet_pton().
		Lots of minor R4100-related updates.
20050119	Correcting the R4100 config register in src/coproc.c, and
		a minor update to dev_vr41xx.
		Finally began a redesign/remodelling/cleanup that I have had
		in mind for quite some time... moving many things that were
		in struct emul into a new struct machine.
		Userland emulation now works with bintrans.
		Refreshing the LANCE controller (dev_le.c).
		Fixing the LK201 keyboard id.
20050120	Continuing on the remodelling/cleanup.
		Fixing the SCSI bug (which was triggered sometimes by
		NetBSD 2.0/pmax on Linux/i386 hosts).
		Adding a speed-limit hack to the mc146818 device when running
		in DECstation mode (limiting to emulated 30 MHz clock, so
		that Ultrix doesn't freak out).
		Adding an ugly workaround for the floating-point bug which
		is triggered when running NetBSD/pmax 2.0 on an Alpha host.
		The count/compare interrupt will not be triggered now, if
		the compare register is left untouched.
		Many, many other fixes...
20050121	Continuing the remodelling/cleanup. (Mostly working on the
		network stack, and on moving towards multiple emulations
		with multiple machines per emulation.)
		Fixbug: not clearing lowest parts of lo0 and hi on tlbr
		(seems to increase performance when emulating Linux?).
20050122	Continuing the remodelling/cleanup.
		Linux on DECstation uses a non-used part of the RTC registers
		for the year value; this is supported now, so Linux thinks
		it is 2005 and not 2000.
		Began hacking on something to reply to Debian's DHCP requests,
		but it's not working yet.
20050123	Continuing the remodelling/cleanup.
20050124	Continuing the remodelling/cleanup.
		Converting the dev_vga charcell memory to support direct
		bintrans access (similar to how dev_fb works), and fixing a
		couple of bintrans bugs in the process.
		The emulator now compiles under OpenBSD/arc 2.3 without
		crashing (mostly due to the bintrans fixes, but also some
		minor updates to the configure script).
20050125	Continuing the remodelling/cleanup.
		The '-a' option was missing in the Hello World example in the
		documentation. (Thanks to Soohyun Cho for noticing this.)
20050126	Continuing the remodelling/cleanup. Moving around stuff in
		the header files, etc. Adding a '-K' command line option, which
		forces the debugger to be entered at the exit of a simulation,
		regardless of failure or success. Beginning to work on the
		config file parser.
		Splitting doc/index.html into experiments.html, guestoses.html,
		intro.html, and misc.html.
		Updating the man page and adding a skeleton section about the
		configure files to doc/misc.html.
20050127	Minor documentation updates.
20050128	Continuing the remodelling/cleanup, mostly working on the
		config file parser (adding a couple of machine words, enough
		to run simple emulations, and adding support for multi-line
		comments using tuborgs).
		Removing some command line options for the least working
		emulation modes (-e, -f, -g, -E, -H), adding new -E and -e
		options for selecting machine type.
		Moving global variables from src/x11.c into struct machine (a
		bit buggy, but it seems to almost work).
20050129	Removing the Playstation 2 mode (-B) and hpcmips modes (-F)
		from the command line as well.
		Changing the -T command line option from meaning "trace on bad
		address" to meaning "enter the single-step debugger on bad
		address".
		More updates to the configuration file parser (nested tuborg
		comments, more options, ...).
		Making -s a global setting, not just affecting one machine.
		Trying to fix the X11 event stuff... but it's so ugly that it
		must be rewritten later.
		Continuing the multi-emul cleanup.
		Bugfixes and other updates to dev_vga.
20050130	Continuing the remodelling/cleanup. Finally moving out the
		MIPS dependant stuff of the cpu struct into its own struct.
		Renaming cpu.c to cpu_mips.c, and cpu_common.c to cpu.c.
		Adding a dummy cpu_ppc.c.
		Removing the UltraSPARC bintrans backend.
		Many other minor updates.
		src/file.c should now be free from MIPS-dependancies.
20050131	Continuing a little bit more on src/file.c. PPC ELFs can now
		be loaded, it seems.
		Continuing on src/cpu_ppc.c.
		'mips' is undefined by the configure script, if it is defined
		by default. (Fixes build on at least OpenBSD/arc and
		NetBSD/arc, where gcc defines 'mips'.)
		A couple of other minor fixes.
		Removing the "Changing framebuffer resolution" section from
		doc/misc.h (because it's buggy and not very useful anway).
		Adding a mystrtoull(), used on systems where there is no
		strtoull() in libc.
		Adding 'add_x11_display' to the configure file parser 
		(corresponding to the -z command line option).
		Continuing the multi-emul machine cleanup.
20050201	Minor updates (man page, RELEASE, README).
		Continuing the cleanup.
		Adding a 'name' field to the emul struct, and adding a command
		to the debugger ("focus") to make it possible to switch focus
		to different machines (in different emuls).
		Beginning to work on the PPC disassembler etc. Hello World
		for linux-ppc64 can be disassembled :-)
20050202	Adding a hack for reading symbols from Microsoft's variant of
		COFF files.
		Adding a dummy cpu_sparc.c and include/cpu_sparc.h.
		Cleaning up more to support multiple cpu families.
		Various other minor updates.
		Fixing another old-gcc-on-Alpha problem.
20050203	Bintrans cache size is now variable, settable by a new
		configuration file option 'bintrans_size'.
		The debugger can now theoretically call disassembler functions
		for cpu families with non-fixed instruction word length.
		Working more on the mec controller. It now works well enough
		to let both NetBSD/sgimips and OpenBSD/sgi connect to the
		outside world using ftp :-)
		Continuing on the cleanup of the networking subsystem.
20050204	Continuing the cleanup.
		Working on a way to use separate xterms for serial ports and
		other console input, when emulating multiple machines (or one
		machine with multiple serial lines active).
20050205	Minor documentation updates.
20050206	Moving console.c from devices/ to src/, and continuing the
		work on using separate windows for each serial console.
		Trying to get OpenBSD/sgi to boot with root-on-nfs on an
		emulated NetBSD/pmax server, but no success in setting up
		the server yet.
20050207	Continuing on the console cleanup.
		Adding a 'start_paused' configuration file option, and a
		'pause' command to the debugger.
20050208	Everything now builds with --withoutmips.
		Continuing on the documentation on how to run OpenBSD/sgi, but
		no actual success yet.
		sizeof => (int)sizeof in the configure script (as suggested by
		Nils Weller).
20050209	Adding a check for -lm to the configure script.
		Continuing on the cleanup: trying to make memory_rw non-MIPS
		dependant.
		Trying to make a better fix for the cdrom-block-size problems
		on FreeBSD. (It now works with a Windows NT 4.0 cdrom in my
		drive.)
		Began a clean-up of the userland subsystem.
20050210	Continuing the userland cleanup.
		IBM's Hello World example for Linux/PPC64 runs fine now.
20050211	Continuing the cleanup. Removing the --userland configure
		option (because support for userland is always included now).
		Working more on getting OpenBSD/sgi to boot with root on
		nfs. (Booting with the ramdisk kernel, and mounting root via
		nfs works, but not yet from the generic kernel.)
		Major update to the manpage.
		Removing the -G command line option (SGI modes).
20050212	Updating the documentation (experimental devices: dev_cons
		and dev_mp, better hello.c, and some other things).
20050213	Some minor fixes: documentation, 80 columns in some source
		files, better configure script options.
		Adding some more PPC instructions.
		Added a NOFPU flag to the MIPS cpu flags, so that executing
		FPU instructions on for example VR4xxx will fail (as suggested
		by Alexander Yurchenko).
20050214	Implementing more PPC instructions.
		Adding dev_pmppc.
20050215	Continuing the work on PPC emulation. Adding a (mostly non-
		working) NetBSD/powerpc userland mode, a (buggy)
		show_trace_tree thing (simliar to the MIPS version).
20050216	Continuing...
20050218	Continuing the clean-up. (Merging the devices and devstate
		debugger commands, more 80-column cleanup, some documentation
		updates, ...).
20050219	Removing the -D, -A, and -a command line options. Updating the
		documentation, in preparation for the next release.
		Adding interrupt stuff to dev_cons.
		Single-stepping now looks/works better with bintrans enabled.
		Beginning the first phase of release testing; various minor
		updates to make everything build cleanly on Solaris.
20050220	Continuing testing for the release...
                
==============  RELEASE 0.3  ==============

20050221	Minor updates. Some more clean-up.
		Beginning on the new device registry stuff.
20050222	Continuing on the device stuff, and doing various other kinds
		of clean-up.
		Adding a dummy BeBox mode.
		Making the pc register common for all cpu families.
		Adding some more PPC instructions and fixing some bugs.
20050223	Continuing on the BeBox stuff, and adding more instructions.
		Adding an ns16550 to the VR4131 emulation (which is probably
		a close enough fake to the VR4131's SIU unit).
20050224	Minor updates. Adding dummy PReP, macppc, and DB64360 modes.
		Continuing on the device registry rewrite.
20050225	Continuing on the device stuff.
20050226	Continuing more on the device rewrite.
		Separating the "testmips" machine into testmips and baremips
		(and similarly with the ppc machine).
		Redesigning the device registry again :-)
		Adding a "device" command to the config file parser.
		Adding "device add" and "device remove" to the debugger.
		Removing pcidevs.h, because it was almost unused.
20050228	Correcting the Sprite disk image url in the documentation.
20050301	Adding an URISC cpu emulation mode (single-opcode machine).
20050303	Adding some files to the experiments directory (rssb_as.c,
		rssb_as.README, urisc_test.s).
		Continuing on the device stuff.
20050304	Minor documentation update. Also, the SPARC, PPC, and URISC
		modes are now enabled by default in the configure script.
		Some minor PPC updates (adding a VGA device to the bebox
		emulation mode).
20050305	Moving the static i386 bintrans runchunk code snippet (and the
		others) to be dynamically generated. (This allows the code to
		compile on i386 with old gcc.)
		Loading PPC64 ELFs now sets R2 to the TOC base.
		Changing the name of the emulator from mips64emul to GXemul.
		Splitting out the configuration file part of the documentation
		into its own file (configfiles.html).
20050306	Some really minor documentation updates.
		Adding a -D command line option (for "fully deterministic"
		behaviour).
20050308	Minor PPC updates. Adding a dummy OpenFirmware emulation layer.
20050309	Adding a hack for systems without inet_pton (such as Cygwin in
		Windows) as suggested by Soohyun Cho. (And updating the
		configure script too.)
		Adding a dummy HPPA cpu family.
		Some more OpenFirmware updates.
		Faster loading of badly aligned ELF regions.
20050311	Minor updates. Adding a dummy "NEC MobilePro 780" hpcmips
		machine mode; disabling direct bintrans access to framebuffers
		that are not 4K page aligned.
20050312	Adding an ugly KIU hack to the VR41xx device (which enables
		NetBSD/hpcmips MobilePro 780 keyboard input).
20050313	Adding a dummy "pcic" device (a pcmcia card controller).
		Adding a dummy Alpha cpu emulation mode.
		Fixing a strcmp length bug (thanks to Alexander Yurchenko for
		noticing the bug).
20050314	Some minor bintrans-related updates in preparation for a new
		bintrans subsystem: command line option -b now means "old
		bintrans", -B means "disable bintrans", and using no option at
		all selects "new bintrans".
		Better generation of MAC addresses when emulating multiple
		machines and/or NICs.
		Minor documentation updates (regarding configuration files).
20050315	Adding dummy standby, suspend, and hibernate MIPS opcodes.
		RTC interrupt hack for VR4121 (hpcmips).
		Enough of the pcic is now emulated to let NetBSD/hpcmips detect
		a PCMCIA harddisk controller card (but there is no support for
		ISA/PCMCIA interrupts yet).
		Adding preliminary instructions on how to install
		NetBSD/hpcmips.
		Continuing the attempt to get harddisks working with interrupts
		(pcic, wdc on hpcmips).
20050318	Minor updates. (Fixing disassembly of MIPS bgtz etc., 
		continuing on the device cleanup, ...)
20050319	Minor updates.
20050320	Minor updates.
20050322	Various minor updates.
20050323	Some more minor updates.
20050328	VR41xx-related updates (keyboard stuff: the space key and
		shifted and ctrled keys are now working in userland (ie
		NetBSD/hpcmips' ramdisk installer).
		Also adding simple cursor key support to the VR41xx kiu.
20050329	Some progress on the wdc.
		Updating the documentation of how to (possibly) install
		NetBSD/hpcmips, once it is working.
		Adding delays before wdc interrupts; this allows NetBSD
		2.0/hpcmips to be successfully installed!
		Mirroring physical addresses 0x8....... to 0x00000000 on
		hpcmips; this makes it possible to run X11 inside
		NetBSD/hpcmips :-)
		Updating the documentation regarding NetBSD/hpcmips.
		Fixing 16-bit vs 15-bit color in dev_fb.
20050330	Print a warning when the user attempts to load a gzipped
		file. (Thanks to Juan RP for making me aware of this "bug".)
20050331	Importing aic7xxx_reg.h from NetBSD.
		Adding a "-x" command line option, which forces xterms for
		each emulated serial port to always be opened.
		Adding a MobilePro 770 mode (same as 780, but different
		framebuffer address which allows bintrans = fast scrolling),
		and a MobilePro 800 (with 800x600 pixels framebuffer :-).
20050401	Minor updates.
20050402	Minor updates. (The standby and suspend instructions are
		bintransed as NOPs, and some minor documentation updates.)
20050403	Adding an Agenda VR3 mode, and playing around with a Linux
		kernel image, but not much success yet.
		Changing BIFB_D16_FFFF -> BIFB_D16_0000 for the hpcmips 
		framebuffers, causing NetBSD to boot with correct colors.
		New syntax for loading raw files: loadaddr:skiplen:
		initialpc:filename. (This is necessary to boot the Linux VR3
		kernels.)
		The Linux VR3 kernel boots in both serial console mode and
		using the framebuffer, but it panics relatively early.
20050404	Continuing on the AHC, and some other minor updates.
20050405	Adding a note in doc/experimental.html about "root1.2.6.cramfs"
		(thanks to Alec Voropay for noticing that it wasn't part
		of root1.2.6.kernel-8.00).
		Also adding a note about another cramfs image.
		-o options are now added to the command line passed to the
		Linux kernel, when emulating the VR3.
		Adding a MobilePro 880 mode, and a dummy IBM WorkPad Z50 mode.
20050406	Connecting the VR3 serial controller to irq 9 (Linux calls this
		irq 17), and some other interrupt-related cleanups.
		Reducing the memory overhead per bintranslated page. (Hopefully
		this makes things faster, or at least not slower...)
20050407	Some more cleanup regarding command line argument passing for
		the hpcmips modes.
		Playing with Linux kernels for MobilePro 770 and 800; they get
		as far as mounting a root filesystem, but then crash.
		Doing some testing for the next release.

==============  RELEASE 0.3.1  ==============


1 dpavlin 2 /*
2     * Copyright (C) 2003-2005 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: machine.c,v 1.406 2005/04/06 23:13:37 debug Exp $
29     *
30     * Emulation of specific machines.
31     *
32     * This module is quite large. Hopefully it is still clear enough to be
33     * easily understood. The main parts are:
34     *
35     * Helper functions.
36     *
37     * Machine specific Interrupt routines.
38     *
39     * Machine specific Initialization routines.
40     */
41    
42     #include <stdio.h>
43     #include <stdlib.h>
44     #include <stdarg.h>
45     #ifdef SOLARIS
46     #include <strings.h>
47     #else
48     #include <string.h>
49     #endif
50     #include <time.h>
51     #include <unistd.h>
52    
53     #include "arcbios.h"
54     #include "bus_pci.h"
55     #include "cpu.h"
56     #include "cpu_mips.h"
57     #include "device.h"
58     #include "devices.h"
59     #include "diskimage.h"
60     #include "emul.h"
61     #include "machine.h"
62     #include "memory.h"
63     #include "misc.h"
64     #include "mp.h"
65     #include "net.h"
66     #include "symbol.h"
67    
68     /* For SGI and ARC emulation: */
69     #include "sgi_arcbios.h"
70     #include "arcbios_other.h"
71     #include "crimereg.h"
72    
73     /* For DECstation emulation: */
74     #include "dec_prom.h"
75     #include "dec_bootinfo.h"
76     #include "dec_5100.h"
77     #include "dec_kn01.h"
78     #include "dec_kn02.h"
79     #include "dec_kn03.h"
80     #include "dec_kmin.h"
81     #include "dec_maxine.h"
82    
83     /* HPC: */
84     #include "hpc_bootinfo.h"
85     #include "vripreg.h"
86    
87    
88     struct machine_entry_subtype {
89     int machine_subtype;/* Old-style subtype */
90     const char *name; /* Official name */
91     int n_aliases;
92     char **aliases; /* Aliases */
93     };
94    
95     struct machine_entry {
96     struct machine_entry *next;
97    
98     /* Machine type: */
99     int arch;
100     int machine_type; /* Old-style type */
101     const char *name; /* Official name */
102     int n_aliases;
103     char **aliases; /* Aliases */
104    
105     /* Machine subtypes: */
106     int n_subtypes;
107     struct machine_entry_subtype **subtype;
108     };
109    
110     /* This is initialized by machine_init(): */
111     static struct machine_entry *first_machine_entry = NULL;
112    
113    
114     /*
115     * machine_new():
116     *
117     * Returns a reasonably initialized struct machine.
118     */
119     struct machine *machine_new(char *name, struct emul *emul)
120     {
121     struct machine *m;
122     m = malloc(sizeof(struct machine));
123     if (m == NULL) {
124     fprintf(stderr, "machine_new(): out of memory\n");
125     exit(1);
126     }
127    
128     memset(m, 0, sizeof(struct machine));
129    
130     /* Back pointer: */
131     m->emul = emul;
132    
133     m->name = strdup(name);
134    
135     /* Sane default values: */
136     m->serial_nr = 0;
137     m->machine_type = MACHINE_NONE;
138     m->machine_subtype = MACHINE_NONE;
139     m->bintrans_enable = 1;
140     m->prom_emulation = 1;
141     m->speed_tricks = 1;
142     m->byte_order_override = NO_BYTE_ORDER_OVERRIDE;
143     m->boot_kernel_filename = "";
144     m->boot_string_argument = NULL;
145     m->automatic_clock_adjustment = 1;
146     m->x11_scaledown = 1;
147     m->n_gfx_cards = 1;
148     m->dbe_on_nonexistant_memaccess = 1;
149     m->show_symbolic_register_names = 1;
150     m->bintrans_size = DEFAULT_BINTRANS_SIZE_IN_MB * 1048576;
151     symbol_init(&m->symbol_context);
152    
153     return m;
154     }
155    
156    
157     /*
158     * machine_name_to_type():
159     *
160     * Take a type and a subtype as strings, and convert them into numeric
161     * values used internally throughout the code.
162     *
163     * Return value is 1 on success, 0 if there was no match.
164     * Also, any errors/warnings are printed using fatal()/debug().
165     */
166     int machine_name_to_type(char *stype, char *ssubtype,
167     int *type, int *subtype, int *arch)
168     {
169     struct machine_entry *me;
170     int i, j, k;
171    
172     *type = MACHINE_NONE;
173     *subtype = 0;
174    
175     me = first_machine_entry;
176     while (me != NULL) {
177     for (i=0; i<me->n_aliases; i++)
178     if (strcasecmp(me->aliases[i], stype) == 0) {
179     /* Found a type: */
180     *type = me->machine_type;
181     *arch = me->arch;
182    
183     if (me->n_subtypes == 0)
184     return 1;
185    
186     /* Check for subtype: */
187     for (j=0; j<me->n_subtypes; j++)
188     for (k=0; k<me->subtype[j]->n_aliases;
189     k++)
190     if (strcasecmp(ssubtype,
191     me->subtype[j]->aliases[k]
192     ) == 0) {
193     *subtype = me->subtype[
194     j]->machine_subtype;
195     return 1;
196     }
197    
198     fatal("unknown subtype '%s' for emulation"
199     " '%s'\n", ssubtype, stype);
200     exit(1);
201     }
202    
203     me = me->next;
204     }
205    
206     fatal("machine_name_to_type(): unknown emulation type '%s' (", stype);
207     if (ssubtype == NULL)
208     fatal("no subtype)\n");
209     else
210     fatal("subtype '%s')\n", ssubtype);
211    
212     fatal("Use the -H command line option to get a list of available"
213     " types and subtypes.\n");
214     return 0;
215     }
216    
217    
218     /*
219     * machine_add_tickfunction():
220     *
221     * Adds a tick function (a function called every now and then, depending on
222     * clock cycle count) to a machine.
223     */
224     void machine_add_tickfunction(struct machine *machine, void (*func)
225     (struct cpu *, void *), void *extra, int clockshift)
226     {
227     int n = machine->n_tick_entries;
228    
229     if (n >= MAX_TICK_FUNCTIONS) {
230     fprintf(stderr, "machine_add_tickfunction(): too "
231     "many tick functions\n");
232     exit(1);
233     }
234    
235     /* Don't use too low clockshifts, that would be too inefficient
236     with bintrans. */
237     if (clockshift < N_SAFE_BINTRANS_LIMIT_SHIFT)
238     fatal("WARNING! clockshift = %i, less than "
239     "N_SAFE_BINTRANS_LIMIT_SHIFT (%i)\n",
240     clockshift, N_SAFE_BINTRANS_LIMIT_SHIFT);
241    
242     machine->ticks_till_next[n] = 0;
243     machine->ticks_reset_value[n] = 1 << clockshift;
244     machine->tick_func[n] = func;
245     machine->tick_extra[n] = extra;
246    
247     machine->n_tick_entries ++;
248     }
249    
250    
251     /****************************************************************************
252     * *
253     * Helper functions *
254     * *
255     ****************************************************************************/
256    
257    
258     int int_to_bcd(int i)
259     {
260     return (i/10) * 16 + (i % 10);
261     }
262    
263    
264     /*
265     * dump_mem_string():
266     *
267     * Dump the contents of emulated RAM as readable text. Bytes that aren't
268     * readable are dumped in [xx] notation, where xx is in hexadecimal.
269     * Dumping ends after DUMP_MEM_STRING_MAX bytes, or when a terminating
270     * zero byte is found.
271     */
272     #define DUMP_MEM_STRING_MAX 45
273     void dump_mem_string(struct cpu *cpu, uint64_t addr)
274     {
275     int i;
276     for (i=0; i<DUMP_MEM_STRING_MAX; i++) {
277     unsigned char ch = '\0';
278    
279     cpu->memory_rw(cpu, cpu->mem, addr + i, &ch, sizeof(ch),
280     MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
281     if (ch == '\0')
282     return;
283     if (ch >= ' ' && ch < 126)
284     debug("%c", ch);
285     else
286     debug("[%02x]", ch);
287     }
288     }
289    
290    
291     /*
292     * store_byte():
293     *
294     * Stores a byte in emulated ram. (Helper function.)
295     */
296     void store_byte(struct cpu *cpu, uint64_t addr, uint8_t data)
297     {
298     if ((addr >> 32) == 0)
299     addr = (int64_t)(int32_t)addr;
300     cpu->memory_rw(cpu, cpu->mem,
301     addr, &data, sizeof(data), MEM_WRITE, CACHE_DATA);
302     }
303    
304    
305     /*
306     * store_string():
307     *
308     * Stores chars into emulated RAM until a zero byte (string terminating
309     * character) is found. The zero byte is also copied.
310     * (strcpy()-like helper function, host-RAM-to-emulated-RAM.)
311     */
312     void store_string(struct cpu *cpu, uint64_t addr, char *s)
313     {
314     do {
315     store_byte(cpu, addr++, *s);
316     } while (*s++);
317     }
318    
319    
320     /*
321     * add_environment_string():
322     *
323     * Like store_string(), but advances the pointer afterwards. The most
324     * obvious use is to place a number of strings (such as environment variable
325     * strings) after one-another in emulated memory.
326     */
327     void add_environment_string(struct cpu *cpu, char *s, uint64_t *addr)
328     {
329     store_string(cpu, *addr, s);
330     (*addr) += strlen(s) + 1;
331     }
332    
333    
334     /*
335     * store_64bit_word():
336     *
337     * Stores a 64-bit word in emulated RAM. Byte order is taken into account.
338     * Helper function.
339     */
340     int store_64bit_word(struct cpu *cpu, uint64_t addr, uint64_t data64)
341     {
342     unsigned char data[8];
343     if ((addr >> 32) == 0)
344     addr = (int64_t)(int32_t)addr;
345     data[0] = (data64 >> 56) & 255;
346     data[1] = (data64 >> 48) & 255;
347     data[2] = (data64 >> 40) & 255;
348     data[3] = (data64 >> 32) & 255;
349     data[4] = (data64 >> 24) & 255;
350     data[5] = (data64 >> 16) & 255;
351     data[6] = (data64 >> 8) & 255;
352     data[7] = (data64) & 255;
353     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
354     int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
355     tmp = data[1]; data[1] = data[6]; data[6] = tmp;
356     tmp = data[2]; data[2] = data[5]; data[5] = tmp;
357     tmp = data[3]; data[3] = data[4]; data[4] = tmp;
358     }
359     return cpu->memory_rw(cpu, cpu->mem,
360     addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
361     }
362    
363    
364     /*
365     * store_32bit_word():
366     *
367     * Stores a 32-bit word in emulated RAM. Byte order is taken into account.
368     * (This function takes a 64-bit word as argument, to suppress some
369     * warnings, but only the lowest 32 bits are used.)
370     */
371     int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
372     {
373     unsigned char data[4];
374     if ((addr >> 32) == 0)
375     addr = (int64_t)(int32_t)addr;
376     data[0] = (data32 >> 24) & 255;
377     data[1] = (data32 >> 16) & 255;
378     data[2] = (data32 >> 8) & 255;
379     data[3] = (data32) & 255;
380     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
381     int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
382     tmp = data[1]; data[1] = data[2]; data[2] = tmp;
383     }
384     return cpu->memory_rw(cpu, cpu->mem,
385     addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
386     }
387    
388    
389     /*
390     * store_16bit_word():
391     *
392     * Stores a 16-bit word in emulated RAM. Byte order is taken into account.
393     * (This function takes a 64-bit word as argument, to suppress some
394     * warnings, but only the lowest 16 bits are used.)
395     */
396     int store_16bit_word(struct cpu *cpu, uint64_t addr, uint64_t data16)
397     {
398     unsigned char data[2];
399     if ((addr >> 32) == 0)
400     addr = (int64_t)(int32_t)addr;
401     data[0] = (data16 >> 8) & 255;
402     data[1] = (data16) & 255;
403     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
404     int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
405     }
406     return cpu->memory_rw(cpu, cpu->mem,
407     addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
408     }
409    
410    
411     /*
412     * store_buf():
413     *
414     * memcpy()-like helper function, from host RAM to emulated RAM.
415     */
416     void store_buf(struct cpu *cpu, uint64_t addr, char *s, size_t len)
417     {
418     if ((addr >> 32) == 0)
419     addr = (int64_t)(int32_t)addr;
420     if ((addr & 7) == 0 && (((size_t)s) & 7) == 0) {
421     while (len >= 8) {
422     cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)s,
423     8, MEM_WRITE, CACHE_DATA);
424     addr += 8;
425     s += 8;
426     len -= 8;
427     }
428     }
429    
430     if ((addr & 3) == 0 && (((size_t)s) & 3) == 0) {
431     while (len >= 4) {
432     cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)s,
433     4, MEM_WRITE, CACHE_DATA);
434     addr += 4;
435     s += 4;
436     len -= 4;
437     }
438     }
439    
440     while (len-- != 0)
441     store_byte(cpu, addr++, *s++);
442     }
443    
444    
445     /*
446     * store_pointer_and_advance():
447     *
448     * Stores a 32-bit or 64-bit pointer in emulated RAM, and advances the
449     * target address. (Used by ARC and SGI initialization.)
450     */
451     void store_pointer_and_advance(struct cpu *cpu, uint64_t *addrp,
452     uint64_t data, int flag64)
453     {
454     uint64_t addr = *addrp;
455     if (flag64) {
456     store_64bit_word(cpu, addr, data);
457     addr += 8;
458     } else {
459     store_32bit_word(cpu, addr, data);
460     addr += 4;
461     }
462     *addrp = addr;
463     }
464    
465    
466     /*
467     * load_32bit_word():
468     *
469     * Helper function. Prints a warning and returns 0, if the read failed.
470     * Emulated byte order is taken into account.
471     */
472     uint32_t load_32bit_word(struct cpu *cpu, uint64_t addr)
473     {
474     unsigned char data[4];
475    
476     if ((addr >> 32) == 0)
477     addr = (int64_t)(int32_t)addr;
478     cpu->memory_rw(cpu, cpu->mem,
479     addr, data, sizeof(data), MEM_READ, CACHE_DATA);
480    
481     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
482     int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
483     tmp = data[1]; data[1] = data[2]; data[2] = tmp;
484     }
485    
486     return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
487     }
488    
489    
490     /*
491     * store_64bit_word_in_host():
492     *
493     * Stores a 64-bit word in the _host's_ RAM. Emulated byte order is taken
494     * into account. This is useful when building structs in the host's RAM
495     * which will later be copied into emulated RAM.
496     */
497     void store_64bit_word_in_host(struct cpu *cpu,
498     unsigned char *data, uint64_t data64)
499     {
500     data[0] = (data64 >> 56) & 255;
501     data[1] = (data64 >> 48) & 255;
502     data[2] = (data64 >> 40) & 255;
503     data[3] = (data64 >> 32) & 255;
504     data[4] = (data64 >> 24) & 255;
505     data[5] = (data64 >> 16) & 255;
506     data[6] = (data64 >> 8) & 255;
507     data[7] = (data64) & 255;
508     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
509     int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
510     tmp = data[1]; data[1] = data[6]; data[6] = tmp;
511     tmp = data[2]; data[2] = data[5]; data[5] = tmp;
512     tmp = data[3]; data[3] = data[4]; data[4] = tmp;
513     }
514     }
515    
516    
517     /*
518     * store_32bit_word_in_host():
519     *
520     * See comment for store_64bit_word_in_host().
521     *
522     * (Note: The data32 parameter is a uint64_t. This is done to suppress
523     * some warnings.)
524     */
525     void store_32bit_word_in_host(struct cpu *cpu,
526     unsigned char *data, uint64_t data32)
527     {
528     data[0] = (data32 >> 24) & 255;
529     data[1] = (data32 >> 16) & 255;
530     data[2] = (data32 >> 8) & 255;
531     data[3] = (data32) & 255;
532     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
533     int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
534     tmp = data[1]; data[1] = data[2]; data[2] = tmp;
535     }
536     }
537    
538    
539     /*
540     * store_16bit_word_in_host():
541     *
542     * See comment for store_64bit_word_in_host().
543     */
544     void store_16bit_word_in_host(struct cpu *cpu,
545     unsigned char *data, uint16_t data16)
546     {
547     data[0] = (data16 >> 8) & 255;
548     data[1] = (data16) & 255;
549     if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
550     int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
551     }
552     }
553    
554    
555     /****************************************************************************
556     * *
557     * Machine dependant Interrupt routines *
558     * *
559     ****************************************************************************/
560    
561    
562     /*
563     * DECstation KN02 interrupts:
564     */
565     void kn02_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
566     {
567     int current;
568    
569     irq_nr -= 8;
570     irq_nr &= 0xff;
571    
572     if (assrt) {
573     /* OR in the irq_nr into the CSR: */
574     m->kn02_csr->csr[0] |= irq_nr;
575     } else {
576     /* AND out the irq_nr from the CSR: */
577     m->kn02_csr->csr[0] &= ~irq_nr;
578     }
579    
580     current = m->kn02_csr->csr[0] & m->kn02_csr->csr[2];
581     if (current == 0)
582     cpu_interrupt_ack(cpu, 2);
583     else
584     cpu_interrupt(cpu, 2);
585     }
586    
587    
588     /*
589     * DECstation KMIN interrupts:
590     *
591     * TC slot 3 = system slot.
592     */
593     void kmin_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
594     {
595     irq_nr -= 8;
596     /* debug("kmin_interrupt(): irq_nr=%i assrt=%i\n", irq_nr, assrt); */
597    
598     if (assrt)
599     m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] |= irq_nr;
600     else
601     m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] &= ~irq_nr;
602    
603     if (m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10]
604     & m->dec_ioasic_data->reg[(IOASIC_IMSK - IOASIC_SLOT_1_START) / 0x10])
605     cpu_interrupt(cpu, KMIN_INT_TC3);
606     else
607     cpu_interrupt_ack(cpu, KMIN_INT_TC3);
608     }
609    
610    
611     /*
612     * DECstation KN03 interrupts:
613     */
614     void kn03_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
615     {
616     irq_nr -= 8;
617     /* debug("kn03_interrupt(): irq_nr=0x%x assrt=%i\n", irq_nr, assrt); */
618    
619     if (assrt)
620     m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] |= irq_nr;
621     else
622     m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] &= ~irq_nr;
623    
624     if (m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10]
625     & m->dec_ioasic_data->reg[(IOASIC_IMSK - IOASIC_SLOT_1_START) / 0x10])
626     cpu_interrupt(cpu, KN03_INT_ASIC);
627     else
628     cpu_interrupt_ack(cpu, KN03_INT_ASIC);
629     }
630    
631    
632     /*
633     * DECstation MAXINE interrupts:
634     */
635     void maxine_interrupt(struct machine *m, struct cpu *cpu,
636     int irq_nr, int assrt)
637     {
638     irq_nr -= 8;
639     debug("maxine_interrupt(): irq_nr=0x%x assrt=%i\n", irq_nr, assrt);
640    
641     if (assrt)
642     m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START)
643     / 0x10] |= irq_nr;
644     else
645     m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START)
646     / 0x10] &= ~irq_nr;
647    
648     if (m->dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10]
649     & m->dec_ioasic_data->reg[(IOASIC_IMSK - IOASIC_SLOT_1_START)
650     / 0x10])
651     cpu_interrupt(cpu, XINE_INT_TC3);
652     else
653     cpu_interrupt_ack(cpu, XINE_INT_TC3);
654     }
655    
656    
657     /*
658     * DECstation KN230 interrupts:
659     */
660     void kn230_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
661     {
662     int r2 = 0;
663    
664     m->kn230_csr->csr |= irq_nr;
665    
666     switch (irq_nr) {
667     case KN230_CSR_INTR_SII:
668     case KN230_CSR_INTR_LANCE:
669     r2 = 3;
670     break;
671     case KN230_CSR_INTR_DZ0:
672     case KN230_CSR_INTR_OPT0:
673     case KN230_CSR_INTR_OPT1:
674     r2 = 2;
675     break;
676     default:
677     fatal("kn230_interrupt(): irq_nr = %i ?\n", irq_nr);
678     }
679    
680     if (assrt) {
681     /* OR in the irq_nr mask into the CSR: */
682     m->kn230_csr->csr |= irq_nr;
683    
684     /* Assert MIPS interrupt 2 or 3: */
685     cpu_interrupt(cpu, r2);
686     } else {
687     /* AND out the irq_nr mask from the CSR: */
688     m->kn230_csr->csr &= ~irq_nr;
689    
690     /* If the CSR interrupt bits are all zero,
691     clear the bit in the cause register as well. */
692     if (r2 == 2) {
693     /* irq 2: */
694     if ((m->kn230_csr->csr & (KN230_CSR_INTR_DZ0
695     | KN230_CSR_INTR_OPT0 | KN230_CSR_INTR_OPT1)) == 0)
696     cpu_interrupt_ack(cpu, r2);
697     } else {
698     /* irq 3: */
699     if ((m->kn230_csr->csr & (KN230_CSR_INTR_SII |
700     KN230_CSR_INTR_LANCE)) == 0)
701     cpu_interrupt_ack(cpu, r2);
702     }
703     }
704     }
705    
706    
707     /*
708     * Jazz interrupts (for Acer PICA-61 etc):
709     *
710     * 0..7 MIPS interrupts
711     * 8 + x, where x = 0..15 Jazz interrupts
712     * 8 + x, where x = 16..31 ISA interrupt (irq nr + 16)
713     */
714     void jazz_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
715     {
716     uint32_t irq;
717     int isa = 0;
718    
719     irq_nr -= 8;
720    
721     /* debug("jazz_interrupt() irq_nr = %i, assrt = %i\n",
722     irq_nr, assrt); */
723    
724     if (irq_nr >= 16) {
725     isa = 1;
726     irq_nr -= 16;
727     }
728    
729     irq = 1 << irq_nr;
730    
731     if (isa) {
732     if (assrt)
733     m->jazz_data->isa_int_asserted |= irq;
734     else
735     m->jazz_data->isa_int_asserted &= ~irq;
736     } else {
737     if (assrt)
738     m->jazz_data->int_asserted |= irq;
739     else
740     m->jazz_data->int_asserted &= ~irq;
741     }
742    
743     /* debug(" %08x %08x\n", m->jazz_data->int_asserted,
744     m->jazz_data->int_enable_mask); */
745     /* debug(" %08x %08x\n", m->jazz_data->isa_int_asserted,
746     m->jazz_data->isa_int_enable_mask); */
747    
748     if (m->jazz_data->int_asserted /* & m->jazz_data->int_enable_mask */
749     & ~0x8000 )
750     cpu_interrupt(cpu, 3);
751     else
752     cpu_interrupt_ack(cpu, 3);
753    
754     if (m->jazz_data->isa_int_asserted & m->jazz_data->isa_int_enable_mask)
755     cpu_interrupt(cpu, 4);
756     else
757     cpu_interrupt_ack(cpu, 4);
758    
759     /* TODO: this "15" (0x8000) is the timer... fix this? */
760     if (m->jazz_data->int_asserted & 0x8000)
761     cpu_interrupt(cpu, 6);
762     else
763     cpu_interrupt_ack(cpu, 6);
764     }
765    
766    
767     /*
768     * VR41xx interrupt routine:
769     *
770     * irq_nr = 8 + x
771     * x = 0..15 for level1
772     * x = 16..31 for level2
773     * x = 32+y for GIU interrupt y
774     */
775     void vr41xx_interrupt(struct machine *m, struct cpu *cpu,
776     int irq_nr, int assrt)
777     {
778     int giu_irq = 0;
779    
780     irq_nr -= 8;
781     if (irq_nr >= 32) {
782     giu_irq = irq_nr - 32;
783    
784     if (assrt)
785     m->vr41xx_data->giuint |= (1 << giu_irq);
786     else
787     m->vr41xx_data->giuint &= ~(1 << giu_irq);
788     }
789    
790     /* TODO: This is wrong. What about GIU bit 8? */
791    
792     if (irq_nr != 8) {
793     /* If any GIU bit is asserted, then assert the main
794     GIU interrupt: */
795     if (m->vr41xx_data->giuint & m->vr41xx_data->giumask)
796     vr41xx_interrupt(m, cpu, 8 + 8, 1);
797     else
798     vr41xx_interrupt(m, cpu, 8 + 8, 0);
799     }
800    
801     /* debug("vr41xx_interrupt(): irq_nr=%i assrt=%i\n",
802     irq_nr, assrt); */
803    
804     if (irq_nr < 16) {
805     if (assrt)
806     m->vr41xx_data->sysint1 |= (1 << irq_nr);
807     else
808     m->vr41xx_data->sysint1 &= ~(1 << irq_nr);
809     } else if (irq_nr < 32) {
810     irq_nr -= 16;
811     if (assrt)
812     m->vr41xx_data->sysint2 |= (1 << irq_nr);
813     else
814     m->vr41xx_data->sysint2 &= ~(1 << irq_nr);
815     }
816    
817     /* TODO: Which hardware interrupt pin? */
818    
819     /* debug(" sysint1=%04x mask=%04x, sysint2=%04x mask=%04x\n",
820     m->vr41xx_data->sysint1, m->vr41xx_data->msysint1,
821     m->vr41xx_data->sysint2, m->vr41xx_data->msysint2); */
822    
823     if ((m->vr41xx_data->sysint1 & m->vr41xx_data->msysint1) |
824     (m->vr41xx_data->sysint2 & m->vr41xx_data->msysint2))
825     cpu_interrupt(cpu, 2);
826     else
827     cpu_interrupt_ack(cpu, 2);
828     }
829    
830    
831     /*
832     * Playstation 2 interrupt routine:
833     */
834     void ps2_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
835     {
836     irq_nr -= 8;
837     debug("ps2_interrupt(): irq_nr=0x%x assrt=%i\n", irq_nr, assrt);
838    
839     if (assrt) {
840     /* OR into the INTR: */
841     if (irq_nr < 0x10000)
842     m->ps2_data->intr |= irq_nr;
843     else
844     m->ps2_data->dmac_reg[0x601] |= (irq_nr >> 16);
845    
846     /* Assert interrupt: TODO: masks */
847     if (irq_nr >= 0x10000)
848     cpu_interrupt(cpu, 3);
849     else
850     cpu_interrupt(cpu, 2);
851     } else {
852     /* AND out of the INTR: */
853     if (irq_nr < 0x10000)
854     m->ps2_data->intr &= ~irq_nr;
855     else
856     m->ps2_data->dmac_reg[0x601] &= ~(irq_nr >> 16);
857    
858     /* TODO: masks */
859     if ((m->ps2_data->intr & 0xffff) == 0)
860     cpu_interrupt_ack(cpu, 2);
861     if ((m->ps2_data->dmac_reg[0x601] & 0xffff) == 0)
862     cpu_interrupt_ack(cpu, 3);
863     }
864     }
865    
866    
867     /*
868     * SGI "IP22" interrupt routine:
869     */
870     void sgi_ip22_interrupt(struct machine *m, struct cpu *cpu,
871     int irq_nr, int assrt)
872     {
873     /*
874     * SGI-IP22 specific interrupt stuff:
875     *
876     * irq_nr should be 8 + x, where x = 0..31 for local0,
877     * and 32..63 for local1 interrupts.
878     * Add 64*y for "mappable" interrupts, where 1<<y is
879     * the mappable interrupt bitmask. TODO: this misses 64*0 !
880     */
881    
882     uint32_t newmask;
883     uint32_t stat, mask;
884    
885     irq_nr -= 8;
886     newmask = 1 << (irq_nr & 31);
887    
888     if (irq_nr >= 64) {
889     int ms = irq_nr / 64;
890     uint32_t new = 1 << ms;
891     if (assrt)
892     m->sgi_ip22_data->reg[4] |= new;
893     else
894     m->sgi_ip22_data->reg[4] &= ~new;
895     /* TODO: is this enough? */
896     irq_nr &= 63;
897     }
898    
899     if (irq_nr < 32) {
900     if (assrt)
901     m->sgi_ip22_data->reg[0] |= newmask;
902     else
903     m->sgi_ip22_data->reg[0] &= ~newmask;
904     } else {
905     if (assrt)
906     m->sgi_ip22_data->reg[2] |= newmask;
907     else
908     m->sgi_ip22_data->reg[2] &= ~newmask;
909     }
910    
911     /* Read stat and mask for local0: */
912     stat = m->sgi_ip22_data->reg[0];
913     mask = m->sgi_ip22_data->reg[1];
914     if ((stat & mask) == 0)
915     cpu_interrupt_ack(cpu, 2);
916     else
917     cpu_interrupt(cpu, 2);
918    
919     /* Read stat and mask for local1: */
920     stat = m->sgi_ip22_data->reg[2];
921     mask = m->sgi_ip22_data->reg[3];
922     if ((stat & mask) == 0)
923     cpu_interrupt_ack(cpu, 3);
924     else
925     cpu_interrupt(cpu, 3);
926     }
927    
928    
929     /*
930     * SGI "IP30" interrupt routine:
931     *
932     * irq_nr = 8 + 1 + nr, where nr is:
933     * 0..49 HEART irqs hardware irq 2,3,4
934     * 50 HEART timer hardware irq 5
935     * 51..63 HEART errors hardware irq 6
936     *
937     * according to Linux/IP30.
938     */
939     void sgi_ip30_interrupt(struct machine *m, struct cpu *cpu,
940     int irq_nr, int assrt)
941     {
942     uint64_t newmask;
943     uint64_t stat, mask;
944    
945     irq_nr -= 8;
946     if (irq_nr == 0)
947     goto just_assert_and_such;
948     irq_nr --;
949    
950     newmask = (int64_t)1 << irq_nr;
951    
952     if (assrt)
953     m->sgi_ip30_data->isr |= newmask;
954     else
955     m->sgi_ip30_data->isr &= ~newmask;
956    
957     just_assert_and_such:
958    
959     cpu_interrupt_ack(cpu, 2);
960     cpu_interrupt_ack(cpu, 3);
961     cpu_interrupt_ack(cpu, 4);
962     cpu_interrupt_ack(cpu, 5);
963     cpu_interrupt_ack(cpu, 6);
964    
965     stat = m->sgi_ip30_data->isr;
966     mask = m->sgi_ip30_data->imask0;
967    
968     if ((stat & mask) & 0x000000000000ffffULL)
969     cpu_interrupt(cpu, 2);
970     if ((stat & mask) & 0x00000000ffff0000ULL)
971     cpu_interrupt(cpu, 3);
972     if ((stat & mask) & 0x0003ffff00000000ULL)
973     cpu_interrupt(cpu, 4);
974     if ((stat & mask) & 0x0004000000000000ULL)
975     cpu_interrupt(cpu, 5);
976     if ((stat & mask) & 0xfff8000000000000ULL)
977     cpu_interrupt(cpu, 6);
978     }
979    
980    
981     /*
982     * SGI "IP32" interrupt routine:
983     */
984     void sgi_ip32_interrupt(struct machine *m, struct cpu *cpu,
985     int irq_nr, int assrt)
986     {
987     /*
988     * The 64-bit word at crime offset 0x10 is CRIME_INTSTAT,
989     * which contains the current interrupt bits. CRIME_INTMASK
990     * contains a mask of which bits are actually in use.
991     *
992     * crime hardcoded at 0x14000000, for SGI-IP32.
993     * If any of these bits are asserted, then physical MIPS
994     * interrupt 2 should be asserted.
995     *
996     * TODO: how should all this be done nicely?
997     *
998     * TODO: mace interrupt mask
999     */
1000    
1001     uint64_t crime_addr = CRIME_INTSTAT;
1002     uint64_t mace_addr = 0x14;
1003     uint64_t crime_interrupts, crime_interrupts_mask, mace_interrupts;
1004     unsigned int i;
1005     unsigned char x[8];
1006    
1007     /*
1008     * This mapping of both MACE and CRIME interrupts into the same
1009     * 'int' is really ugly.
1010     *
1011     * If MACE_PERIPH_MISC or MACE_PERIPH_SERIAL is set, then mask
1012     * that bit out and treat the rest of the word as the mace interrupt
1013     * bitmask.
1014     *
1015     * TODO: fix.
1016     */
1017     if (irq_nr & MACE_PERIPH_SERIAL) {
1018     /* Read current MACE interrupt bits: */
1019     memcpy(x, m->mace_data->reg + mace_addr, sizeof(uint32_t));
1020     mace_interrupts = 0;
1021     for (i=0; i<sizeof(uint32_t); i++) {
1022     /* SGI is big-endian... */
1023     mace_interrupts <<= 8;
1024     mace_interrupts |= x[i];
1025     }
1026    
1027     if (assrt)
1028     mace_interrupts |= (irq_nr & ~MACE_PERIPH_SERIAL);
1029     else
1030     mace_interrupts &= ~(irq_nr & ~MACE_PERIPH_SERIAL);
1031    
1032     /* Write back MACE interrupt bits: */
1033     for (i=0; i<4; i++)
1034     x[3-i] = mace_interrupts >> (i*8);
1035     memcpy(m->mace_data->reg + mace_addr, x, sizeof(uint32_t));
1036    
1037     irq_nr = MACE_PERIPH_SERIAL;
1038     if (mace_interrupts == 0)
1039     assrt = 0;
1040     else
1041     assrt = 1;
1042     }
1043    
1044     /* Hopefully _MISC and _SERIAL will not be both on at the same time. */
1045     if (irq_nr & MACE_PERIPH_MISC) {
1046     /* Read current MACE interrupt bits: */
1047     memcpy(x, m->mace_data->reg + mace_addr, sizeof(uint32_t));
1048     mace_interrupts = 0;
1049     for (i=0; i<sizeof(uint32_t); i++) {
1050     /* SGI is big-endian... */
1051     mace_interrupts <<= 8;
1052     mace_interrupts |= x[i];
1053     }
1054    
1055     if (assrt)
1056     mace_interrupts |= (irq_nr & ~MACE_PERIPH_MISC);
1057     else
1058     mace_interrupts &= ~(irq_nr & ~MACE_PERIPH_MISC);
1059    
1060     /* Write back MACE interrupt bits: */
1061     for (i=0; i<4; i++)
1062     x[3-i] = mace_interrupts >> (i*8);
1063     memcpy(m->mace_data->reg + mace_addr, x, sizeof(uint32_t));
1064    
1065     irq_nr = MACE_PERIPH_MISC;
1066     if (mace_interrupts == 0)
1067     assrt = 0;
1068     else
1069     assrt = 1;
1070     }
1071    
1072     /* Read CRIME_INTSTAT: */
1073     memcpy(x, m->crime_data->reg + crime_addr, sizeof(uint64_t));
1074     crime_interrupts = 0;
1075     for (i=0; i<8; i++) {
1076     /* SGI is big-endian... */
1077     crime_interrupts <<= 8;
1078     crime_interrupts |= x[i];
1079     }
1080    
1081     if (assrt)
1082     crime_interrupts |= irq_nr;
1083     else
1084     crime_interrupts &= ~irq_nr;
1085    
1086     /* Write back CRIME_INTSTAT: */
1087     for (i=0; i<8; i++)
1088     x[7-i] = crime_interrupts >> (i*8);
1089     memcpy(m->crime_data->reg + crime_addr, x, sizeof(uint64_t));
1090    
1091     /* Read CRIME_INTMASK: */
1092     memcpy(x, m->crime_data->reg + CRIME_INTMASK, sizeof(uint64_t));
1093     crime_interrupts_mask = 0;
1094     for (i=0; i<8; i++) {
1095     crime_interrupts_mask <<= 8;
1096     crime_interrupts_mask |= x[i];
1097     }
1098    
1099     if ((crime_interrupts & crime_interrupts_mask) == 0)
1100     cpu_interrupt_ack(cpu, 2);
1101     else
1102     cpu_interrupt(cpu, 2);
1103    
1104     /* printf("sgi_crime_machine_irq(%i,%i): new interrupts = 0x%08x\n", assrt, irq_nr, crime_interrupts); */
1105     }
1106    
1107    
1108     /*
1109     * Au1x00 interrupt routine:
1110     *
1111     * TODO: This is just bogus so far. For more info, read this:
1112     * http://www.meshcube.org/cgi-bin/viewcvs.cgi/kernel/linux/arch/mips/au1000/common/
1113     *
1114     * CPU int 2 = IC 0, request 0
1115     * CPU int 3 = IC 0, request 1
1116     * CPU int 4 = IC 1, request 0
1117     * CPU int 5 = IC 1, request 1
1118     *
1119     * Interrupts 0..31 are on interrupt controller 0, interrupts 32..63 are
1120     * on controller 1.
1121     *
1122     * Special case: if irq_nr == 64+8, then this just updates the CPU
1123     * interrupt assertions.
1124     */
1125     void au1x00_interrupt(struct machine *m, struct cpu *cpu,
1126     int irq_nr, int assrt)
1127     {
1128     uint32_t ms;
1129    
1130     irq_nr -= 8;
1131     debug("au1x00_interrupt(): irq_nr=%i assrt=%i\n", irq_nr, assrt);
1132    
1133     if (irq_nr < 64) {
1134     ms = 1 << (irq_nr & 31);
1135    
1136     if (assrt)
1137     m->au1x00_ic_data->request0_int |= ms;
1138     else
1139     m->au1x00_ic_data->request0_int &= ~ms;
1140    
1141     /* TODO: Controller 1 */
1142     }
1143    
1144     if ((m->au1x00_ic_data->request0_int &
1145     m->au1x00_ic_data->mask) != 0)
1146     cpu_interrupt(cpu, 2);
1147     else
1148     cpu_interrupt_ack(cpu, 2);
1149    
1150     /* TODO: What _is_ request1? */
1151    
1152     /* TODO: Controller 1 */
1153     }
1154    
1155    
1156     /****************************************************************************
1157     * *
1158     * Machine dependant Initialization routines *
1159     * *
1160     ****************************************************************************/
1161    
1162    
1163     /*
1164     * machine_setup():
1165     *
1166     * This (rather large) function initializes memory, registers, and/or devices
1167     * required by specific machine emulations.
1168     */
1169     void machine_setup(struct machine *machine)
1170     {
1171     uint64_t addr, addr2;
1172     int i, j;
1173     struct memory *mem;
1174     char tmpstr[1000];
1175    
1176     /* DECstation: */
1177     char *framebuffer_console_name, *serial_console_name;
1178     int color_fb_flag;
1179     int boot_scsi_boardnumber = 3, boot_net_boardnumber = 3;
1180     char *turbochannel_default_gfx_card = "PMAG-BA";
1181     /* PMAG-AA, -BA, -CA/DA/EA/FA, -JA, -RO, PMAGB-BA */
1182    
1183     /* HPCmips: */
1184     struct xx {
1185     struct btinfo_magic a;
1186     struct btinfo_bootpath b;
1187     struct btinfo_symtab c;
1188     } xx;
1189     struct hpc_bootinfo hpc_bootinfo;
1190     uint64_t hpcmips_fb_addr = 0;
1191     int hpcmips_fb_bits = 0, hpcmips_fb_encoding = 0;
1192     int hpcmips_fb_xsize = 0;
1193     int hpcmips_fb_ysize = 0;
1194     int hpcmips_fb_xsize_mem = 0;
1195     int hpcmips_fb_ysize_mem = 0;
1196    
1197     /* ARCBIOS stuff: */
1198     struct arcbios_spb arcbios_spb;
1199     struct arcbios_spb_64 arcbios_spb_64;
1200     struct arcbios_sysid arcbios_sysid;
1201     struct arcbios_dsp_stat arcbios_dsp_stat;
1202     uint64_t mem_base, mem_count;
1203     uint64_t system = 0;
1204     uint64_t sgi_ram_offset = 0;
1205     uint64_t arc_reserved;
1206     int arc_wordlen = sizeof(uint32_t);
1207     char *short_machine_name = NULL;
1208     char *eaddr_string = "eaddr=10:20:30:40:50:60"; /* nonsense */
1209     unsigned char macaddr[6];
1210    
1211     /* Generic bootstring stuff: */
1212     int bootdev_id = diskimage_bootdev(machine);
1213     char *bootstr = NULL;
1214     char *bootarg = NULL;
1215     char *init_bootpath;
1216    
1217     /* PCI stuff: */
1218     struct pci_data *pci_data;
1219    
1220     /* Framebuffer stuff: */
1221     struct vfb_data *fb;
1222    
1223     /* Abreviation: :-) */
1224     struct cpu *cpu = machine->cpus[machine->bootstrap_cpu];
1225    
1226    
1227     mem = cpu->mem;
1228     machine->machine_name = NULL;
1229    
1230     /* TODO: Move this somewhere else? */
1231     if (machine->boot_string_argument == NULL) {
1232     switch (machine->machine_type) {
1233     case MACHINE_ARC:
1234     machine->boot_string_argument = "-aN";
1235     break;
1236     case MACHINE_DEC:
1237     machine->boot_string_argument = "-a";
1238     break;
1239     default:
1240     /* Important, because boot_string_argument should
1241     not be set to NULL: */
1242     machine->boot_string_argument = "";
1243     }
1244     }
1245    
1246     switch (machine->machine_type) {
1247    
1248     case MACHINE_NONE:
1249     printf("\nNo emulation type specified.\n");
1250     exit(1);
1251    
1252     case MACHINE_BAREMIPS:
1253     /*
1254     * A "bare" MIPS test machine.
1255     *
1256     * NOTE: NO devices at all.
1257     */
1258     cpu->byte_order = EMUL_BIG_ENDIAN;
1259     machine->machine_name = "\"Bare\" MIPS machine";
1260     break;
1261    
1262     case MACHINE_TESTMIPS:
1263     /*
1264     * A MIPS test machine (which happens to work with my
1265     * thesis work).
1266     */
1267     cpu->byte_order = EMUL_BIG_ENDIAN;
1268     machine->machine_name = "MIPS test machine";
1269    
1270     machine->main_console_handle = dev_cons_init(
1271     machine, mem, DEV_CONS_ADDRESS, "console", 2);
1272    
1273     snprintf(tmpstr, sizeof(tmpstr) - 1, "mp addr=0x%llx",
1274     (long long)DEV_MP_ADDRESS);
1275     device_add(machine, tmpstr);
1276    
1277     fb = dev_fb_init(machine, mem, 0x12000000, VFB_GENERIC,
1278     640,480, 640,480, 24, "generic", 1);
1279     break;
1280    
1281     case MACHINE_DEC:
1282     cpu->byte_order = EMUL_LITTLE_ENDIAN;
1283    
1284     /* An R2020 or R3220 memory thingy: */
1285     cpu->cd.mips.coproc[3] = mips_coproc_new(cpu, 3);
1286    
1287     /* There aren't really any good standard values... */
1288     framebuffer_console_name = "osconsole=0,3";
1289     serial_console_name = "osconsole=1";
1290    
1291     switch (machine->machine_subtype) {
1292     case MACHINE_DEC_PMAX_3100: /* type 1, KN01 */
1293     /* Supposed to have 12MHz or 16.67MHz R2000 CPU, R2010 FPC, R2020 Memory coprocessor */
1294     machine->machine_name = "DEC PMAX 3100 (KN01)";
1295    
1296     /* 12 MHz for 2100, 16.67 MHz for 3100 */
1297     if (machine->emulated_hz == 0)
1298     machine->emulated_hz = 16670000;
1299    
1300     if (machine->physical_ram_in_mb > 24)
1301     fprintf(stderr, "WARNING! Real DECstation 3100 machines cannot have more than 24MB RAM. Continuing anyway.\n");
1302    
1303     if ((machine->physical_ram_in_mb % 4) != 0)
1304     fprintf(stderr, "WARNING! Real DECstation 3100 machines have an integer multiple of 4 MBs of RAM. Continuing anyway.\n");
1305    
1306     color_fb_flag = 1; /* 1 for color, 0 for mono. TODO: command line option? */
1307    
1308     /*
1309     * According to NetBSD/pmax:
1310     *
1311     * pm0 at ibus0 addr 0xfc00000: 1024x864x1 (or x8 for color)
1312     * dc0 at ibus0 addr 0x1c000000
1313     * le0 at ibus0 addr 0x18000000: address 00:00:00:00:00:00
1314     * sii0 at ibus0 addr 0x1a000000
1315     * mcclock0 at ibus0 addr 0x1d000000: mc146818 or compatible
1316     * 0x1e000000 = system status and control register
1317     */
1318     fb = dev_fb_init(machine, mem, KN01_PHYS_FBUF_START,
1319     color_fb_flag? VFB_DEC_VFB02 : VFB_DEC_VFB01,
1320     0,0,0,0,0, color_fb_flag? "VFB02":"VFB01", 1);
1321     dev_colorplanemask_init(mem, KN01_PHYS_COLMASK_START, &fb->color_plane_mask);
1322     dev_vdac_init(mem, KN01_SYS_VDAC, fb->rgb_palette, color_fb_flag);
1323     dev_le_init(machine, mem, KN01_SYS_LANCE, KN01_SYS_LANCE_B_START, KN01_SYS_LANCE_B_END, KN01_INT_LANCE, 4*1048576);
1324     dev_sii_init(machine, mem, KN01_SYS_SII, KN01_SYS_SII_B_START, KN01_SYS_SII_B_END, KN01_INT_SII);
1325     dev_dc7085_init(machine, mem, KN01_SYS_DZ, KN01_INT_DZ, machine->use_x11);
1326     dev_mc146818_init(machine, mem, KN01_SYS_CLOCK, KN01_INT_CLOCK, MC146818_DEC, 1);
1327     dev_kn01_csr_init(mem, KN01_SYS_CSR, color_fb_flag);
1328    
1329     framebuffer_console_name = "osconsole=0,3"; /* fb,keyb */
1330     serial_console_name = "osconsole=3"; /* 3 */
1331     break;
1332    
1333     case MACHINE_DEC_3MAX_5000: /* type 2, KN02 */
1334     /* Supposed to have 25MHz R3000 CPU, R3010 FPC, */
1335     /* and a R3220 Memory coprocessor */
1336     machine->machine_name = "DECstation 5000/200 (3MAX, KN02)";
1337    
1338     if (machine->emulated_hz == 0)
1339     machine->emulated_hz = 25000000;
1340    
1341     if (machine->physical_ram_in_mb < 8)
1342     fprintf(stderr, "WARNING! Real KN02 machines do not have less than 8MB RAM. Continuing anyway.\n");
1343     if (machine->physical_ram_in_mb > 480)
1344     fprintf(stderr, "WARNING! Real KN02 machines cannot have more than 480MB RAM. Continuing anyway.\n");
1345    
1346     /* An R3220 memory thingy: */
1347     cpu->cd.mips.coproc[3] = mips_coproc_new(cpu, 3);
1348    
1349     /*
1350     * According to NetBSD/pmax:
1351     * asc0 at tc0 slot 5 offset 0x0
1352     * le0 at tc0 slot 6 offset 0x0
1353     * ibus0 at tc0 slot 7 offset 0x0
1354     * dc0 at ibus0 addr 0x1fe00000
1355     * mcclock0 at ibus0 addr 0x1fe80000: mc146818
1356     *
1357     * kn02 shared irq numbers (IP) are offset by +8
1358     * in the emulator
1359     */
1360    
1361     /* KN02 interrupts: */
1362     machine->md_interrupt = kn02_interrupt;
1363    
1364     /*
1365     * TURBOchannel slots 0, 1, and 2 are free for
1366     * option cards. Let's put in zero or more graphics
1367     * boards:
1368     *
1369     * TODO: It's also possible to have larger graphics
1370     * cards that occupy several slots. How to solve
1371     * this nicely?
1372     */
1373     dev_turbochannel_init(machine, mem, 0,
1374     KN02_PHYS_TC_0_START, KN02_PHYS_TC_0_END,
1375     machine->n_gfx_cards >= 1?
1376     turbochannel_default_gfx_card : "",
1377     KN02_IP_SLOT0 +8);
1378    
1379     dev_turbochannel_init(machine, mem, 1,
1380     KN02_PHYS_TC_1_START, KN02_PHYS_TC_1_END,
1381     machine->n_gfx_cards >= 2?
1382     turbochannel_default_gfx_card : "",
1383     KN02_IP_SLOT1 +8);
1384    
1385     dev_turbochannel_init(machine, mem, 2,
1386     KN02_PHYS_TC_2_START, KN02_PHYS_TC_2_END,
1387     machine->n_gfx_cards >= 3?
1388     turbochannel_default_gfx_card : "",
1389     KN02_IP_SLOT2 +8);
1390    
1391     /* TURBOchannel slots 3 and 4 are reserved. */
1392    
1393     /* TURBOchannel slot 5 is PMAZ-AA ("asc" SCSI). */
1394     dev_turbochannel_init(machine, mem, 5,
1395     KN02_PHYS_TC_5_START, KN02_PHYS_TC_5_END,
1396     "PMAZ-AA", KN02_IP_SCSI +8);
1397    
1398     /* TURBOchannel slot 6 is PMAD-AA ("le" ethernet). */
1399     dev_turbochannel_init(machine, mem, 6,
1400     KN02_PHYS_TC_6_START, KN02_PHYS_TC_6_END,
1401     "PMAD-AA", KN02_IP_LANCE +8);
1402    
1403     /* TURBOchannel slot 7 is system stuff. */
1404     machine->main_console_handle =
1405     dev_dc7085_init(machine, mem,
1406     KN02_SYS_DZ, KN02_IP_DZ +8, machine->use_x11);
1407     dev_mc146818_init(machine, mem,
1408     KN02_SYS_CLOCK, KN02_INT_CLOCK, MC146818_DEC, 1);
1409    
1410     machine->kn02_csr =
1411     dev_kn02_init(cpu, mem, KN02_SYS_CSR);
1412    
1413     framebuffer_console_name = "osconsole=0,7";
1414     /* fb,keyb */
1415     serial_console_name = "osconsole=2";
1416     boot_scsi_boardnumber = 5;
1417     boot_net_boardnumber = 6; /* TODO: 3? */
1418     break;
1419    
1420     case MACHINE_DEC_3MIN_5000: /* type 3, KN02BA */
1421     machine->machine_name = "DECstation 5000/112 or 145 (3MIN, KN02BA)";
1422     if (machine->emulated_hz == 0)
1423     machine->emulated_hz = 33000000;
1424     if (machine->physical_ram_in_mb > 128)
1425     fprintf(stderr, "WARNING! Real 3MIN machines cannot have more than 128MB RAM. Continuing anyway.\n");
1426    
1427     /* KMIN interrupts: */
1428     machine->md_interrupt = kmin_interrupt;
1429    
1430     /*
1431     * tc0 at mainbus0: 12.5 MHz clock (0x10000000, slotsize = 64MB)
1432     * tc slot 1: 0x14000000
1433     * tc slot 2: 0x18000000
1434     * ioasic0 at tc0 slot 3 offset 0x0 (0x1c000000) slot 0
1435     * asic regs (0x1c040000) slot 1
1436     * station's ether address (0x1c080000) slot 2
1437     * le0 at ioasic0 offset 0xc0000: address 00:00:00:00:00:00 (0x1c0c0000) slot 3
1438     * scc0 at ioasic0 offset 0x100000 (0x1c100000) slot 4
1439     * scc1 at ioasic0 offset 0x180000: console (0x1c180000) slot 6
1440     * mcclock0 at ioasic0 offset 0x200000: mc146818 or compatible (0x1c200000) slot 8
1441     * asc0 at ioasic0 offset 0x300000: NCR53C94, 25MHz, SCSI ID 7 (0x1c300000) slot 12
1442     * dma for asc0 (0x1c380000) slot 14
1443     */
1444     machine->dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1c000000, 0);
1445     dev_le_init(machine, mem, 0x1c0c0000, 0, 0, KMIN_INTR_LANCE +8, 4*65536);
1446     dev_scc_init(machine, mem, 0x1c100000, KMIN_INTR_SCC_0 +8, machine->use_x11, 0, 1);
1447     dev_scc_init(machine, mem, 0x1c180000, KMIN_INTR_SCC_1 +8, machine->use_x11, 1, 1);
1448     dev_mc146818_init(machine, mem, 0x1c200000, KMIN_INTR_CLOCK +8, MC146818_DEC, 1);
1449     dev_asc_init(machine, mem, 0x1c300000, KMIN_INTR_SCSI +8,
1450     NULL, DEV_ASC_DEC, NULL, NULL);
1451    
1452     /*
1453     * TURBOchannel slots 0, 1, and 2 are free for
1454     * option cards. These are by default filled with
1455     * zero or more graphics boards.
1456     *
1457     * TODO: irqs
1458     */
1459     dev_turbochannel_init(machine, mem, 0,
1460     0x10000000, 0x103fffff,
1461     machine->n_gfx_cards >= 1?
1462     turbochannel_default_gfx_card : "",
1463     KMIN_INT_TC0);
1464    
1465     dev_turbochannel_init(machine, mem, 1,
1466     0x14000000, 0x143fffff,
1467     machine->n_gfx_cards >= 2?
1468     turbochannel_default_gfx_card : "",
1469     KMIN_INT_TC1);
1470    
1471     dev_turbochannel_init(machine, mem, 2,
1472     0x18000000, 0x183fffff,
1473     machine->n_gfx_cards >= 3?
1474     turbochannel_default_gfx_card : "",
1475     KMIN_INT_TC2);
1476    
1477     /* (kmin shared irq numbers (IP) are offset by +8 in the emulator) */
1478     /* kmin_csr = dev_kmin_init(cpu, mem, KMIN_REG_INTR); */
1479    
1480     framebuffer_console_name = "osconsole=0,3"; /* fb, keyb (?) */
1481     serial_console_name = "osconsole=3"; /* ? */
1482     break;
1483    
1484     case MACHINE_DEC_3MAXPLUS_5000: /* type 4, KN03 */
1485     machine->machine_name = "DECsystem 5900 or 5000 (3MAX+) (KN03)";
1486    
1487     /* 5000/240 (KN03-GA, R3000): 40 MHz */
1488     /* 5000/260 (KN05-NB, R4000): 60 MHz */
1489     /* TODO: are both these type 4? */
1490     if (machine->emulated_hz == 0)
1491     machine->emulated_hz = 40000000;
1492     if (machine->physical_ram_in_mb > 480)
1493     fprintf(stderr, "WARNING! Real KN03 machines cannot have more than 480MB RAM. Continuing anyway.\n");
1494    
1495     /* KN03 interrupts: */
1496     machine->md_interrupt = kn03_interrupt;
1497    
1498     /*
1499     * tc0 at mainbus0: 25 MHz clock (slot 0) (0x1e000000)
1500     * tc0 slot 1 (0x1e800000)
1501     * tc0 slot 2 (0x1f000000)
1502     * ioasic0 at tc0 slot 3 offset 0x0 (0x1f800000)
1503     * something that has to do with interrupts? (?) (0x1f840000 ?)
1504     * le0 at ioasic0 offset 0xc0000 (0x1f8c0000)
1505     * scc0 at ioasic0 offset 0x100000 (0x1f900000)
1506     * scc1 at ioasic0 offset 0x180000: console (0x1f980000)
1507     * mcclock0 at ioasic0 offset 0x200000: mc146818 or compatible (0x1fa00000)
1508     * asc0 at ioasic0 offset 0x300000: NCR53C94, 25MHz, SCSI ID 7 (0x1fb00000)
1509     */
1510     machine->dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1f800000, 0);
1511    
1512     dev_le_init(machine, mem, KN03_SYS_LANCE, 0, 0, KN03_INTR_LANCE +8, 4*65536);
1513    
1514     machine->dec_ioasic_data->dma_func[3] = dev_scc_dma_func;
1515     machine->dec_ioasic_data->dma_func_extra[2] = dev_scc_init(machine, mem, KN03_SYS_SCC_0, KN03_INTR_SCC_0 +8, machine->use_x11, 0, 1);
1516     machine->dec_ioasic_data->dma_func[2] = dev_scc_dma_func;
1517     machine->dec_ioasic_data->dma_func_extra[3] = dev_scc_init(machine, mem, KN03_SYS_SCC_1, KN03_INTR_SCC_1 +8, machine->use_x11, 1, 1);
1518    
1519     dev_mc146818_init(machine, mem, KN03_SYS_CLOCK, KN03_INT_RTC, MC146818_DEC, 1);
1520     dev_asc_init(machine, mem, KN03_SYS_SCSI,
1521     KN03_INTR_SCSI +8, NULL, DEV_ASC_DEC, NULL, NULL);
1522    
1523     /*
1524     * TURBOchannel slots 0, 1, and 2 are free for
1525     * option cards. These are by default filled with
1526     * zero or more graphics boards.
1527     *
1528     * TODO: irqs
1529     */
1530     dev_turbochannel_init(machine, mem, 0,
1531     KN03_PHYS_TC_0_START, KN03_PHYS_TC_0_END,
1532     machine->n_gfx_cards >= 1?
1533     turbochannel_default_gfx_card : "",
1534     KN03_INTR_TC_0 +8);
1535    
1536     dev_turbochannel_init(machine, mem, 1,
1537     KN03_PHYS_TC_1_START, KN03_PHYS_TC_1_END,
1538     machine->n_gfx_cards >= 2?
1539     turbochannel_default_gfx_card : "",
1540     KN03_INTR_TC_1 +8);
1541    
1542     dev_turbochannel_init(machine, mem, 2,
1543     KN03_PHYS_TC_2_START, KN03_PHYS_TC_2_END,
1544     machine->n_gfx_cards >= 3?
1545     turbochannel_default_gfx_card : "",
1546     KN03_INTR_TC_2 +8);
1547    
1548     /* TODO: interrupts */
1549     /* shared (turbochannel) interrupts are +8 */
1550    
1551     framebuffer_console_name = "osconsole=0,3"; /* fb, keyb (?) */
1552     serial_console_name = "osconsole=3"; /* ? */
1553     break;
1554    
1555     case MACHINE_DEC_5800: /* type 5, KN5800 */
1556     machine->machine_name = "DECsystem 5800";
1557    
1558     /* TODO: this is incorrect, banks multiply by 8 etc */
1559     if (machine->physical_ram_in_mb < 48)
1560     fprintf(stderr, "WARNING! 5800 will probably not run with less than 48MB RAM. Continuing anyway.\n");
1561    
1562     /*
1563     * According to http://www2.no.netbsd.org/Ports/pmax/models.html,
1564     * the 5800-series is based on VAX 6000/300.
1565     */
1566    
1567     /*
1568     * Ultrix might support SMP on this machine type.
1569     *
1570     * Something at 0x10000000.
1571     * ssc serial console at 0x10140000, interrupt 2 (shared with XMI?).
1572     * xmi 0 at address 0x11800000 (node x at offset x*0x80000)
1573     * Clock uses interrupt 3 (shared with XMI?).
1574     */
1575    
1576     machine->dec5800_csr = dev_dec5800_init(machine, mem, 0x10000000);
1577     dev_decbi_init(mem, 0x10000000);
1578     dev_ssc_init(machine, mem, 0x10140000, 2, machine->use_x11, &machine->dec5800_csr->csr);
1579     dev_decxmi_init(mem, 0x11800000);
1580     dev_deccca_init(mem, DEC_DECCCA_BASEADDR);
1581    
1582     break;
1583    
1584     case MACHINE_DEC_5400: /* type 6, KN210 */
1585     machine->machine_name = "DECsystem 5400 (KN210)";
1586     /*
1587     * Misc. info from the KN210 manual:
1588     *
1589     * Interrupt lines:
1590     * irq5 fpu
1591     * irq4 halt
1592     * irq3 pwrfl -> mer1 -> mer0 -> wear
1593     * irq2 100 Hz -> birq7
1594     * irq1 dssi -> ni -> birq6
1595     * irq0 birq5 -> console -> timers -> birq4
1596     *
1597     * Interrupt status register at 0x10048000.
1598     * Main memory error status register at 0x1008140.
1599     * Interval Timer Register (ITR) at 0x10084010.
1600     * Q22 stuff at 0x10088000 - 0x1008ffff.
1601     * TODR at 0x1014006c.
1602     * TCR0 (timer control register 0) 0x10140100.
1603     * TIR0 (timer interval register 0) 0x10140104.
1604     * TCR1 (timer control register 1) 0x10140110.
1605     * TIR1 (timer interval register 1) 0x10140114.
1606     * VRR0 (Vector Read Register 0) at 0x16000050.
1607     * VRR1 (Vector Read Register 1) at 0x16000054.
1608     * VRR2 (Vector Read Register 2) at 0x16000058.
1609     * VRR3 (Vector Read Register 3) at 0x1600005c.
1610     */
1611     /* ln (ethernet) at 0x10084x00 ? and 0x10120000 ? */
1612     /* error registers (?) at 0x17000000 and 0x10080000 */
1613     device_add(machine, "kn210 addr=0x10080000");
1614     dev_ssc_init(machine, mem, 0x10140000, 0, machine->use_x11, NULL); /* TODO: not irq 0 */
1615     break;
1616    
1617     case MACHINE_DEC_MAXINE_5000: /* type 7, KN02CA */
1618     machine->machine_name = "Personal DECstation 5000/xxx (MAXINE) (KN02CA)";
1619     if (machine->emulated_hz == 0)
1620     machine->emulated_hz = 33000000;
1621    
1622     if (machine->physical_ram_in_mb < 8)
1623     fprintf(stderr, "WARNING! Real KN02CA machines do not have less than 8MB RAM. Continuing anyway.\n");
1624     if (machine->physical_ram_in_mb > 40)
1625     fprintf(stderr, "WARNING! Real KN02CA machines cannot have more than 40MB RAM. Continuing anyway.\n");
1626    
1627     /* Maxine interrupts: */
1628     machine->md_interrupt = maxine_interrupt;
1629    
1630     /*
1631     * Something at address 0xca00000. (?)
1632     * Something at address 0xe000000. (?)
1633     * tc0 slot 0 (0x10000000)
1634     * tc0 slot 1 (0x14000000)
1635     * (tc0 slot 2 used by the framebuffer)
1636     * ioasic0 at tc0 slot 3 offset 0x0 (0x1c000000)
1637     * le0 at ioasic0 offset 0xc0000: address 00:00:00:00:00:00 (0x1c0c0000)
1638     * scc0 at ioasic0 offset 0x100000: console <-- serial (0x1c100000)
1639     * mcclock0 at ioasic0 offset 0x200000: mc146818 (0x1c200000)
1640     * isdn at ioasic0 offset 0x240000 not configured (0x1c240000)
1641     * bba0 at ioasic0 offset 0x240000 (audio0 at bba0) <--- which one of isdn and bba0?
1642     * dtop0 at ioasic0 offset 0x280000 (0x1c280000)
1643     * fdc at ioasic0 offset 0x2c0000 not configured <-- floppy (0x1c2c0000)
1644     * asc0 at ioasic0 offset 0x300000: NCR53C94, 25MHz, SCSI ID 7 (0x1c300000)
1645     * xcfb0 at tc0 slot 2 offset 0x0: 1024x768x8 built-in framebuffer (0xa000000)
1646     */
1647     machine->dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1c000000, 0);
1648    
1649     /* TURBOchannel slots (0 and 1): */
1650     dev_turbochannel_init(machine, mem, 0,
1651     0x10000000, 0x103fffff,
1652     machine->n_gfx_cards >= 2?
1653     turbochannel_default_gfx_card : "",
1654     XINE_INTR_TC_0 +8);
1655     dev_turbochannel_init(machine, mem, 1,
1656     0x14000000, 0x143fffff,
1657     machine->n_gfx_cards >= 3?
1658     turbochannel_default_gfx_card : "",
1659     XINE_INTR_TC_1 +8);
1660    
1661     /*
1662     * TURBOchannel slot 2 is hardwired to be used by
1663     * the framebuffer: (NOTE: 0x8000000, not 0x18000000)
1664     */
1665     dev_turbochannel_init(machine, mem, 2,
1666     0x8000000, 0xbffffff, "PMAG-DV", 0);
1667    
1668     /*
1669     * TURBOchannel slot 3: fixed, ioasic
1670     * (the system stuff), 0x1c000000
1671     */
1672     dev_le_init(machine, mem, 0x1c0c0000, 0, 0, XINE_INTR_LANCE +8, 4*65536);
1673     dev_scc_init(machine, mem, 0x1c100000,
1674     XINE_INTR_SCC_0 +8, machine->use_x11, 0, 1);
1675     dev_mc146818_init(machine, mem, 0x1c200000,
1676     XINE_INT_TOY, MC146818_DEC, 1);
1677     dev_asc_init(machine, mem, 0x1c300000,
1678     XINE_INTR_SCSI +8, NULL, DEV_ASC_DEC, NULL, NULL);
1679    
1680     framebuffer_console_name = "osconsole=3,2"; /* keyb,fb ?? */
1681     serial_console_name = "osconsole=3";
1682     break;
1683    
1684     case MACHINE_DEC_5500: /* type 11, KN220 */
1685     machine->machine_name = "DECsystem 5500 (KN220)";
1686    
1687     /*
1688     * According to NetBSD's pmax ports page:
1689     * KN220-AA is a "30 MHz R3000 CPU with R3010 FPU"
1690     * with "512 kBytes of Prestoserve battery backed RAM."
1691     */
1692     if (machine->emulated_hz == 0)
1693     machine->emulated_hz = 30000000;
1694    
1695     /*
1696     * See KN220 docs for more info.
1697     *
1698     * something at 0x10000000
1699     * something at 0x10001000
1700     * something at 0x10040000
1701     * scc at 0x10140000
1702     * qbus at (or around) 0x10080000
1703     * dssi (disk controller) buffers at 0x10100000, registers at 0x10160000.
1704     * sgec (ethernet) registers at 0x10008000, station addresss at 0x10120000.
1705     * asc (scsi) at 0x17100000.
1706     */
1707    
1708     dev_ssc_init(machine, mem, 0x10140000, 0, machine->use_x11, NULL); /* TODO: not irq 0 */
1709    
1710     /* something at 0x17000000, ultrix says "cpu 0 panic: DS5500 I/O Board is missing" if this is not here */
1711     dev_dec5500_ioboard_init(cpu, mem, 0x17000000);
1712    
1713     dev_sgec_init(mem, 0x10008000, 0); /* irq? */
1714    
1715     /* The asc controller might be TURBOchannel-ish? */
1716     #if 0
1717     dev_turbochannel_init(machine, mem, 0, 0x17100000, 0x171fffff, "PMAZ-AA", 0); /* irq? */
1718     #else
1719     dev_asc_init(machine, mem, 0x17100000, 0, NULL, DEV_ASC_DEC, NULL, NULL); /* irq? */
1720     #endif
1721    
1722     framebuffer_console_name = "osconsole=0,0"; /* TODO (?) */
1723     serial_console_name = "osconsole=0";
1724     break;
1725    
1726     case MACHINE_DEC_MIPSMATE_5100: /* type 12 */
1727     machine->machine_name = "DEC MIPSMATE 5100 (KN230)";
1728     if (machine->emulated_hz == 0)
1729     machine->emulated_hz = 20000000;
1730     if (machine->physical_ram_in_mb > 128)
1731     fprintf(stderr, "WARNING! Real MIPSMATE 5100 machines cannot have more than 128MB RAM. Continuing anyway.\n");
1732    
1733     if (machine->use_x11)
1734     fprintf(stderr, "WARNING! Real MIPSMATE 5100 machines cannot have a graphical framebuffer. Continuing anyway.\n");
1735    
1736     /* KN230 interrupts: */
1737     machine->md_interrupt = kn230_interrupt;
1738    
1739     /*
1740     * According to NetBSD/pmax:
1741     * dc0 at ibus0 addr 0x1c000000
1742     * le0 at ibus0 addr 0x18000000: address 00:00:00:00:00:00
1743     * sii0 at ibus0 addr 0x1a000000
1744     */
1745     dev_mc146818_init(machine, mem, KN230_SYS_CLOCK, 4, MC146818_DEC, 1);
1746     dev_dc7085_init(machine, mem, KN230_SYS_DZ0, KN230_CSR_INTR_DZ0, machine->use_x11); /* NOTE: CSR_INTR */
1747     /* dev_dc7085_init(machine, mem, KN230_SYS_DZ1, KN230_CSR_INTR_OPT0, machine->use_x11); */ /* NOTE: CSR_INTR */
1748     /* dev_dc7085_init(machine, mem, KN230_SYS_DZ2, KN230_CSR_INTR_OPT1, machine->use_x11); */ /* NOTE: CSR_INTR */
1749     dev_le_init(machine, mem, KN230_SYS_LANCE, KN230_SYS_LANCE_B_START, KN230_SYS_LANCE_B_END, KN230_CSR_INTR_LANCE, 4*1048576);
1750     dev_sii_init(machine, mem, KN230_SYS_SII, KN230_SYS_SII_B_START, KN230_SYS_SII_B_END, KN230_CSR_INTR_SII);
1751    
1752     snprintf(tmpstr, sizeof(tmpstr) - 1,
1753     "kn230 addr=0x%llx", (long long)KN230_SYS_ICSR);
1754     machine->kn230_csr = device_add(machine, tmpstr);
1755    
1756     serial_console_name = "osconsole=0";
1757     break;
1758    
1759     default:
1760     ;
1761     }
1762    
1763     /*
1764     * Most OSes on DECstation use physical addresses below
1765     * 0x20000000, but OSF/1 seems to use 0xbe...... as if it was
1766     * 0x1e......, so we need this hack:
1767     */
1768     dev_ram_init(mem, 0xa0000000, 0x20000000, DEV_RAM_MIRROR, 0x0);
1769    
1770     /* DECstation PROM stuff: (TODO: endianness) */
1771     for (i=0; i<100; i++)
1772     store_32bit_word(cpu, DEC_PROM_CALLBACK_STRUCT + i*4,
1773     DEC_PROM_EMULATION + i*8);
1774    
1775     /* Fill PROM with dummy return instructions: (TODO: make this nicer) */
1776     for (i=0; i<100; i++) {
1777     store_32bit_word(cpu, DEC_PROM_EMULATION + i*8,
1778     0x03e00008); /* return */
1779     store_32bit_word(cpu, DEC_PROM_EMULATION + i*8 + 4,
1780     0x00000000); /* nop */
1781     }
1782    
1783     /*
1784     * According to dec_prom.h from NetBSD:
1785     *
1786     * "Programs loaded by the new PROMs pass the following arguments:
1787     * a0 argc
1788     * a1 argv
1789     * a2 DEC_PROM_MAGIC
1790     * a3 The callback vector defined below"
1791     *
1792     * So we try to emulate a PROM, even though no such thing has been
1793     * loaded.
1794     */
1795    
1796     cpu->cd.mips.gpr[MIPS_GPR_A0] = 3;
1797     cpu->cd.mips.gpr[MIPS_GPR_A1] = DEC_PROM_INITIAL_ARGV;
1798     cpu->cd.mips.gpr[MIPS_GPR_A2] = DEC_PROM_MAGIC;
1799     cpu->cd.mips.gpr[MIPS_GPR_A3] = DEC_PROM_CALLBACK_STRUCT;
1800    
1801     store_32bit_word(cpu, INITIAL_STACK_POINTER + 0x10,
1802     BOOTINFO_MAGIC);
1803     store_32bit_word(cpu, INITIAL_STACK_POINTER + 0x14,
1804     BOOTINFO_ADDR);
1805    
1806     store_32bit_word(cpu, DEC_PROM_INITIAL_ARGV,
1807     (DEC_PROM_INITIAL_ARGV + 0x10));
1808     store_32bit_word(cpu, DEC_PROM_INITIAL_ARGV+4,
1809     (DEC_PROM_INITIAL_ARGV + 0x70));
1810     store_32bit_word(cpu, DEC_PROM_INITIAL_ARGV+8,
1811     (DEC_PROM_INITIAL_ARGV + 0xe0));
1812     store_32bit_word(cpu, DEC_PROM_INITIAL_ARGV+12, 0);
1813    
1814     /*
1815     * NetBSD and Ultrix expect the boot args to be like this:
1816     *
1817     * "boot" "bootdev" [args?]
1818     *
1819     * where bootdev is supposed to be "rz(0,0,0)netbsd" for
1820     * 3100/2100 (although that crashes Ultrix :-/), and
1821     * "5/rz0a/netbsd" for all others. The number '5' is the
1822     * slot number of the boot device.
1823     *
1824     * 'rz' for disks, 'tz' for tapes.
1825     *
1826     * TODO: Make this nicer.
1827     */
1828     {
1829     char bootpath[200];
1830    
1831     #if 0
1832     if (machine->machine_subtype == MACHINE_DEC_PMAX_3100)
1833     strcpy(bootpath, "rz(0,0,0)");
1834     else
1835     #endif
1836     strcpy(bootpath, "5/rz1/");
1837    
1838     if (bootdev_id < 0 || machine->force_netboot) {
1839     /* tftp boot: */
1840     strcpy(bootpath, "5/tftp/");
1841     bootpath[0] = '0' + boot_net_boardnumber;
1842     } else {
1843     /* disk boot: */
1844     bootpath[0] = '0' + boot_scsi_boardnumber;
1845     if (diskimage_is_a_tape(machine, bootdev_id))
1846     bootpath[2] = 't';
1847     bootpath[4] = '0' + bootdev_id;
1848     }
1849    
1850     init_bootpath = bootpath;
1851     }
1852    
1853     bootarg = malloc(strlen(init_bootpath) +
1854     strlen(machine->boot_kernel_filename) + 1 +
1855     strlen(machine->boot_string_argument) + 1);
1856     strcpy(bootarg, init_bootpath);
1857     strcat(bootarg, machine->boot_kernel_filename);
1858    
1859     bootstr = "boot";
1860    
1861     store_string(cpu, DEC_PROM_INITIAL_ARGV+0x10, bootstr);
1862     store_string(cpu, DEC_PROM_INITIAL_ARGV+0x70, bootarg);
1863     store_string(cpu, DEC_PROM_INITIAL_ARGV+0xe0,
1864     machine->boot_string_argument);
1865    
1866     /* Decrease the nr of args, if there are no args :-) */
1867     if (machine->boot_string_argument == NULL ||
1868     machine->boot_string_argument[0] == '\0')
1869     cpu->cd.mips.gpr[MIPS_GPR_A0] --;
1870    
1871     if (machine->boot_string_argument[0] != '\0') {
1872     strcat(bootarg, " ");
1873     strcat(bootarg, machine->boot_string_argument);
1874     }
1875    
1876     xx.a.common.next = (char *)&xx.b - (char *)&xx;
1877     xx.a.common.type = BTINFO_MAGIC;
1878     xx.a.magic = BOOTINFO_MAGIC;
1879    
1880     xx.b.common.next = (char *)&xx.c - (char *)&xx.b;
1881     xx.b.common.type = BTINFO_BOOTPATH;
1882     strcpy(xx.b.bootpath, bootstr);
1883    
1884     xx.c.common.next = 0;
1885     xx.c.common.type = BTINFO_SYMTAB;
1886     xx.c.nsym = 0;
1887     xx.c.ssym = 0;
1888     xx.c.esym = machine->file_loaded_end_addr;
1889    
1890     store_buf(cpu, BOOTINFO_ADDR, (char *)&xx, sizeof(xx));
1891    
1892     /*
1893     * The system's memmap: (memmap is a global variable, in
1894     * dec_prom.h)
1895     */
1896     store_32bit_word_in_host(cpu,
1897     (unsigned char *)&memmap.pagesize, 4096);
1898     {
1899     unsigned int i;
1900     for (i=0; i<sizeof(memmap.bitmap); i++)
1901     memmap.bitmap[i] = ((int)i * 4096*8 <
1902     1048576*machine->physical_ram_in_mb)?
1903     0xff : 0x00;
1904     }
1905     store_buf(cpu, DEC_MEMMAP_ADDR, (char *)&memmap, sizeof(memmap));
1906    
1907     /* Environment variables: */
1908     addr = DEC_PROM_STRINGS;
1909    
1910     if (machine->use_x11 && machine->n_gfx_cards > 0)
1911     /* (0,3) Keyboard and Framebuffer */
1912     add_environment_string(cpu, framebuffer_console_name, &addr);
1913     else
1914     /* Serial console */
1915     add_environment_string(cpu, serial_console_name, &addr);
1916    
1917     /*
1918     * The KN5800 (SMP system) uses a CCA (console communications
1919     * area): (See VAX 6000 documentation for details.)
1920     */
1921     {
1922     char tmps[300];
1923     sprintf(tmps, "cca=%x",
1924     (int)(DEC_DECCCA_BASEADDR + 0xa0000000ULL));
1925     add_environment_string(cpu, tmps, &addr);
1926     }
1927    
1928     /* These are needed for Sprite to boot: */
1929     {
1930     char tmps[300];
1931    
1932     sprintf(tmps, "boot=%s", bootarg);
1933     add_environment_string(cpu, tmps, &addr);
1934    
1935     sprintf(tmps, "bitmap=0x%x", (uint32_t)((
1936     DEC_MEMMAP_ADDR + sizeof(memmap.pagesize))
1937     & 0xffffffffULL));
1938     add_environment_string(cpu, tmps, &addr);
1939    
1940     sprintf(tmps, "bitmaplen=0x%x",
1941     machine->physical_ram_in_mb * 1048576 / 4096 / 8);
1942     add_environment_string(cpu, tmps, &addr);
1943     }
1944    
1945     add_environment_string(cpu, "scsiid0=7", &addr);
1946     add_environment_string(cpu, "bootmode=a", &addr);
1947     add_environment_string(cpu, "testaction=q", &addr);
1948     add_environment_string(cpu, "haltaction=h", &addr);
1949     add_environment_string(cpu, "more=24", &addr);
1950    
1951     /* Used in at least Ultrix on the 5100: */
1952     add_environment_string(cpu, "scsiid=7", &addr);
1953     add_environment_string(cpu, "baud0=9600", &addr);
1954     add_environment_string(cpu, "baud1=9600", &addr);
1955     add_environment_string(cpu, "baud2=9600", &addr);
1956     add_environment_string(cpu, "baud3=9600", &addr);
1957     add_environment_string(cpu, "iooption=0x1", &addr);
1958    
1959     /* The end: */
1960     add_environment_string(cpu, "", &addr);
1961    
1962     break;
1963    
1964     case MACHINE_COBALT:
1965     cpu->byte_order = EMUL_LITTLE_ENDIAN;
1966     machine->machine_name = "Cobalt";
1967    
1968     /*
1969     * Interrupts seem to be the following:
1970     * (according to http://www.funet.fi/pub/Linux/PEOPLE/Linus/v2.4/patch-html/patch-2.4.19/linux-2.4.19_arch_mips_cobalt_irq.c.html)
1971     *
1972     * 2 Galileo chip (timer)
1973     * 3 Tulip 0 + NCR SCSI
1974     * 4 Tulip 1
1975     * 5 16550 UART (serial console)
1976     * 6 VIA southbridge PIC
1977     * 7 PCI
1978     */
1979     /* dev_XXX_init(cpu, mem, 0x10000000, machine->emulated_hz); */
1980     dev_mc146818_init(machine, mem, 0x10000070, 0, MC146818_PC_CMOS, 4);
1981     machine->main_console_handle = dev_ns16550_init(machine, mem,
1982     0x1c800000, 5, 1, 1, "serial console");
1983    
1984     /*
1985     * According to NetBSD/cobalt:
1986     *
1987     * pchb0 at pci0 dev 0 function 0: Galileo GT-64111 System Controller, rev 1 (NOTE: added by dev_gt_init())
1988     * tlp0 at pci0 dev 7 function 0: DECchip 21143 Ethernet, pass 4.1
1989     * Symbios Logic 53c860 (SCSI mass storage, revision 0x02) at pci0 dev 8
1990     * pcib0 at pci0 dev 9 function 0, VIA Technologies VT82C586 (Apollo VP) PCI-ISA Bridge, rev 37
1991     * pciide0 at pci0 dev 9 function 1: VIA Technologies VT82C586 (Apollo VP) ATA33 cr
1992     * tlp1 at pci0 dev 12 function 0: DECchip 21143 Ethernet, pass 4.1
1993     */
1994     pci_data = dev_gt_init(machine, mem, 0x14000000, 2, 6); /* 7 for PCI, not 6? */
1995     /* bus_pci_add(machine, pci_data, mem, 0, 7, 0, pci_dec21143_init, pci_dec21143_rr); */
1996     bus_pci_add(machine, pci_data, mem, 0, 8, 0, NULL, NULL); /* PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_860 */
1997     bus_pci_add(machine, pci_data, mem, 0, 9, 0, pci_vt82c586_isa_init, pci_vt82c586_isa_rr);
1998     bus_pci_add(machine, pci_data, mem, 0, 9, 1, pci_vt82c586_ide_init, pci_vt82c586_ide_rr);
1999     /* bus_pci_add(machine, pci_data, mem, 0, 12, 0, pci_dec21143_init, pci_dec21143_rr); */
2000    
2001     /*
2002     * NetBSD/cobalt expects memsize in a0, but it seems that what
2003     * it really wants is the end of memory + 0x80000000.
2004     *
2005     * The bootstring should be stored starting 512 bytes before end
2006     * of physical ram.
2007     */
2008     cpu->cd.mips.gpr[MIPS_GPR_A0] = machine->physical_ram_in_mb * 1048576 + 0x80000000;
2009     bootstr = "root=/dev/hda1 ro";
2010     /* bootstr = "nfsroot=/usr/cobalt/"; */
2011     store_string(cpu, 0xffffffff80000000ULL +
2012     machine->physical_ram_in_mb * 1048576 - 512, bootstr);
2013     break;
2014    
2015     case MACHINE_HPCMIPS:
2016     cpu->byte_order = EMUL_LITTLE_ENDIAN;
2017     memset(&hpc_bootinfo, 0, sizeof(hpc_bootinfo));
2018     /* TODO: set platid from netbsd/usr/src/sys/arch/hpc/include/platid* */
2019     /*
2020     #define PLATID_FLAGS_SHIFT 0
2021     #define PLATID_CPU_SUBMODEL_SHIFT 8
2022     #define PLATID_CPU_MODEL_SHIFT 14
2023     #define PLATID_CPU_SERIES_SHIFT 20
2024     #define PLATID_CPU_ARCH_SHIFT 26
2025    
2026     #define PLATID_SUBMODEL_SHIFT 0
2027     #define PLATID_MODEL_SHIFT 8
2028     #define PLATID_SERIES_SHIFT 16
2029     #define PLATID_VENDOR_SHIFT 22
2030     */
2031    
2032     /*
2033     NOTE: See http://forums.projectmayo.com/viewtopic.php?topic=2743&forum=23
2034     for info on framebuffer addresses.
2035     */
2036    
2037     switch (machine->machine_subtype) {
2038     case MACHINE_HPCMIPS_CASIO_BE300:
2039     /* 166MHz VR4131 */
2040     machine->machine_name = "Casio Cassiopeia BE-300";
2041     hpcmips_fb_addr = 0x0a200000;
2042     hpcmips_fb_xsize = 240;
2043     hpcmips_fb_ysize = 320;
2044     hpcmips_fb_xsize_mem = 256;
2045     hpcmips_fb_ysize_mem = 320;
2046     hpcmips_fb_bits = 15;
2047     hpcmips_fb_encoding = BIFB_D16_0000;
2048    
2049     machine->main_console_handle = dev_ns16550_init(
2050     machine, mem, 0xa008680, 0, 4,
2051     machine->use_x11? 0 : 1, "serial console"); /* TODO: irq? */
2052     machine->vr41xx_data = dev_vr41xx_init(machine, mem, 4131);
2053     machine->md_interrupt = vr41xx_interrupt;
2054    
2055     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2056     (1 << 26) /* 1 = MIPS */
2057     + (1 << 20) /* 1 = VR */
2058     + (1 << 14) /* 1 = VR41XX */
2059     + (6 << 8) /* 6 = VR4131 */
2060     );
2061     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2062     (3 << 22) /* 22: vendor 3=casio */
2063     + (1 << 16) /* 16: series 1=CASSIOPEIAE*/
2064     + (2 << 8) /* 8: model 2=EXXX*/
2065     + (3) /* 0: submodel 3=E500 */
2066     );
2067     /* TODO: Don't use model number for E500, it's a BE300! */
2068     break;
2069     case MACHINE_HPCMIPS_CASIO_E105:
2070     /* 131MHz VR4121 */
2071     machine->machine_name = "Casio Cassiopeia E-105";
2072     hpcmips_fb_addr = 0x0a200000; /* TODO? */
2073     hpcmips_fb_xsize = 240;
2074     hpcmips_fb_ysize = 320;
2075     hpcmips_fb_xsize_mem = 256;
2076     hpcmips_fb_ysize_mem = 320;
2077     hpcmips_fb_bits = 16;
2078     hpcmips_fb_encoding = BIFB_D16_0000;
2079    
2080     machine->main_console_handle = dev_ns16550_init(
2081     machine, mem, 0xa008680, 0, 4,
2082     machine->use_x11? 0 : 1, "serial console"); /* TODO: irq? */
2083     machine->vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2084     machine->md_interrupt = vr41xx_interrupt;
2085    
2086     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2087     (1 << 26) /* 1 = MIPS */
2088     + (1 << 20) /* 1 = VR */
2089     + (1 << 14) /* 1 = VR41XX */
2090     + (3 << 8) /* 3 = VR4121 */
2091     );
2092     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2093     (3 << 22) /* 22: vendor 3=casio */
2094     + (1 << 16) /* 16: series 1=CASSIOPEIAE*/
2095     + (2 << 8) /* 8: model 2=EXXX*/
2096     + (2) /* 0: submodel 2=E105 */
2097     );
2098     break;
2099     case MACHINE_HPCMIPS_NEC_MOBILEPRO_770:
2100     /* 131 MHz VR4121 */
2101     machine->machine_name = "NEC MobilePro 770";
2102     /* TODO: */
2103     hpcmips_fb_addr = 0xa000000;
2104     hpcmips_fb_xsize = 640;
2105     hpcmips_fb_ysize = 240;
2106     hpcmips_fb_xsize_mem = 800;
2107     hpcmips_fb_ysize_mem = 240;
2108     hpcmips_fb_bits = 16;
2109     hpcmips_fb_encoding = BIFB_D16_0000;
2110    
2111     machine->vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2112     machine->md_interrupt = vr41xx_interrupt;
2113    
2114     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2115     (1 << 26) /* 1 = MIPS */
2116     + (1 << 20) /* 1 = VR */
2117     + (1 << 14) /* 1 = VR41XX */
2118     + (3 << 8) /* 3 = VR4121 */
2119     );
2120     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2121     (1 << 22) /* 22: vendor 1=NEC */
2122     + (2 << 16) /* 16: series 2="NEC MCR" */
2123     + (2 << 8) /* 8: model 2="MCR 5XX" */
2124     + (4) /* 0: submodel 4="MCR 520A" */
2125     );
2126     break;
2127     case MACHINE_HPCMIPS_NEC_MOBILEPRO_780:
2128     /* 166 (or 168) MHz VR4121 */
2129     machine->machine_name = "NEC MobilePro 780";
2130     /* TODO: */
2131     hpcmips_fb_addr = 0xa180100;
2132     hpcmips_fb_xsize = 640;
2133     hpcmips_fb_ysize = 240;
2134     hpcmips_fb_xsize_mem = 640;
2135     hpcmips_fb_ysize_mem = 240;
2136     hpcmips_fb_bits = 16;
2137     hpcmips_fb_encoding = BIFB_D16_0000;
2138    
2139     machine->vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2140     machine->md_interrupt = vr41xx_interrupt;
2141    
2142     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2143     (1 << 26) /* 1 = MIPS */
2144     + (1 << 20) /* 1 = VR */
2145     + (1 << 14) /* 1 = VR41XX */
2146     + (3 << 8) /* 3 = VR4121 */
2147     );
2148     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2149     (1 << 22) /* 22: vendor 1=NEC */
2150     + (2 << 16) /* 16: series 2="NEC MCR" */
2151     + (2 << 8) /* 8: model 2="MCR 5XX" */
2152     + (8) /* 0: submodel 8="MCR 530A" */
2153     );
2154     break;
2155     case MACHINE_HPCMIPS_NEC_MOBILEPRO_800:
2156     /* 131 MHz VR4121 */
2157     machine->machine_name = "NEC MobilePro 800";
2158     /* TODO: */
2159     hpcmips_fb_addr = 0xa000000;
2160     hpcmips_fb_xsize = 800;
2161     hpcmips_fb_ysize = 600;
2162     hpcmips_fb_xsize_mem = 800;
2163     hpcmips_fb_ysize_mem = 600;
2164     hpcmips_fb_bits = 16;
2165     hpcmips_fb_encoding = BIFB_D16_0000;
2166    
2167     machine->vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2168     machine->md_interrupt = vr41xx_interrupt;
2169    
2170     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2171     (1 << 26) /* 1 = MIPS */
2172     + (1 << 20) /* 1 = VR */
2173     + (1 << 14) /* 1 = VR41XX */
2174     + (3 << 8) /* 3 = VR4121 */
2175     );
2176     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2177     (1 << 22) /* 22: vendor 1=NEC */
2178     + (2 << 16) /* 16: series 2="NEC MCR" */
2179     + (3 << 8) /* 8: model 3="MCR 7XX" */
2180     + (2) /* 0: submodel 2="MCR 700A" */
2181     );
2182     break;
2183     case MACHINE_HPCMIPS_NEC_MOBILEPRO_880:
2184     /* 168 MHz VR4121 */
2185     machine->machine_name = "NEC MobilePro 880";
2186     /* TODO: */
2187     hpcmips_fb_addr = 0xa0ea600;
2188     hpcmips_fb_xsize = 800;
2189     hpcmips_fb_ysize = 600;
2190     hpcmips_fb_xsize_mem = 800;
2191     hpcmips_fb_ysize_mem = 600;
2192     hpcmips_fb_bits = 16;
2193     hpcmips_fb_encoding = BIFB_D16_0000;
2194    
2195     machine->vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2196     machine->md_interrupt = vr41xx_interrupt;
2197    
2198     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2199     (1 << 26) /* 1 = MIPS */
2200     + (1 << 20) /* 1 = VR */
2201     + (1 << 14) /* 1 = VR41XX */
2202     + (3 << 8) /* 3 = VR4121 */
2203     );
2204     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2205     (1 << 22) /* 22: vendor 1=NEC */
2206     + (2 << 16) /* 16: series 2="NEC MCR" */
2207     + (3 << 8) /* 8: model 3="MCR 7XX" */
2208     + (4) /* 0: submodel 4="MCR 730A" */
2209     );
2210     break;
2211     case MACHINE_HPCMIPS_AGENDA_VR3:
2212     /* 66 MHz VR4181 */
2213     machine->machine_name = "Agenda VR3";
2214     /* TODO: */
2215     hpcmips_fb_addr = 0x1000;
2216     hpcmips_fb_xsize = 160;
2217     hpcmips_fb_ysize = 240;
2218     hpcmips_fb_xsize_mem = 160;
2219     hpcmips_fb_ysize_mem = 240;
2220     hpcmips_fb_bits = 4;
2221     hpcmips_fb_encoding = BIFB_D4_M2L_F;
2222    
2223     machine->vr41xx_data = dev_vr41xx_init(machine, mem, 4181);
2224     machine->md_interrupt = vr41xx_interrupt;
2225    
2226     /* TODO: Hm... irq 17 according to linux, but
2227     VRIP_INTR_SIU (=9) here? */
2228     {
2229     int x;
2230     x = dev_ns16550_init(machine, mem, 0x0c000010,
2231     8 + VRIP_INTR_SIU, 1, 1, "serial 0");
2232    
2233     if (!machine->use_x11)
2234     machine->main_console_handle = x;
2235     }
2236    
2237     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2238     (1 << 26) /* 1 = MIPS */
2239     + (1 << 20) /* 1 = VR */
2240     + (1 << 14) /* 1 = VR41XX */
2241     + (4 << 8) /* 4 = VR4181 */
2242     );
2243     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2244     (15 << 22) /* 22: vendor 15=Agenda */
2245     + (1 << 16) /* 16: series 2=VR */
2246     + (1 << 8) /* 8: model 1=VR3 */
2247     + (0) /* 0: submodel 0="VR3" */
2248     );
2249    
2250     dev_ram_init(mem, 0x0f000000, 0x01000000, DEV_RAM_MIRROR, 0x0);
2251     break;
2252     case MACHINE_HPCMIPS_IBM_WORKPAD_Z50:
2253     /* 131 MHz VR4121 */
2254     machine->machine_name = "Agenda VR3";
2255     /* TODO: */
2256     hpcmips_fb_addr = 0xa000000;
2257     hpcmips_fb_xsize = 640;
2258     hpcmips_fb_ysize = 480;
2259     hpcmips_fb_xsize_mem = 640;
2260     hpcmips_fb_ysize_mem = 480;
2261     hpcmips_fb_bits = 16;
2262     hpcmips_fb_encoding = BIFB_D16_0000;
2263    
2264     machine->vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2265     machine->md_interrupt = vr41xx_interrupt;
2266    
2267     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2268     (1 << 26) /* 1 = MIPS */
2269     + (1 << 20) /* 1 = VR */
2270     + (1 << 14) /* 1 = VR41XX */
2271     + (3 << 8) /* 3 = VR4121 */
2272     );
2273     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2274     (9 << 22) /* 22: vendor 9=IBM */
2275     + (1 << 16) /* 16: series 1=WorkPad */
2276     + (1 << 8) /* 8: model 1=Z50 */
2277     + (0) /* 0: submodel 0 */
2278     );
2279     break;
2280     default:
2281     printf("Unimplemented hpcmips machine number.\n");
2282     exit(1);
2283     }
2284    
2285     if (machine->use_x11)
2286     machine->main_console_handle =
2287     machine->vr41xx_data->kiu_console_handle;
2288    
2289     /* NetBSD/hpcmips and possibly others expects the following: */
2290    
2291     cpu->cd.mips.gpr[MIPS_GPR_A0] = 1; /* argc */
2292     cpu->cd.mips.gpr[MIPS_GPR_A1] = machine->physical_ram_in_mb * 1048576
2293     + 0xffffffff80000000ULL - 512; /* argv */
2294     cpu->cd.mips.gpr[MIPS_GPR_A2] = machine->physical_ram_in_mb * 1048576
2295     + 0xffffffff80000000ULL - 256; /* ptr to hpc_bootinfo */
2296    
2297     bootstr = machine->boot_kernel_filename;
2298     store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 16);
2299     store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 4, 0);
2300     store_string(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 16, bootstr);
2301    
2302     /* Special case for the Agenda VR3: */
2303     if (machine->machine_subtype == MACHINE_HPCMIPS_AGENDA_VR3) {
2304     const int tmplen = 1000;
2305     char *tmp = malloc(tmplen);
2306    
2307     cpu->cd.mips.gpr[MIPS_GPR_A0] = 2; /* argc */
2308    
2309     store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 4, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 64);
2310     store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 8, 0);
2311    
2312     snprintf(tmp, tmplen, "root=/dev/rom video=vr4181fb:xres:160,yres:240,bpp:4,"
2313     "gray,hpck:3084,inv ether=0,0x03fe0300,eth0");
2314     tmp[tmplen-1] = '\0';
2315    
2316     if (!machine->use_x11)
2317     snprintf(tmp+strlen(tmp), tmplen-strlen(tmp), " console=ttyS0,115200");
2318     tmp[tmplen-1] = '\0';
2319    
2320     if (machine->boot_string_argument[0])
2321     snprintf(tmp+strlen(tmp), tmplen-strlen(tmp), " %s", machine->boot_string_argument);
2322     tmp[tmplen-1] = '\0';
2323    
2324     store_string(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 64, tmp);
2325    
2326     bootarg = tmp;
2327     } else if (machine->boot_string_argument[0]) {
2328     cpu->cd.mips.gpr[MIPS_GPR_A0] ++; /* argc */
2329    
2330     store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 4, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 64);
2331     store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 8, 0);
2332    
2333     store_string(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 64,
2334     machine->boot_string_argument);
2335    
2336     bootarg = machine->boot_string_argument;
2337     }
2338    
2339     store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.length, sizeof(hpc_bootinfo));
2340     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.magic, HPC_BOOTINFO_MAGIC);
2341     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_addr, 0x80000000 + hpcmips_fb_addr);
2342     store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_line_bytes, hpcmips_fb_xsize_mem * (((hpcmips_fb_bits-1)|7)+1) / 8);
2343     store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_width, hpcmips_fb_xsize);
2344     store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_height, hpcmips_fb_ysize);
2345     store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_type, hpcmips_fb_encoding);
2346     store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.bi_cnuse, BI_CNUSE_BUILTIN); /* _BUILTIN or _SERIAL */
2347    
2348     /* printf("hpc_bootinfo.platid_cpu = 0x%08x\n", hpc_bootinfo.platid_cpu);
2349     printf("hpc_bootinfo.platid_machine = 0x%08x\n", hpc_bootinfo.platid_machine); */
2350     store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.timezone, 0);
2351     store_buf(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 256, (char *)&hpc_bootinfo, sizeof(hpc_bootinfo));
2352    
2353     if (hpcmips_fb_addr != 0) {
2354     dev_fb_init(machine, mem, hpcmips_fb_addr, VFB_HPCMIPS,
2355     hpcmips_fb_xsize, hpcmips_fb_ysize,
2356     hpcmips_fb_xsize_mem, hpcmips_fb_ysize_mem,
2357     hpcmips_fb_bits, "HPCmips", 0);
2358    
2359     /* NetBSD/hpcmips uses framebuffer at physical
2360     address 0x8.......: */
2361     dev_ram_init(mem, 0x80000000, 0x20000000,
2362     DEV_RAM_MIRROR, 0x0);
2363     }
2364    
2365     break;
2366    
2367     case MACHINE_PS2:
2368     cpu->byte_order = EMUL_LITTLE_ENDIAN;
2369     machine->machine_name = "Playstation 2";
2370    
2371     if (machine->physical_ram_in_mb != 32)
2372     fprintf(stderr, "WARNING! Playstation 2 machines are supposed to have exactly 32 MB RAM. Continuing anyway.\n");
2373     if (!machine->use_x11)
2374     fprintf(stderr, "WARNING! Playstation 2 without -X is pretty meaningless. Continuing anyway.\n");
2375    
2376     /*
2377     * According to NetBSD:
2378     * Hardware irq 0 is timer/interrupt controller
2379     * Hardware irq 1 is dma controller
2380     *
2381     * Some things are not yet emulated (at all), and hence are detected incorrectly:
2382     * sbus0 at mainbus0: controller type 2
2383     * ohci0 at sbus0 (at 0x1f801600, according to linux)
2384     * ohci0: OHCI version 1.0
2385     */
2386    
2387     device_add(machine, "ps2_gs addr=0x12000000");
2388     machine->ps2_data = dev_ps2_stuff_init(machine, mem, 0x10000000);
2389     dev_ps2_ohci_init(cpu, mem, 0x1f801600);
2390     dev_ram_init(mem, 0x1c000000, 4 * 1048576, DEV_RAM_RAM, 0); /* TODO: how much? */
2391    
2392     machine->md_interrupt = ps2_interrupt;
2393    
2394     add_symbol_name(&machine->symbol_context,
2395     PLAYSTATION2_SIFBIOS, 0x10000, "[SIFBIOS entry]", 0);
2396     store_32bit_word(cpu, PLAYSTATION2_BDA + 0, PLAYSTATION2_SIFBIOS);
2397     store_buf(cpu, PLAYSTATION2_BDA + 4, "PS2b", 4);
2398    
2399     #if 0
2400     /* Harddisk controller present flag: */
2401     store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x0, 0x100);
2402     dev_ps2_spd_init(machine, mem, 0x14000000);
2403     #endif
2404    
2405     store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x4, PLAYSTATION2_OPTARGS);
2406     bootstr = "root=/dev/hda1 crtmode=vesa0,60";
2407     store_string(cpu, PLAYSTATION2_OPTARGS, bootstr);
2408    
2409     /* TODO: netbsd's bootinfo.h, for symbolic names */
2410     {
2411     time_t timet;
2412     struct tm *tmp;
2413    
2414     /* RTC data given by the BIOS: */
2415     timet = time(NULL) + 9*3600; /* PS2 uses Japanese time */
2416     tmp = gmtime(&timet);
2417     /* TODO: are these 0- or 1-based? */
2418     store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 1, int_to_bcd(tmp->tm_sec));
2419     store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 2, int_to_bcd(tmp->tm_min));
2420     store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 3, int_to_bcd(tmp->tm_hour));
2421     store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 5, int_to_bcd(tmp->tm_mday));
2422     store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 6, int_to_bcd(tmp->tm_mon + 1));
2423     store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 7, int_to_bcd(tmp->tm_year - 100));
2424     }
2425    
2426     /* "BOOTINFO_PCMCIA_TYPE" in NetBSD's bootinfo.h. This contains the sbus controller type. */
2427     store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x1c, 3);
2428    
2429     /* TODO: Is this necessary? */
2430     cpu->cd.mips.gpr[MIPS_GPR_SP] = 0x80007f00;
2431    
2432     break;
2433    
2434     case MACHINE_SGI:
2435     case MACHINE_ARC:
2436     /*
2437     * SGI and ARC emulation share a lot of code. (SGI is a special case of
2438     * "almost ARC".)
2439     *
2440     * http://obsolete.majix.org/computers/sgi/iptable.shtml contains a pretty
2441     * detailed list of IP ("Inhouse Processor") model numbers.
2442     * (Or http://hardware.majix.org/computers/sgi/iptable.shtml)
2443     */
2444     machine->machine_name = malloc(500);
2445     if (machine->machine_name == NULL) {
2446     fprintf(stderr, "out of memory\n");
2447     exit(1);
2448     }
2449     short_machine_name = malloc(500);
2450     if (short_machine_name == NULL) {
2451     fprintf(stderr, "out of memory\n");
2452     exit(1);
2453     }
2454    
2455     if (machine->machine_type == MACHINE_SGI) {
2456     cpu->byte_order = EMUL_BIG_ENDIAN;
2457     sprintf(short_machine_name, "SGI-IP%i", machine->machine_subtype);
2458     sprintf(machine->machine_name, "SGI-IP%i", machine->machine_subtype);
2459    
2460     /* Super-special case for IP24: */
2461     if (machine->machine_subtype == 24)
2462     sprintf(short_machine_name, "SGI-IP22");
2463    
2464     sgi_ram_offset = 1048576 * machine->memory_offset_in_mb;
2465    
2466     /* Special cases for IP20,22,24,26 memory offset: */
2467     if (machine->machine_subtype == 20 || machine->machine_subtype == 22 ||
2468     machine->machine_subtype == 24 || machine->machine_subtype == 26) {
2469     dev_ram_init(mem, 0x00000000, 0x10000, DEV_RAM_MIRROR, sgi_ram_offset);
2470     dev_ram_init(mem, 0x00050000, sgi_ram_offset-0x50000, DEV_RAM_MIRROR, sgi_ram_offset + 0x50000);
2471     }
2472    
2473     /* Special cases for IP28,30 memory offset: */
2474     if (machine->machine_subtype == 28 || machine->machine_subtype == 30) {
2475     /* TODO: length below should maybe not be 128MB? */
2476     dev_ram_init(mem, 0x00000000, 128*1048576, DEV_RAM_MIRROR, sgi_ram_offset);
2477     }
2478     } else {
2479     cpu->byte_order = EMUL_LITTLE_ENDIAN;
2480     sprintf(short_machine_name, "ARC");
2481     sprintf(machine->machine_name, "ARC");
2482     }
2483    
2484     if (machine->machine_type == MACHINE_SGI) {
2485     /* TODO: Other SGI machine types? */
2486     switch (machine->machine_subtype) {
2487     case 12:
2488     strcat(machine->machine_name, " (Iris Indigo IP12)");
2489    
2490     /* TODO */
2491     /* 33 MHz R3000, according to http://www.irisindigo.com/ */
2492     /* "capable of addressing up to 96MB of memory." */
2493    
2494     break;
2495     case 19:
2496     strcat(machine->machine_name, " (Everest IP19)");
2497     machine->main_console_handle =
2498     dev_zs_init(machine, mem, 0x1fbd9830, 0, 1, "serial zs"); /* serial? netbsd? */
2499     dev_scc_init(machine, mem, 0x10086000, 0, machine->use_x11, 0, 8); /* serial? irix? */
2500    
2501     device_add(machine, "sgi_ip19 addr=0x18000000");
2502    
2503     /* Irix' <everest_du_init+0x130> reads this device: */
2504     device_add(machine, "random addr=0x10006000 len=16");
2505    
2506     /* Irix' get_mpconf() looks for this: (TODO) */
2507     store_32bit_word(cpu, 0xa0000000 + 0x3000,
2508     0xbaddeed2);
2509    
2510     /* Memory size, not 4096 byte pages, but 256 bytes? (16 is size of kernel... approx) */
2511     store_32bit_word(cpu, 0xa0000000 + 0x26d0,
2512     30000); /* (machine->physical_ram_in_mb - 16) * (1048576 / 256)); */
2513    
2514     break;
2515     case 20:
2516     strcat(machine->machine_name, " (Indigo)");
2517    
2518     /*
2519     * Guesses based on NetBSD 2.0 beta, 20040606.
2520     *
2521     * int0 at mainbus0 addr 0x1fb801c0: bus 1MHz, CPU 2MHz
2522     * imc0 at mainbus0 addr 0x1fa00000: revision 0
2523     * gio0 at imc0
2524     * unknown GIO card (product 0x00 revision 0x00) at gio0 slot 0 addr 0x1f400000 not configured
2525     * unknown GIO card (product 0x00 revision 0x00) at gio0 slot 1 addr 0x1f600000 not configured
2526     * unknown GIO card (product 0x00 revision 0x00) at gio0 slot 2 addr 0x1f000000 not configured
2527     * hpc0 at gio0 addr 0x1fb80000: SGI HPC1
2528     * zsc0 at hpc0 offset 0xd10 (channels 0 and 1, channel 1 for console)
2529     * zsc1 at hpc0 offset 0xd00 (2 channels)
2530     * sq0 at hpc0 offset 0x100: SGI Seeq 80c03
2531     * wdsc0 at hpc0 offset 0x11f
2532     * dpclock0 at hpc0 offset 0xe00
2533     */
2534    
2535     /* int0 at mainbus0 addr 0x1fb801c0 */
2536     machine->sgi_ip20_data = dev_sgi_ip20_init(cpu, mem, DEV_SGI_IP20_BASE);
2537    
2538     /* imc0 at mainbus0 addr 0x1fa00000: revision 0: TODO (or in dev_sgi_ip20?) */
2539    
2540     dev_zs_init(machine, mem, 0x1fbd9830, 0, 1, "zs console");
2541    
2542     /* This is the zsc0 reported by NetBSD: TODO: irqs */
2543     machine->main_console_handle = dev_zs_init(machine, mem, 0x1fb80d10, 0, 1, "zsc0"); /* zsc0 */
2544     dev_zs_init(machine, mem, 0x1fb80d00, 0, 1, "zsc1"); /* zsc1 */
2545    
2546     /* WDSC SCSI controller: */
2547     dev_wdsc_init(machine, mem, 0x1fb8011f, 0, 0);
2548    
2549     /* Return memory read errors so that hpc1
2550     and hpc2 are not detected: */
2551     device_add(machine, "unreadable addr=0x1fb00000 len=0x10000");
2552     device_add(machine, "unreadable addr=0x1f980000 len=0x10000");
2553    
2554     /* Return nothing for gio slots 0, 1, and 2: */
2555     device_add(machine, "unreadable addr=0x1f400000 len=0x1000"); /* gio0 slot 0 */
2556     device_add(machine, "unreadable addr=0x1f600000 len=0x1000"); /* gio0 slot 1 */
2557     device_add(machine, "unreadable addr=0x1f000000 len=0x1000"); /* gio0 slot 2 */
2558    
2559     break;
2560     case 21:
2561     strcat(machine->machine_name, " (uknown SGI-IP21 ?)"); /* TODO */
2562     /* NOTE: Special case for arc_wordlen: */
2563     arc_wordlen = sizeof(uint64_t);
2564    
2565     device_add(machine, "random addr=0x418000200, len=0x20000");
2566    
2567     break;
2568     case 22:
2569     case 24:
2570     if (machine->machine_subtype == 22) {
2571     strcat(machine->machine_name, " (Indy, Indigo2, Challenge S; Full-house)");
2572     machine->sgi_ip22_data = dev_sgi_ip22_init(machine, mem, 0x1fbd9000, 0);
2573     } else {
2574     strcat(machine->machine_name, " (Indy, Indigo2, Challenge S; Guiness)");
2575     machine->sgi_ip22_data = dev_sgi_ip22_init(machine, mem, 0x1fbd9880, 1);
2576     }
2577    
2578     /*
2579     Why is this here? TODO
2580     dev_ram_init(mem, 0x88000000ULL,
2581     128 * 1048576, DEV_RAM_MIRROR, 0x08000000);
2582     */
2583     machine->md_interrupt = sgi_ip22_interrupt;
2584    
2585     /*
2586     * According to NetBSD 1.6.2:
2587     *
2588     * imc0 at mainbus0 addr 0x1fa00000, Revision 0
2589     * gio0 at imc0
2590     * hpc0 at gio0 addr 0x1fb80000: SGI HPC3
2591     * zsc0 at hpc0 offset 0x59830
2592     * zstty0 at zsc0 channel 1 (console i/o)
2593     * zstty1 at zsc0 channel 0
2594     * sq0 at hpc0 offset 0x54000: SGI Seeq 80c03 (Ethernet)
2595     * wdsc0 at hpc0 offset 0x44000: WD33C93 SCSI, rev=0, target 7
2596     * scsibus2 at wdsc0: 8 targets, 8 luns per target
2597     * dsclock0 at hpc0 offset 0x60000
2598     *
2599     * According to Linux/IP22:
2600     * tty00 at 0xbfbd9830 (irq = 45) is a Zilog8530
2601     * tty01 at 0xbfbd9838 (irq = 45) is a Zilog8530
2602     *
2603     * and according to NetBSD 2.0_BETA (20040606):
2604     *
2605     * haltwo0 at hpc0 offset 0x58000: HAL2 revision 0.0.0
2606     * audio0 at haltwo0: half duplex
2607     *
2608     * IRQ numbers are of the form 8 + x, where x = 0..31 for local0
2609     * interrupts, and 32..63 for local1. + y*65 for "mappable".
2610     */
2611    
2612     /* zsc0 serial console. */
2613     i = dev_zs_init(machine, mem, 0x1fbd9830,
2614     8 + 32 + 3 + 64*5, 1, "zsc0");
2615    
2616     /* Not supported by NetBSD 1.6.2, but by 2.0_BETA: */
2617     j = dev_pckbc_init(machine, mem, 0x1fbd9840, PCKBC_8242,
2618     0, 0, machine->use_x11); /* TODO: irq numbers */
2619    
2620     if (machine->use_x11)
2621     machine->main_console_handle = j;
2622    
2623     /* sq0: Ethernet. TODO: This should have irq_nr = 8 + 3 */
2624     /* dev_sq_init... */
2625    
2626     /* wdsc0: SCSI */
2627     dev_wdsc_init(machine, mem, 0x1fbc4000, 0, 8 + 1);
2628    
2629     /* wdsc1: SCSI TODO: irq nr */
2630     dev_wdsc_init(machine, mem, 0x1fbcc000, 1, 8 + 1);
2631    
2632     /* dsclock0: TODO: possibly irq 8 + 33 */
2633    
2634     /* Return memory read errors so that hpc1 and hpc2 are not detected: */
2635     device_add(machine, "unreadable addr=0x1fb00000, len=0x10000");
2636     device_add(machine, "unreadable addr=0x1f980000, len=0x10000");
2637    
2638     /* Similarly for gio slots 0, 1, and 2: */
2639     device_add(machine, "unreadable addr=0x1f400000, len=0x1000"); /* gio0 slot 0 */
2640     device_add(machine, "unreadable addr=0x1f600000, len=0x1000"); /* gio0 slot 1 */
2641     device_add(machine, "unreadable addr=0x1f000000, len=0x1000"); /* gio0 slot 2 */
2642    
2643     break;
2644     case 25:
2645     /* NOTE: Special case for arc_wordlen: */
2646     arc_wordlen = sizeof(uint64_t);
2647     strcat(machine->machine_name, " (Everest IP25)");
2648    
2649     /* serial? irix? */
2650     dev_scc_init(machine, mem,
2651     0x400086000ULL, 0, machine->use_x11, 0, 8);
2652    
2653     /* NOTE: ip19! (perhaps not really the same */
2654     device_add(machine, "sgi_ip19 addr=0x18000000");
2655    
2656     /*
2657     * Memory size, not 4096 byte pages, but 256
2658     * bytes? (16 is size of kernel... approx)
2659     */
2660     store_32bit_word(cpu, 0xa0000000ULL + 0x26d0,
2661     30000); /* (machine->physical_ram_in_mb - 16)
2662     * (1048576 / 256)); */
2663    
2664     break;
2665     case 26:
2666     /* NOTE: Special case for arc_wordlen: */
2667     arc_wordlen = sizeof(uint64_t);
2668     strcat(machine->machine_name,
2669     " (uknown SGI-IP26 ?)"); /* TODO */
2670     machine->main_console_handle =
2671     dev_zs_init(machine, mem, 0x1fbd9830,
2672     0, 1, "zs console");
2673     break;
2674     case 27:
2675     strcat(machine->machine_name,
2676     " (Origin 200/2000, Onyx2)");
2677     arc_wordlen = sizeof(uint64_t);
2678     /* 2 cpus per node */
2679    
2680     machine->main_console_handle =
2681     dev_zs_init(machine, mem, 0x1fbd9830,
2682     0, 1, "zs console");
2683     break;
2684     case 28:
2685     /* NOTE: Special case for arc_wordlen: */
2686     arc_wordlen = sizeof(uint64_t);
2687     strcat(machine->machine_name, " (Impact Indigo2 ?)");
2688    
2689     device_add(machine, "random addr=0x1fbe0000, len=1");
2690    
2691     /* Something at paddr 0x1880fb0000. */
2692    
2693     break;
2694     case 30:
2695     /* NOTE: Special case for arc_wordlen: */
2696     arc_wordlen = sizeof(uint64_t);
2697     strcat(machine->machine_name, " (Octane)");
2698    
2699     machine->sgi_ip30_data = dev_sgi_ip30_init(machine, mem, 0x0ff00000);
2700     machine->md_interrupt = sgi_ip30_interrupt;
2701    
2702     dev_ram_init(mem, 0xa0000000ULL,
2703     128 * 1048576, DEV_RAM_MIRROR, 0x00000000);
2704    
2705     dev_ram_init(mem, 0x80000000ULL,
2706     32 * 1048576, DEV_RAM_RAM, 0x00000000);
2707    
2708     /*
2709     * Something at paddr=1f022004: TODO
2710     * Something at paddr=813f0510 - paddr=813f0570 ?
2711     * Something at paddr=813f04b8
2712     * Something at paddr=f8000003c used by Linux/Octane
2713     *
2714     * 16550 serial port at paddr=1f620178, addr mul 1
2715     * (Error messages are printed to this serial port by the PROM.)
2716     *
2717     * There seems to also be a serial port at 1f620170. The "symmon"
2718     * program dumps something there, but it doesn't look like
2719     * readable text. (TODO)
2720     */
2721     machine->main_console_handle = dev_ns16550_init(machine, mem, 0x1f620170, 0, 1,
2722     machine->use_x11? 0 : 1, "serial 0"); /* TODO: irq? */
2723     dev_ns16550_init(machine, mem, 0x1f620178, 0, 1,
2724     0, "serial 1"); /* TODO: irq? */
2725    
2726     /* MardiGras graphics: */
2727     device_add(machine, "sgi_mardigras addr=0x1c000000");
2728    
2729     break;
2730     case 32:
2731     strcat(machine->machine_name, " (O2)");
2732    
2733     /* TODO: Find out where the physical ram is actually located. */
2734     dev_ram_init(mem, 0x07ffff00ULL, 256, DEV_RAM_MIRROR, 0x03ffff00);
2735     dev_ram_init(mem, 0x10000000ULL, 256, DEV_RAM_MIRROR, 0x00000000);
2736     dev_ram_init(mem, 0x11ffff00ULL, 256, DEV_RAM_MIRROR, 0x01ffff00);
2737     dev_ram_init(mem, 0x12000000ULL, 256, DEV_RAM_MIRROR, 0x02000000);
2738     dev_ram_init(mem, 0x17ffff00ULL, 256, DEV_RAM_MIRROR, 0x03ffff00);
2739     dev_ram_init(mem, 0x20000000ULL, 128 * 1048576, DEV_RAM_MIRROR, 0x00000000);
2740     dev_ram_init(mem, 0x40000000ULL, 128 * 1048576, DEV_RAM_MIRROR, 0x10000000);
2741    
2742     machine->crime_data = dev_crime_init(machine, mem, 0x14000000, 2, machine->use_x11); /* crime0 */
2743     dev_sgi_mte_init(mem, 0x15000000); /* mte ??? memory thing */
2744     dev_sgi_gbe_init(machine, mem, 0x16000000); /* gbe? framebuffer? */
2745    
2746     /*
2747     * A combination of NetBSD and Linux info:
2748     *
2749     * 17000000 vice (Video Image Compression Engine)
2750     * 1f000000 mace
2751     * 1f080000 macepci
2752     * 1f100000 vin1
2753     * 1f180000 vin2
2754     * 1f200000 vout
2755     * 1f280000 enet (mec0, MAC-110 Ethernet)
2756     * 1f300000 perif:
2757     * 1f300000 audio
2758     * 1f310000 isa
2759     * 1f318000 (accessed by Irix' pciio_pio_write64)
2760     * 1f320000 kbdms
2761     * 1f330000 i2c
2762     * 1f340000 ust
2763     * 1f380000 isa ext
2764     * 1f390000 com0 (serial)
2765     * 1f398000 com1 (serial)
2766     * 1f3a0000 mcclock0
2767     */
2768    
2769     machine->mace_data = dev_mace_init(mem, 0x1f310000, 2);
2770     machine->md_interrupt = sgi_ip32_interrupt;
2771    
2772     /*
2773     * IRQ mapping is really ugly. TODO: fix
2774     *
2775     * com0 at mace0 offset 0x390000 intr 4 intrmask 0x3f00000: ns16550a, working fifo
2776     * com1 at mace0 offset 0x398000 intr 4 intrmask 0xfc000000: ns16550a, working fifo
2777     * pckbc0 at mace0 offset 0x320000 intr 5 intrmask 0x0
2778     * mcclock0 at mace0 offset 0x3a0000 intrmask 0x0
2779     * macepci0 at mace0 offset 0x80000 intr 7 intrmask 0x0: rev 1
2780     *
2781     * intr 4 = MACE_PERIPH_SERIAL
2782     * intr 5 = MACE_PERIPH_MISC
2783     * intr 7 = MACE_PCI_BRIDGE
2784     */
2785    
2786     i = dev_pckbc_init(machine, mem, 0x1f320000,
2787     PCKBC_8242, 0x200 + MACE_PERIPH_MISC,
2788     0x800 + MACE_PERIPH_MISC, machine->use_x11);
2789     /* keyb+mouse (mace irq numbers) */
2790    
2791     net_generate_unique_mac(machine, macaddr);
2792     eaddr_string = malloc(30);
2793     if (eaddr_string == NULL) {
2794     fprintf(stderr, "out of memory\n");
2795     exit(1);
2796     }
2797     sprintf(eaddr_string, "eaddr=%02x:%02x:"
2798     "%02x:%02x:%02x:%02x",
2799     macaddr[0], macaddr[1], macaddr[2],
2800     macaddr[3], macaddr[4], macaddr[5]);
2801     dev_sgi_mec_init(machine, mem, 0x1f280000, MACE_ETHERNET, macaddr);
2802    
2803     dev_sgi_ust_init(mem, 0x1f340000); /* ust? */
2804    
2805     j = dev_ns16550_init(machine, mem, 0x1f390000,
2806     (1<<20) + MACE_PERIPH_SERIAL, 0x100,
2807     machine->use_x11? 0 : 1, "serial 0"); /* com0 */
2808     dev_ns16550_init(machine, mem, 0x1f398000,
2809     (1<<26) + MACE_PERIPH_SERIAL, 0x100,
2810     0, "serial 1"); /* com1 */
2811    
2812     if (machine->use_x11)
2813     machine->main_console_handle = i;
2814     else
2815     machine->main_console_handle = j;
2816    
2817     dev_mc146818_init(machine, mem, 0x1f3a0000, (1<<8) + MACE_PERIPH_MISC, MC146818_SGI, 0x40); /* mcclock0 */
2818     dev_zs_init(machine, mem, 0x1fbd9830, 0, 1, "zs console");
2819    
2820     /*
2821     * PCI devices: (according to NetBSD's GENERIC config file for sgimips)
2822     *
2823     * ne* at pci? dev ? function ?
2824     * ahc0 at pci0 dev 1 function ?
2825     * ahc1 at pci0 dev 2 function ?
2826     */
2827    
2828     pci_data = dev_macepci_init(mem, 0x1f080000, MACE_PCI_BRIDGE); /* macepci0 */
2829     /* bus_pci_add(machine, pci_data, mem, 0, 0, 0, pci_ne2000_init, pci_ne2000_rr); TODO */
2830     #if 1
2831     bus_pci_add(machine, pci_data, mem, 0, 1, 0, pci_ahc_init, pci_ahc_rr);
2832     #endif
2833     /* bus_pci_add(machine, pci_data, mem, 0, 2, 0, pci_ahc_init, pci_ahc_rr); */
2834    
2835     break;
2836     case 35:
2837     strcat(machine->machine_name, " (Origin 3000)");
2838     /* 4 cpus per node */
2839    
2840     machine->main_console_handle =
2841     dev_zs_init(machine, mem, 0x1fbd9830,
2842     0, 1, "zs console");
2843     break;
2844     case 53:
2845     strcat(machine->machine_name, " (Origin 350)");
2846     /*
2847     * According to http://kumba.drachentekh.net/xml/myguide.html
2848     * Origin 350, Tezro IP53 R16000
2849     */
2850     break;
2851     default:
2852     fatal("unimplemented SGI machine type IP%i\n",
2853     machine->machine_subtype);
2854     exit(1);
2855     }
2856     } else {
2857     switch (machine->machine_subtype) {
2858    
2859     case MACHINE_ARC_NEC_RD94:
2860     case MACHINE_ARC_NEC_R94:
2861     case MACHINE_ARC_NEC_R96:
2862     /*
2863     * "NEC-RD94" (NEC RISCstation 2250)
2864     * "NEC-R94" (NEC RISCstation 2200)
2865     * "NEC-R96" (NEC Express RISCserver)
2866     *
2867     * http://mirror.aarnet.edu.au/pub/NetBSD/misc/chs/arcdiag.out (NEC-R96)
2868     */
2869    
2870     switch (machine->machine_subtype) {
2871     case MACHINE_ARC_NEC_RD94:
2872     strcat(machine->machine_name, " (NEC-RD94, NEC RISCstation 2250)");
2873     break;
2874     case MACHINE_ARC_NEC_R94:
2875     strcat(machine->machine_name, " (NEC-R94; NEC RISCstation 2200)");
2876     break;
2877     case MACHINE_ARC_NEC_R96:
2878     strcat(machine->machine_name, " (NEC-R96; NEC Express RISCserver)");
2879     break;
2880     }
2881    
2882     /* TODO: interrupt controller! */
2883    
2884     pci_data = device_add(machine,
2885     "rd94 addr=0x80000000, irq=0");
2886    
2887     device_add(machine, "sn addr=0x80001000 irq=0");
2888     dev_mc146818_init(machine, mem, 0x80004000ULL, 0, MC146818_ARC_NEC, 1);
2889     i = dev_pckbc_init(machine, mem, 0x80005000ULL, PCKBC_8042, 0, 0, machine->use_x11);
2890     j = dev_ns16550_init(machine, mem, 0x80006000ULL,
2891     3, 1, machine->use_x11? 0 : 1, "serial 0"); /* com0 */
2892     dev_ns16550_init(machine, mem, 0x80007000ULL,
2893     0, 1, 0, "serial 1"); /* com1 */
2894    
2895     if (machine->use_x11)
2896     machine->main_console_handle = i;
2897     else
2898     machine->main_console_handle = j;
2899    
2900     /* lpt at 0x80008000 */
2901    
2902     device_add(machine, "fdc addr=0x8000c000, irq=0");
2903    
2904     switch (machine->machine_subtype) {
2905     case MACHINE_ARC_NEC_RD94:
2906     case MACHINE_ARC_NEC_R94:
2907     /* PCI devices: (NOTE: bus must be 0, device must be 3, 4, or 5, for NetBSD to accept interrupts) */
2908     bus_pci_add(machine, pci_data, mem, 0, 3, 0, pci_dec21030_init, pci_dec21030_rr); /* tga graphics */
2909     break;
2910     case MACHINE_ARC_NEC_R96:
2911     dev_fb_init(machine, mem, 0x100e00000ULL,
2912     VFB_GENERIC, 640,480, 1024,480,
2913     8, "necvdfrb", 1);
2914     break;
2915     }
2916     break;
2917    
2918     case MACHINE_ARC_NEC_R98:
2919     /*
2920     * "NEC-R98" (NEC RISCserver 4200)
2921     *
2922     * According to http://mail-index.netbsd.org/port-arc/2004/02/01/0001.html:
2923     *
2924     * Network adapter at "start: 0x 0 18600000, length: 0x1000, level: 4, vector: 9"
2925     * Disk at "start: 0x 0 18c103f0, length: 0x1000, level: 5, vector: 6"
2926     * Keyboard at "start: 0x 0 18c20060, length: 0x1000, level: 5, vector: 3"
2927     * Serial at "start: 0x 0 18c103f8, length: 0x1000, level: 5, vector: 4"
2928     * Serial at "start: 0x 0 18c102f8, length: 0x1000, level: 5, vector: 4"
2929     * Parallel at "start: 0x 0 18c10278, length: 0x1000, level: 5, vector: 5"
2930     */
2931    
2932     strcat(machine->machine_name, " (NEC-R98; NEC RISCserver 4200)");
2933    
2934     /*
2935     * Windows NT access stuff at these addresses:
2936     *
2937     * 19980308, 18000210, 18c0a008,
2938     * 19022018, 19026010, andso on.
2939     */
2940     break;
2941    
2942     case MACHINE_ARC_JAZZ_PICA:
2943     case MACHINE_ARC_JAZZ_MAGNUM:
2944     /*
2945     * "PICA-61"
2946     *
2947     * According to NetBSD 1.6.2:
2948     *
2949     * jazzio0 at mainbus0
2950     * timer0 at jazzio0 addr 0xe0000228
2951     * mcclock0 at jazzio0 addr 0xe0004000: mc146818 or compatible
2952     * lpt at jazzio0 addr 0xe0008000 intr 0 not configured
2953     * fdc at jazzio0 addr 0xe0003000 intr 1 not configured
2954     * MAGNUM at jazzio0 addr 0xe000c000 intr 2 not configured
2955     * ALI_S3 at jazzio0 addr 0xe0800000 intr 3 not configured
2956     * sn0 at jazzio0 addr 0xe0001000 intr 4: SONIC Ethernet
2957     * sn0: Ethernet address 69:6a:6b:6c:00:00
2958     * asc0 at jazzio0 addr 0xe0002000 intr 5: NCR53C94, target 0
2959     * pckbd at jazzio0 addr 0xe0005000 intr 6 not configured
2960     * pms at jazzio0 addr 0xe0005000 intr 7 not configured
2961     * com0 at jazzio0 addr 0xe0006000 intr 8: ns16550a, working fifo
2962     * com at jazzio0 addr 0xe0007000 intr 9 not configured
2963     * jazzisabr0 at mainbus0
2964     * isa0 at jazzisabr0 isa_io_base 0xe2000000 isa_mem_base 0xe3000000
2965     *
2966     * "Microsoft-Jazz", "MIPS Magnum"
2967     *
2968     * timer0 at jazzio0 addr 0xe0000228
2969     * mcclock0 at jazzio0 addr 0xe0004000: mc146818 or compatible
2970     * lpt at jazzio0 addr 0xe0008000 intr 0 not configured
2971     * fdc at jazzio0 addr 0xe0003000 intr 1 not configured
2972     * MAGNUM at jazzio0 addr 0xe000c000 intr 2 not configured
2973     * VXL at jazzio0 addr 0xe0800000 intr 3 not configured
2974     * sn0 at jazzio0 addr 0xe0001000 intr 4: SONIC Ethernet
2975     * sn0: Ethernet address 69:6a:6b:6c:00:00
2976     * asc0 at jazzio0 addr 0xe0002000 intr 5: NCR53C94, target 0
2977     * scsibus0 at asc0: 8 targets, 8 luns per target
2978     * pckbd at jazzio0 addr 0xe0005000 intr 6 not configured
2979     * pms at jazzio0 addr 0xe0005000 intr 7 not configured
2980     * com0 at jazzio0 addr 0xe0006000 intr 8: ns16550a, working fifo
2981     * com at jazzio0 addr 0xe0007000 intr 9 not configured
2982     * jazzisabr0 at mainbus0
2983     * isa0 at jazzisabr0 isa_io_base 0xe2000000 isa_mem_base 0xe3000000
2984     */
2985    
2986     switch (machine->machine_subtype) {
2987     case MACHINE_ARC_JAZZ_PICA:
2988     strcat(machine->machine_name, " (Microsoft Jazz, Acer PICA-61)");
2989     break;
2990     case MACHINE_ARC_JAZZ_MAGNUM:
2991     strcat(machine->machine_name, " (Microsoft Jazz, MIPS Magnum)");
2992     break;
2993     default:
2994     fatal("error in machine.c. jazz\n");
2995     exit(1);
2996     }
2997    
2998     machine->jazz_data = device_add(machine,
2999     "jazz addr=0x80000000");
3000     machine->md_interrupt = jazz_interrupt;
3001    
3002     switch (machine->machine_subtype) {
3003     case MACHINE_ARC_JAZZ_PICA:
3004     dev_vga_init(machine, mem,
3005     0x400b8000ULL, 0x600003c0ULL,
3006     ARC_CONSOLE_MAX_X, ARC_CONSOLE_MAX_Y, machine->machine_name);
3007     arcbios_console_init(cpu, 0x400b8000ULL,
3008     0x600003c0ULL, ARC_CONSOLE_MAX_X,
3009     ARC_CONSOLE_MAX_Y);
3010     break;
3011     case MACHINE_ARC_JAZZ_MAGNUM:
3012     /* PROM mirror? */
3013     dev_ram_init(mem, 0xfff00000, 0x100000,
3014     DEV_RAM_MIRROR, 0x1fc00000);
3015    
3016     /* VXL. TODO */
3017     /* control at 0x60100000? */
3018     dev_fb_init(machine, mem, 0x60200000ULL,
3019     VFB_GENERIC, 1024,768, 1024,768,
3020     8, "VXL", 1);
3021     break;
3022     }
3023    
3024     /* irq 8 + 4 */
3025     device_add(machine, "sn addr=0x80001000 irq=12");
3026    
3027     dev_asc_init(machine, mem,
3028     0x80002000ULL, 8 + 5, NULL, DEV_ASC_PICA,
3029     dev_jazz_dma_controller, machine->jazz_data);
3030    
3031     device_add(machine, "fdc addr=0x80003000, irq=0");
3032    
3033     dev_mc146818_init(machine, mem,
3034     0x80004000ULL, 2, MC146818_ARC_JAZZ, 1);
3035    
3036     i = dev_pckbc_init(machine, mem, 0x80005000ULL,
3037     PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11);
3038    
3039     j = dev_ns16550_init(machine, mem,
3040     0x80006000ULL, 8 + 8, 1,
3041     machine->use_x11? 0 : 1, "serial 0");
3042     dev_ns16550_init(machine, mem,
3043     0x80007000ULL, 8 + 9, 1, 0, "serial 1");
3044    
3045     if (machine->use_x11)
3046     machine->main_console_handle = i;
3047     else
3048     machine->main_console_handle = j;
3049    
3050     #if 0
3051     Not yet.
3052     dev_wdc_init(machine, mem, 0x900001f0ULL, 8+16 + 14, 0);
3053     #endif
3054    
3055     break;
3056    
3057     case MACHINE_ARC_JAZZ_M700:
3058     /*
3059     * "Microsoft-Jazz", "Olivetti M700"
3060     *
3061     * Different enough from Pica and Magnum to be
3062     * separate here.
3063     *
3064     * See http://mail-index.netbsd.org/port-arc/2000/10/18/0001.html.
3065     */
3066    
3067     strcat(machine->machine_name, " (Microsoft Jazz, Olivetti M700)");
3068    
3069     machine->jazz_data = device_add(machine,
3070     "jazz addr=0x80000000");
3071     machine->md_interrupt = jazz_interrupt;
3072    
3073     dev_mc146818_init(machine, mem,
3074     0x80004000ULL, 2, MC146818_ARC_JAZZ, 1);
3075    
3076     i = 0; /* TODO: Yuck! */
3077     #if 0
3078     i = dev_pckbc_init(machine, mem, 0x80005000ULL,
3079     PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11);
3080     #endif
3081     j = dev_ns16550_init(machine, mem,
3082     0x80006000ULL, 8 + 8, 1,
3083     machine->use_x11? 0 : 1, "serial 0");
3084     dev_ns16550_init(machine, mem,
3085     0x80007000ULL, 8 + 9, 1, 0, "serial 1");
3086    
3087     if (machine->use_x11)
3088     machine->main_console_handle = i;
3089     else
3090     machine->main_console_handle = j;
3091    
3092     dev_m700_fb_init(machine, mem,
3093     0x180080000ULL, 0x100000000ULL);
3094    
3095     break;
3096    
3097     case MACHINE_ARC_DESKTECH_TYNE:
3098     /*
3099     * "Deskstation Tyne" (?)
3100     *
3101     * TODO
3102     * http://mail-index.netbsd.org/port-arc/2000/10/14/0000.html
3103     */
3104    
3105     strcat(machine->machine_name, " (Deskstation Tyne)");
3106    
3107     dev_vga_init(machine, mem, 0x1000b8000ULL, 0x9000003c0ULL,
3108     ARC_CONSOLE_MAX_X, ARC_CONSOLE_MAX_Y, machine->machine_name);
3109    
3110     arcbios_console_init(cpu, 0x1000b8000ULL,
3111     0x9000003c0ULL, ARC_CONSOLE_MAX_X,
3112     ARC_CONSOLE_MAX_Y);
3113    
3114     i = dev_ns16550_init(machine, mem, 0x9000003f8ULL, 0, 1, machine->use_x11? 0 : 1, "serial 0");
3115     dev_ns16550_init(machine, mem, 0x9000002f8ULL, 0, 1, 0, "serial 1");
3116     dev_ns16550_init(machine, mem, 0x9000003e8ULL, 0, 1, 0, "serial 2");
3117     dev_ns16550_init(machine, mem, 0x9000002e8ULL, 0, 1, 0, "serial 3");
3118    
3119     dev_mc146818_init(machine, mem,
3120     0x900000070ULL, 2, MC146818_PC_CMOS, 1);
3121    
3122     #if 0
3123     dev_wdc_init(machine, mem, 0x9000001f0ULL, 0, 0);
3124     dev_wdc_init(machine, mem, 0x900000170ULL, 0, 2);
3125     #endif
3126     /* PC kbd */
3127     j = dev_pckbc_init(machine, mem, 0x900000060ULL,
3128     PCKBC_8042, 0, 0, machine->use_x11);
3129    
3130     if (machine->use_x11)
3131     machine->main_console_handle = j;
3132     else
3133     machine->main_console_handle = i;
3134    
3135     break;
3136    
3137     default:
3138     fatal("Unimplemented ARC machine type %i\n",
3139     machine->machine_subtype);
3140     exit(1);
3141     }
3142     }
3143    
3144    
3145     if (!machine->prom_emulation)
3146     goto no_arc_prom_emulation; /* TODO: ugly */
3147    
3148    
3149     /*
3150     * This is important: :-)
3151     *
3152     * TODO: There should not be any use of
3153     * ARCBIOS before this statement.
3154     */
3155     if (arc_wordlen == sizeof(uint64_t))
3156     arcbios_set_64bit_mode(1);
3157    
3158     if (machine->physical_ram_in_mb < 16)
3159     fprintf(stderr, "WARNING! The ARC platform specification doesn't allow less than 16 MB of RAM. Continuing anyway.\n");
3160    
3161     arcbios_set_default_exception_handler(cpu);
3162    
3163     memset(&arcbios_sysid, 0, sizeof(arcbios_sysid));
3164     if (machine->machine_type == MACHINE_SGI) {
3165     /* Vendor ID, max 8 chars: */
3166     strncpy(arcbios_sysid.VendorId, "SGI", 3);
3167     switch (machine->machine_subtype) {
3168     case 22:
3169     strncpy(arcbios_sysid.ProductId,
3170     "87654321", 8); /* some kind of ID? */
3171     break;
3172     case 32:
3173     strncpy(arcbios_sysid.ProductId, "8", 1);
3174     /* 6 or 8 (?) */
3175     break;
3176     default:
3177     snprintf(arcbios_sysid.ProductId, 8, "IP%i",
3178     machine->machine_subtype);
3179     }
3180     } else {
3181     switch (machine->machine_subtype) {
3182     case MACHINE_ARC_NEC_RD94:
3183     strncpy(arcbios_sysid.VendorId, "NEC W&S", 8); /* NOTE: max 8 chars */
3184     strncpy(arcbios_sysid.ProductId, "RD94", 4); /* NOTE: max 8 chars */
3185     break;
3186     case MACHINE_ARC_NEC_R94:
3187     strncpy(arcbios_sysid.VendorId, "NEC W&S", 8); /* NOTE: max 8 chars */
3188     strncpy(arcbios_sysid.ProductId, "ijkl", 4); /* NOTE: max 8 chars */
3189     break;
3190     case MACHINE_ARC_NEC_R96:
3191     strncpy(arcbios_sysid.VendorId, "MIPS DUO", 8); /* NOTE: max 8 chars */
3192     strncpy(arcbios_sysid.ProductId, "blahblah", 8); /* NOTE: max 8 chars */
3193     break;
3194     case MACHINE_ARC_NEC_R98:
3195     strncpy(arcbios_sysid.VendorId, "NEC W&S", 8); /* NOTE: max 8 chars */
3196     strncpy(arcbios_sysid.ProductId, "R98", 4); /* NOTE: max 8 chars */
3197     break;
3198     case MACHINE_ARC_JAZZ_PICA:
3199     strncpy(arcbios_sysid.VendorId, "MIPS MAG", 8);/* NOTE: max 8 chars */
3200     strncpy(arcbios_sysid.ProductId, "ijkl", 4); /* NOTE: max 8 chars */
3201     break;
3202     case MACHINE_ARC_JAZZ_MAGNUM:
3203     strncpy(arcbios_sysid.VendorId, "MIPS MAG", 8);/* NOTE: max 8 chars */
3204     strncpy(arcbios_sysid.ProductId, "ijkl", 4); /* NOTE: max 8 chars */
3205     break;
3206     case MACHINE_ARC_JAZZ_M700:
3207     strncpy(arcbios_sysid.VendorId, "OLI00000", 8);/* NOTE: max 8 chars */
3208     strncpy(arcbios_sysid.ProductId, "ijkl", 4); /* NOTE: max 8 chars */
3209     break;
3210     case MACHINE_ARC_DESKTECH_TYNE:
3211     strncpy(arcbios_sysid.VendorId, "DESKTECH", 8);/* NOTE: max 8 chars */
3212     strncpy(arcbios_sysid.ProductId, "ijkl", 4); /* NOTE: max 8 chars */
3213     break;
3214     default:
3215     fatal("error in machine.c sysid\n");
3216     exit(1);
3217     }
3218     }
3219     store_buf(cpu, SGI_SYSID_ADDR, (char *)&arcbios_sysid, sizeof(arcbios_sysid));
3220    
3221     arcbios_get_dsp_stat(cpu, &arcbios_dsp_stat);
3222     store_buf(cpu, ARC_DSPSTAT_ADDR, (char *)&arcbios_dsp_stat, sizeof(arcbios_dsp_stat));
3223    
3224     /*
3225     * The first 12 MBs of RAM are simply reserved... this simplifies things a lot.
3226     * If there's more than 512MB of RAM, it has to be split in two, according to
3227     * the ARC spec. This code creates a number of chunks of at most 512MB each.
3228     *
3229     * NOTE: The region of physical address space between 0x10000000 and 0x1fffffff
3230     * (256 - 512 MB) is usually occupied by memory mapped devices, so that portion is "lost".
3231     */
3232    
3233     arc_reserved = 0x2000;
3234     if (machine->machine_type == MACHINE_SGI)
3235     arc_reserved = 0x4000;
3236    
3237     arcbios_add_memory_descriptor(cpu, 0, arc_reserved, ARCBIOS_MEM_FirmwarePermanent);
3238     arcbios_add_memory_descriptor(cpu, sgi_ram_offset + arc_reserved, 0x60000-arc_reserved, ARCBIOS_MEM_FirmwareTemporary);
3239    
3240     mem_base = 12;
3241     mem_base += sgi_ram_offset / 1048576;
3242    
3243     while (mem_base < machine->physical_ram_in_mb + sgi_ram_offset/1048576) {
3244     mem_count = machine->physical_ram_in_mb + sgi_ram_offset/1048576
3245     - mem_base;
3246    
3247     /* Skip the 256-512MB region (for devices) */
3248     if (mem_base < 256 && mem_base + mem_count > 256) {
3249     mem_count = 256-mem_base;
3250     }
3251    
3252     /* At most 512MB per descriptor (at least the first 512MB
3253     must be separated this way, according to the ARC spec) */
3254     if (mem_count > 512)
3255     mem_count = 512;
3256    
3257     arcbios_add_memory_descriptor(cpu, mem_base * 1048576,
3258     mem_count * 1048576, ARCBIOS_MEM_FreeMemory);
3259    
3260     mem_base += mem_count;
3261    
3262     /* Skip the devices: */
3263     if (mem_base == 256)
3264     mem_base = 512;
3265     }
3266    
3267    
3268     /*
3269     * Components: (this is an example of what a system could look like)
3270     *
3271     * [System]
3272     * [CPU] (one for each cpu)
3273     * [FPU] (one for each cpu)
3274     * [CPU Caches]
3275     * [Memory]
3276     * [Ethernet]
3277     * [Serial]
3278     * [SCSI]
3279     * [Disk]
3280     *
3281     * Here's a good list of what hardware is in different IP-models:
3282     * http://www.linux-mips.org/archives/linux-mips/2001-03/msg00101.html
3283     */
3284    
3285     if (machine->machine_name == NULL)
3286     fatal("ERROR: machine_name == NULL\n");
3287     if (short_machine_name == NULL)
3288     fatal("ERROR: short_machine_name == NULL\n");
3289    
3290     switch (machine->machine_type) {
3291     case MACHINE_SGI:
3292     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3293     0, 1, 2, 0, 0xffffffff, short_machine_name, 0 /* ROOT */ , NULL, 0);
3294     break;
3295     default:
3296     /* ARC: */
3297     switch (machine->machine_subtype) {
3298     case MACHINE_ARC_NEC_RD94:
3299     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3300     0, 1, 2, 0, 0xffffffff, "NEC-RD94", 0 /* ROOT */ , NULL, 0);
3301     break;
3302     case MACHINE_ARC_NEC_R94:
3303     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3304     0, 1, 2, 0, 0xffffffff, "NEC-R94", 0 /* ROOT */ , NULL, 0);
3305     break;
3306     case MACHINE_ARC_NEC_R96:
3307     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3308     0, 1, 2, 0, 0xffffffff, "NEC-R96", 0 /* ROOT */ , NULL, 0);
3309     break;
3310     case MACHINE_ARC_NEC_R98:
3311     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3312     0, 1, 2, 0, 0xffffffff, "NEC-R98", 0 /* ROOT */ , NULL, 0);
3313     break;
3314     case MACHINE_ARC_JAZZ_PICA:
3315     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3316     0, 1, 2, 0, 0xffffffff, "PICA-61", 0 /* ROOT */ , NULL, 0);
3317     break;
3318     case MACHINE_ARC_JAZZ_MAGNUM:
3319     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3320     0, 1, 2, 0, 0xffffffff, "Microsoft-Jazz", 0 /* ROOT */ , NULL, 0);
3321     break;
3322     case MACHINE_ARC_JAZZ_M700:
3323     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3324     0, 1, 2, 0, 0xffffffff, "Microsoft-Jazz", 0 /* ROOT */ , NULL, 0);
3325     break;
3326     case MACHINE_ARC_DESKTECH_TYNE:
3327     system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC,
3328     0, 1, 2, 0, 0xffffffff, "DESKTECH-TYNE", 0 /* ROOT */ , NULL, 0);
3329     break;
3330     default:
3331     fatal("Unimplemented ARC machine type %i\n",
3332     machine->machine_subtype);
3333     exit(1);
3334     }
3335     }
3336    
3337    
3338     /*
3339     * Common stuff for both SGI and ARC:
3340     */
3341     debug("ARC system @ 0x%llx\n", (long long)system);
3342    
3343     for (i=0; i<machine->ncpus; i++) {
3344     uint64_t cpuaddr, fpu=0, picache, pdcache, sdcache=0;
3345     int cache_size, cache_line_size;
3346     unsigned int jj;
3347     char arc_cpu_name[100];
3348     char arc_fpc_name[105];
3349    
3350     snprintf(arc_cpu_name, sizeof(arc_cpu_name),
3351     "MIPS-%s", machine->cpu_name);
3352    
3353     if (machine->machine_type == MACHINE_ARC &&
3354     machine->machine_subtype == MACHINE_ARC_NEC_R96)
3355     snprintf(arc_cpu_name, sizeof(arc_cpu_name),
3356     "MIPS-%s - Pr 4/5.0, Fp 5/0",
3357     machine->cpu_name);
3358    
3359     arc_cpu_name[sizeof(arc_cpu_name)-1] = 0;
3360     for (jj=0; jj<strlen(arc_cpu_name); jj++)
3361     if (arc_cpu_name[jj] >= 'a' && arc_cpu_name[jj] <= 'z')
3362     arc_cpu_name[jj] += ('A' - 'a');
3363    
3364     strcpy(arc_fpc_name, arc_cpu_name);
3365     strcat(arc_fpc_name, "FPC");
3366    
3367     cpuaddr = arcbios_addchild_manual(cpu, COMPONENT_CLASS_ProcessorClass, COMPONENT_TYPE_CPU,
3368     0, 1, 2, i, 0xffffffff, arc_cpu_name, system, NULL, 0);
3369    
3370     /*
3371     * TODO: This was in the ARC specs, but it isn't
3372     * really used by ARC implementations?
3373     * At least SGI-IP32 uses it.
3374     */
3375     if (machine->machine_type == MACHINE_SGI)
3376     fpu = arcbios_addchild_manual(cpu, COMPONENT_CLASS_ProcessorClass, COMPONENT_TYPE_FPU,
3377     0, 1, 2, 0, 0xffffffff, arc_fpc_name, cpuaddr, NULL, 0);
3378    
3379     cache_size = DEFAULT_PCACHE_SIZE - 12;
3380     if (machine->cache_picache)
3381     cache_size = machine->cache_picache - 12;
3382     if (cache_size < 0)
3383     cache_size = 0;
3384    
3385     cache_line_size = DEFAULT_PCACHE_LINESIZE;
3386     if (machine->cache_picache_linesize)
3387     cache_line_size = machine->cache_picache_linesize;
3388     if (cache_line_size < 0)
3389     cache_line_size = 0;
3390    
3391     picache = arcbios_addchild_manual(cpu, COMPONENT_CLASS_CacheClass,
3392     COMPONENT_TYPE_PrimaryICache, 0, 1, 2,
3393     /*
3394     * Key bits: 0xXXYYZZZZ
3395     * XX is refill-size.
3396     * Cache line size is 1 << YY,
3397     * Cache size is 4KB << ZZZZ.
3398     */
3399     0x01000000 + (cache_line_size << 16) + cache_size,
3400     /* 32 bytes per line, default = 32 KB total */
3401     0xffffffff, NULL, cpuaddr, NULL, 0);
3402    
3403     cache_size = DEFAULT_PCACHE_SIZE - 12;
3404     if (machine->cache_pdcache)
3405     cache_size = machine->cache_pdcache - 12;
3406     if (cache_size < 0)
3407     cache_size = 0;
3408    
3409     cache_line_size = DEFAULT_PCACHE_LINESIZE;
3410     if (machine->cache_pdcache_linesize)
3411     cache_line_size = machine->cache_pdcache_linesize;
3412     if (cache_line_size < 0)
3413     cache_line_size = 0;
3414    
3415     pdcache = arcbios_addchild_manual(cpu, COMPONENT_CLASS_CacheClass,
3416     COMPONENT_TYPE_PrimaryDCache, 0, 1, 2,
3417     /*
3418     * Key bits: 0xYYZZZZ
3419     * Cache line size is 1 << YY,
3420     * Cache size is 4KB << ZZZZ.
3421     */
3422     0x01000000 + (cache_line_size << 16) + cache_size,
3423     /* 32 bytes per line, default = 32 KB total */
3424     0xffffffff, NULL, cpuaddr, NULL, 0);
3425    
3426     if (machine->cache_secondary >= 12) {
3427     cache_size = machine->cache_secondary - 12;
3428    
3429     cache_line_size = 6; /* 64 bytes default */
3430     if (machine->cache_secondary_linesize)
3431     cache_line_size = machine->cache_secondary_linesize;
3432     if (cache_line_size < 0)
3433     cache_line_size = 0;
3434    
3435     sdcache = arcbios_addchild_manual(cpu, COMPONENT_CLASS_CacheClass,
3436     COMPONENT_TYPE_SecondaryDCache, 0, 1, 2,
3437     /*
3438     * Key bits: 0xYYZZZZ
3439     * Cache line size is 1 << YY,
3440     * Cache size is 4KB << ZZZZ.
3441     */
3442     0x01000000 + (cache_line_size << 16) + cache_size,
3443     /* 64 bytes per line, default = 1 MB total */
3444     0xffffffff, NULL, cpuaddr, NULL, 0);
3445     }
3446    
3447     debug("ARC cpu%i @ 0x%llx", i, (long long)cpuaddr);
3448    
3449     if (fpu != 0)
3450     debug(" (fpu @ 0x%llx)\n", (long long)fpu);
3451     else
3452     debug("\n");
3453    
3454     debug(" picache @ 0x%llx, pdcache @ 0x%llx\n",
3455     (long long)picache, (long long)pdcache);
3456    
3457     if (machine->cache_secondary >= 12)
3458     debug(" sdcache @ 0x%llx\n",
3459     (long long)sdcache);
3460    
3461     if (machine->machine_type == MACHINE_SGI) {
3462     /* TODO: Memory amount (and base address?)! */
3463     uint64_t memory = arcbios_addchild_manual(cpu, COMPONENT_CLASS_MemoryClass,
3464     COMPONENT_TYPE_MemoryUnit,
3465     0, 1, 2, 0, 0xffffffff, "memory", cpuaddr, NULL, 0);
3466     debug(" memory @ 0x%llx\n", (long long)memory);
3467     }
3468     }
3469    
3470    
3471     /*
3472     * Other components, and default TLB entries:
3473     *
3474     * TODO: How to build the component tree intermixed with
3475     * the rest of device initialization?
3476     */
3477    
3478     if (machine->machine_type == MACHINE_SGI) {
3479     /* TODO: On which models is this required? */
3480     mips_coproc_tlb_set_entry(cpu, 0, 1048576*16,
3481     0xc000000000000000ULL,
3482     0x0, 1048576*16,
3483     1, 1, 1, 1, 1, 0, 2, 2);
3484     }
3485    
3486     if (machine->machine_type == MACHINE_ARC &&
3487     ( machine->machine_subtype == MACHINE_ARC_NEC_RD94 ||
3488     machine->machine_subtype == MACHINE_ARC_NEC_R94 ||
3489     machine->machine_subtype == MACHINE_ARC_NEC_R96 )) {
3490     uint64_t jazzbus, eisa, other;
3491    
3492     jazzbus = arcbios_addchild_manual(cpu,
3493     COMPONENT_CLASS_AdapterClass,
3494     COMPONENT_TYPE_MultiFunctionAdapter,
3495     0, 1, 2, 0, 0xffffffff, "Jazz-Internal Bus",
3496     system, NULL, 0);
3497    
3498     switch (machine->machine_subtype) {
3499     case MACHINE_ARC_NEC_RD94:
3500     case MACHINE_ARC_NEC_R94:
3501     if (machine->use_x11)
3502     arcbios_addchild_manual(cpu,
3503     COMPONENT_CLASS_ControllerClass,
3504     COMPONENT_TYPE_DisplayController,
3505     0, 1, 2, 0, 0x0, "10110004",
3506     system, NULL, 0);
3507     break;
3508     case MACHINE_ARC_NEC_R96:
3509     if (machine->use_x11) {
3510     uint64_t x;
3511     x = arcbios_addchild_manual(cpu,
3512     COMPONENT_CLASS_ControllerClass,
3513     COMPONENT_TYPE_DisplayController,
3514     COMPONENT_FLAG_ConsoleOut |
3515     COMPONENT_FLAG_Output,
3516     1, 2, 0, 0x0, "necvdfrb",
3517     jazzbus, NULL, 0);
3518     arcbios_addchild_manual(cpu,
3519     COMPONENT_CLASS_PeripheralClass,
3520     COMPONENT_TYPE_MonitorPeripheral,
3521     COMPONENT_FLAG_ConsoleOut |
3522     COMPONENT_FLAG_Output,
3523     1, 2, 0, 0xffffffff, "640x480",
3524     x, NULL, 0);
3525     }
3526    
3527     /* TODO: R[D]94 too? */
3528     eisa = arcbios_addchild_manual(cpu,
3529     COMPONENT_CLASS_AdapterClass,
3530     COMPONENT_TYPE_EISAAdapter,
3531     0, 1, 2, 0, 0xffffffff, "EISA",
3532     system, NULL, 0);
3533    
3534     other = arcbios_addchild_manual(cpu,
3535     COMPONENT_CLASS_ControllerClass,
3536     COMPONENT_TYPE_OtherController,
3537     0, 1, 2, 0, 0xffffffff, "NEC1C01",
3538     eisa, NULL, 0);
3539    
3540     break;
3541     }
3542     }
3543    
3544     if (machine->machine_type == MACHINE_ARC &&
3545     (machine->machine_subtype == MACHINE_ARC_JAZZ_PICA
3546     || machine->machine_subtype == MACHINE_ARC_JAZZ_MAGNUM)) {
3547     uint64_t jazzbus, ali_s3, vxl;
3548     uint64_t diskcontroller, floppy, kbdctl, kbd;
3549     uint64_t ptrctl, ptr, paral, audio;
3550     uint64_t eisa, scsi;
3551     /* uint64_t serial1, serial2; */
3552    
3553     jazzbus = arcbios_addchild_manual(cpu,
3554     COMPONENT_CLASS_AdapterClass,
3555     COMPONENT_TYPE_MultiFunctionAdapter,
3556     0, 1, 2, 0, 0xffffffff, "Jazz-Internal Bus",
3557     system, NULL, 0);
3558    
3559     /*
3560     * DisplayController, needed by NetBSD:
3561     * TODO: NetBSD still doesn't use it :(
3562     */
3563     switch (machine->machine_subtype) {
3564     case MACHINE_ARC_JAZZ_PICA:
3565     /* Default TLB entries on PICA-61: */
3566    
3567     /* 7: 256K, asid: 0x0, v: 0xe1000000,
3568     p0: 0xfff00000(2.VG), p1: 0x0(0..G) */
3569     mips_coproc_tlb_set_entry(cpu, 7, 262144,
3570     0xffffffffe1000000ULL,
3571     0x0fff00000ULL, 0,
3572     1, 0, 0, 0, 1, 0, 2, 0);
3573    
3574     /* 8: 64K, asid: 0x0, v: 0xe0000000,
3575     p0: 0x80000000(2DVG), p1: 0x0(0..G) */
3576     mips_coproc_tlb_set_entry(cpu, 8, 65536,
3577     0xffffffffe0000000ULL,
3578     0x080000000ULL, 0,
3579     1, 0, 1, 0, 1, 0, 2, 0);
3580    
3581     /* 9: 64K, asid: 0x0, v: 0xe00e0000,
3582     p0: 0x800e0000(2DVG), p1: 0x800f0000(2DVG) */
3583     mips_coproc_tlb_set_entry(cpu, 9, 65536,
3584     (uint64_t)0xffffffffe00e0000ULL,
3585     (uint64_t)0x0800e0000ULL,
3586     (uint64_t)0x0800f0000ULL,
3587     1, 1, 1, 1, 1, 0, 2, 2);
3588    
3589     /* 10: 4K, asid: 0x0, v: 0xe0100000,
3590     p0: 0xf0000000(2DVG), p1: 0x0(0..G) */
3591     mips_coproc_tlb_set_entry(cpu, 10, 4096,
3592     (uint64_t)0xffffffffe0100000ULL,
3593     (uint64_t)0x0f0000000ULL, 0,
3594     1, 0, 1, 0, 1, 0, 2, 0);
3595    
3596     /* 11: 1M, asid: 0x0, v: 0xe0200000,
3597     p0: 0x60000000(2DVG), p1: 0x60100000(2DVG) */
3598     mips_coproc_tlb_set_entry(cpu, 11, 1048576,
3599     0xffffffffe0200000ULL,
3600     0x060000000ULL, 0x060100000ULL,
3601     1, 1, 1, 1, 1, 0, 2, 2);
3602    
3603     /* 12: 1M, asid: 0x0, v: 0xe0400000,
3604     p0: 0x60200000(2DVG), p1: 0x60300000(2DVG) */
3605     mips_coproc_tlb_set_entry(cpu, 12, 1048576,
3606     0xffffffffe0400000ULL,
3607     0x060200000ULL, 0x060300000ULL,
3608     1, 1, 1, 1, 1, 0, 2, 2);
3609    
3610     /* 13: 4M, asid: 0x0, v: 0xe0800000,
3611     p0: 0x40000000(2DVG), p1: 0x40400000(2DVG) */
3612     mips_coproc_tlb_set_entry(cpu, 13, 1048576*4,
3613     0xffffffffe0800000ULL,
3614     0x040000000ULL, 0x040400000ULL,
3615     1, 1, 1, 1, 1, 0, 2, 2);
3616    
3617     /* 14: 16M, asid: 0x0, v: 0xe2000000,
3618     p0: 0x90000000(2DVG), p1: 0x91000000(2DVG) */
3619     mips_coproc_tlb_set_entry(cpu, 14, 1048576*16,
3620     0xffffffffe2000000ULL,
3621     0x090000000ULL, 0x091000000ULL,
3622     1, 1, 1, 1, 1, 0, 2, 2);
3623    
3624     if (machine->use_x11) {
3625     ali_s3 = arcbios_addchild_manual(cpu,
3626     COMPONENT_CLASS_ControllerClass,
3627     COMPONENT_TYPE_DisplayController,
3628     COMPONENT_FLAG_ConsoleOut |
3629     COMPONENT_FLAG_Output,
3630     1, 2, 0, 0xffffffff, "ALI_S3",
3631     jazzbus, NULL, 0);
3632    
3633     arcbios_addchild_manual(cpu,
3634     COMPONENT_CLASS_PeripheralClass,
3635     COMPONENT_TYPE_MonitorPeripheral,
3636     COMPONENT_FLAG_ConsoleOut |
3637     COMPONENT_FLAG_Output,
3638     1, 2, 0, 0xffffffff, "1024x768",
3639     ali_s3, NULL, 0);
3640     }
3641     break;
3642     case MACHINE_ARC_JAZZ_MAGNUM:
3643     if (machine->use_x11) {
3644     vxl = arcbios_addchild_manual(cpu,
3645     COMPONENT_CLASS_ControllerClass,
3646     COMPONENT_TYPE_DisplayController,
3647     COMPONENT_FLAG_ConsoleOut |
3648     COMPONENT_FLAG_Output,
3649     1, 2, 0, 0xffffffff, "VXL",
3650     jazzbus, NULL, 0);
3651    
3652     arcbios_addchild_manual(cpu,
3653     COMPONENT_CLASS_PeripheralClass,
3654     COMPONENT_TYPE_MonitorPeripheral,
3655     COMPONENT_FLAG_ConsoleOut |
3656     COMPONENT_FLAG_Output,
3657     1, 2, 0, 0xffffffff, "1024x768",
3658     vxl, NULL, 0);
3659     }
3660     break;
3661     }
3662    
3663     diskcontroller = arcbios_addchild_manual(cpu,
3664     COMPONENT_CLASS_ControllerClass,
3665     COMPONENT_TYPE_DiskController,
3666     COMPONENT_FLAG_Input |
3667     COMPONENT_FLAG_Output,
3668     1, 2, 0, 0xffffffff, "I82077",
3669     jazzbus, NULL, 0);
3670    
3671     floppy = arcbios_addchild_manual(cpu,
3672     COMPONENT_CLASS_PeripheralClass,
3673     COMPONENT_TYPE_FloppyDiskPeripheral,
3674     COMPONENT_FLAG_Removable |
3675     COMPONENT_FLAG_Input |
3676     COMPONENT_FLAG_Output,
3677     1, 2, 0, 0xffffffff, NULL,
3678     diskcontroller, NULL, 0);
3679    
3680     kbdctl = arcbios_addchild_manual(cpu,
3681     COMPONENT_CLASS_ControllerClass,
3682     COMPONENT_TYPE_KeyboardController,
3683     COMPONENT_FLAG_ConsoleIn |
3684     COMPONENT_FLAG_Input,
3685     1, 2, 0, 0xffffffff, "I8742",
3686     jazzbus, NULL, 0);
3687    
3688     kbd = arcbios_addchild_manual(cpu,
3689     COMPONENT_CLASS_PeripheralClass,
3690     COMPONENT_TYPE_KeyboardPeripheral,
3691     COMPONENT_FLAG_ConsoleIn |
3692     COMPONENT_FLAG_Input,
3693     1, 2, 0, 0xffffffff, "PCAT_ENHANCED",
3694     kbdctl, NULL, 0);
3695    
3696     ptrctl = arcbios_addchild_manual(cpu,
3697     COMPONENT_CLASS_ControllerClass,
3698     COMPONENT_TYPE_PointerController,
3699     COMPONENT_FLAG_Input,
3700     1, 2, 0, 0xffffffff, "I8742",
3701     jazzbus, NULL, 0);
3702    
3703     ptr = arcbios_addchild_manual(cpu,
3704     COMPONENT_CLASS_PeripheralClass,
3705     COMPONENT_TYPE_PointerPeripheral,
3706     COMPONENT_FLAG_Input,
3707     1, 2, 0, 0xffffffff, "PS2 MOUSE",
3708     ptrctl, NULL, 0);
3709    
3710     /* These cause Windows NT to bug out. */
3711     #if 0
3712     serial1 = arcbios_addchild_manual(cpu,
3713     COMPONENT_CLASS_ControllerClass,
3714     COMPONENT_TYPE_SerialController,
3715     COMPONENT_FLAG_Input |
3716     COMPONENT_FLAG_Output,
3717     1, 2, 0, 0xffffffff, "COM1",
3718     jazzbus, NULL, 0);
3719    
3720     serial2 = arcbios_addchild_manual(cpu,
3721     COMPONENT_CLASS_ControllerClass,
3722     COMPONENT_TYPE_SerialController,
3723     COMPONENT_FLAG_Input |
3724     COMPONENT_FLAG_Output,
3725     1, 2, 0, 0xffffffff, "COM1",
3726     jazzbus, NULL, 0);
3727     #endif
3728    
3729     paral = arcbios_addchild_manual(cpu,
3730     COMPONENT_CLASS_ControllerClass,
3731     COMPONENT_TYPE_ParallelController,
3732     COMPONENT_FLAG_Input |
3733     COMPONENT_FLAG_Output,
3734     1, 2, 0, 0xffffffff, "LPT1",
3735     jazzbus, NULL, 0);
3736    
3737     audio = arcbios_addchild_manual(cpu,
3738     COMPONENT_CLASS_ControllerClass,
3739     COMPONENT_TYPE_AudioController,
3740     COMPONENT_FLAG_Input |
3741     COMPONENT_FLAG_Output,
3742     1, 2, 0, 0xffffffff, "MAGNUM",
3743     jazzbus, NULL, 0);
3744    
3745     eisa = arcbios_addchild_manual(cpu,
3746     COMPONENT_CLASS_AdapterClass,
3747     COMPONENT_TYPE_EISAAdapter,
3748     0, 1, 2, 0, 0xffffffff, "EISA",
3749     system, NULL, 0);
3750    
3751     {
3752     unsigned char config[78];
3753     memset(config, 0, sizeof(config));
3754    
3755     /* config data version: 1, revision: 2, count: 4 */
3756     config[0] = 0x01; config[1] = 0x00;
3757     config[2] = 0x02; config[3] = 0x00;
3758     config[4] = 0x04; config[5] = 0x00; config[6] = 0x00; config[7] = 0x00;
3759    
3760     /*
3761     type: Interrupt
3762     share_disposition: DeviceExclusive, flags: LevelSensitive
3763     level: 4, vector: 22, reserved1: 0
3764     */
3765     config[8] = arc_CmResourceTypeInterrupt;
3766     config[9] = arc_CmResourceShareDeviceExclusive;
3767     config[10] = arc_CmResourceInterruptLevelSensitive;
3768     config[12] = 4;
3769     config[16] = 22;
3770     config[20] = 0;
3771    
3772     /*
3773     type: Memory
3774     share_disposition: DeviceExclusive, flags: ReadWrite
3775     start: 0x 0 80002000, length: 0x1000
3776     */
3777     config[24] = arc_CmResourceTypeMemory;
3778     config[25] = arc_CmResourceShareDeviceExclusive;
3779     config[26] = arc_CmResourceMemoryReadWrite;
3780     config[28] = 0x00; config[29] = 0x20; config[30] = 0x00; config[31] = 0x80;
3781     config[32] = 0x00; config[33] = 0x00; config[34] = 0x00; config[35] = 0x00;
3782     config[36] = 0x00; config[37] = 0x10; config[38] = 0x00; config[39] = 0x00;
3783    
3784     /*
3785     type: DMA
3786     share_disposition: DeviceExclusive, flags: 0x0
3787     channel: 0, port: 0, reserved1: 0
3788     */
3789     config[40] = arc_CmResourceTypeDMA;
3790     config[41] = arc_CmResourceShareDeviceExclusive;
3791     /* 42..43 = flags, 44,45,46,47 = channel, 48,49,50,51 = port, 52,53,54,55 = reserved */
3792    
3793     /* type: DeviceSpecific
3794     share_disposition: DeviceExclusive, flags: 0x0
3795     datasize: 6, reserved1: 0, reserved2: 0
3796     data: [0x1:0x0:0x2:0x0:0x7:0x30]
3797     */
3798     config[56] = arc_CmResourceTypeDeviceSpecific;
3799     config[57] = arc_CmResourceShareDeviceExclusive;
3800     /* 58,59 = flags 60,61,62,63 = data size, 64..71 = reserved */
3801     config[60] = 6;
3802     /* 72..77 = the data */
3803     config[72] = 0x01;
3804     config[73] = 0x00;
3805     config[74] = 0x02;
3806     config[75] = 0x00;
3807     config[76] = 0x07;
3808     config[77] = 0x30;
3809     scsi = arcbios_addchild_manual(cpu,
3810     COMPONENT_CLASS_AdapterClass,
3811     COMPONENT_TYPE_SCSIAdapter,
3812     0, 1, 2, 0, 0xffffffff, "ESP216",
3813     system, config, sizeof(config));
3814    
3815     arcbios_register_scsicontroller(scsi);
3816     }
3817    
3818     }
3819    
3820    
3821     add_symbol_name(&machine->symbol_context,
3822     ARC_FIRMWARE_ENTRIES, 0x10000, "[ARCBIOS entry]", 0);
3823    
3824     switch (arc_wordlen) {
3825     case sizeof(uint64_t):
3826     for (i=0; i<100; i++)
3827     store_64bit_word(cpu, ARC_FIRMWARE_VECTORS + i*8,
3828     ARC_FIRMWARE_ENTRIES + i*8);
3829     for (i=0; i<100; i++)
3830     store_64bit_word(cpu, ARC_PRIVATE_VECTORS + i*8,
3831     ARC_PRIVATE_ENTRIES + i*8);
3832     break;
3833     default:
3834     for (i=0; i<100; i++)
3835     store_32bit_word(cpu, ARC_FIRMWARE_VECTORS + i*4,
3836     ARC_FIRMWARE_ENTRIES + i*4);
3837     for (i=0; i<100; i++)
3838     store_32bit_word(cpu, ARC_PRIVATE_VECTORS + i*4,
3839     ARC_PRIVATE_ENTRIES + i*4);
3840     }
3841    
3842     switch (arc_wordlen) {
3843     case sizeof(uint64_t):
3844     /*
3845     * ARCS64 SPD (TODO: This is just a guess)
3846     */
3847     memset(&arcbios_spb_64, 0, sizeof(arcbios_spb_64));
3848     store_64bit_word_in_host(cpu, (unsigned char *)&arcbios_spb_64.SPBSignature, ARCBIOS_SPB_SIGNATURE);
3849     store_16bit_word_in_host(cpu, (unsigned char *)&arcbios_spb_64.Version, 64);
3850     store_16bit_word_in_host(cpu, (unsigned char *)&arcbios_spb_64.Revision, 0);
3851     store_64bit_word_in_host(cpu, (unsigned char *)&arcbios_spb_64.FirmwareVector, ARC_FIRMWARE_VECTORS);
3852     store_buf(cpu, SGI_SPB_ADDR, (char *)&arcbios_spb_64, sizeof(arcbios_spb_64));
3853     break;
3854     default: /* 32-bit */
3855     /*
3856     * ARCBIOS SPB: (For ARC and 32-bit SGI modes)
3857     */
3858     memset(&arcbios_spb, 0, sizeof(arcbios_spb));
3859     store_32bit_word_in_host(cpu, (unsigned char *)&arcbios_spb.SPBSignature, ARCBIOS_SPB_SIGNATURE);
3860     store_32bit_word_in_host(cpu, (unsigned char *)&arcbios_spb.SPBLength, sizeof(arcbios_spb));
3861     store_16bit_word_in_host(cpu, (unsigned char *)&arcbios_spb.Version, 1);
3862     store_16bit_word_in_host(cpu, (unsigned char *)&arcbios_spb.Revision, machine->machine_type == MACHINE_SGI? 10 : 2);
3863     store_32bit_word_in_host(cpu, (unsigned char *)&arcbios_spb.FirmwareVector, ARC_FIRMWARE_VECTORS);
3864     store_32bit_word_in_host(cpu, (unsigned char *)&arcbios_spb.FirmwareVectorLength, 100 * 4); /* ? */
3865     store_32bit_word_in_host(cpu, (unsigned char *)&arcbios_spb.PrivateVector, ARC_PRIVATE_VECTORS);
3866     store_32bit_word_in_host(cpu, (unsigned char *)&arcbios_spb.PrivateVectorLength, 100 * 4); /* ? */
3867     store_buf(cpu, SGI_SPB_ADDR, (char *)&arcbios_spb, sizeof(arcbios_spb));
3868     }
3869    
3870     /*
3871     * Boot string in ARC format:
3872     *
3873     * TODO: How about floppies? multi()disk()fdisk()
3874     * Is tftp() good for netbooting?
3875     */
3876     init_bootpath = malloc(500);
3877     if (init_bootpath == NULL) {
3878     fprintf(stderr, "out of mem, bootpath\n");
3879     exit(1);
3880     }
3881     init_bootpath[0] = '\0';
3882    
3883     if (bootdev_id < 0 || machine->force_netboot) {
3884     snprintf(init_bootpath, 400, "tftp()");
3885     } else {
3886     /* TODO: Make this nicer. */
3887     if (machine->machine_type == MACHINE_SGI) {
3888     if (machine->machine_subtype == 30)
3889     strcat(init_bootpath, "xio(0)pci(15)");
3890     if (machine->machine_subtype == 32)
3891     strcat(init_bootpath, "pci(0)");
3892     }
3893    
3894     if (diskimage_is_a_cdrom(machine, bootdev_id))
3895     snprintf(init_bootpath + strlen(init_bootpath), 400,
3896     "scsi(0)cdrom(%i)fdisk(0)", bootdev_id);
3897     else
3898     snprintf(init_bootpath + strlen(init_bootpath), 400,
3899     "scsi(0)disk(%i)rdisk(0)partition(1)", bootdev_id);
3900     }
3901    
3902     if (machine->machine_type == MACHINE_ARC)
3903     strcat(init_bootpath, "\\");
3904    
3905     bootstr = malloc(strlen(init_bootpath) +
3906     strlen(machine->boot_kernel_filename) + 1);
3907     strcpy(bootstr, init_bootpath);
3908     strcat(bootstr, machine->boot_kernel_filename);
3909    
3910     /* Boot args., eg "-a" */
3911     bootarg = machine->boot_string_argument;
3912    
3913     /* argc, argv, envp in a0, a1, a2: */
3914     cpu->cd.mips.gpr[MIPS_GPR_A0] = 0; /* note: argc is increased later */
3915    
3916     /* TODO: not needed? */
3917     cpu->cd.mips.gpr[MIPS_GPR_SP] = machine->physical_ram_in_mb * 1048576 + 0x80000000 - 0x2080;
3918    
3919     /* Set up argc/argv: */
3920     addr = ARC_ENV_STRINGS;
3921     addr2 = ARC_ARGV_START;
3922     cpu->cd.mips.gpr[MIPS_GPR_A1] = addr2;
3923    
3924     /* bootstr: */
3925     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3926     add_environment_string(cpu, bootstr, &addr);
3927     cpu->cd.mips.gpr[MIPS_GPR_A0] ++;
3928    
3929     /* bootarg: */
3930     if (bootarg[0] != '\0') {
3931     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3932     add_environment_string(cpu, bootarg, &addr);
3933     cpu->cd.mips.gpr[MIPS_GPR_A0] ++;
3934     }
3935    
3936     cpu->cd.mips.gpr[MIPS_GPR_A2] = addr2;
3937    
3938     /*
3939     * Add environment variables. For each variable, add it
3940     * as a string using add_environment_string(), and add a
3941     * pointer to it to the ARC_ENV_POINTERS array.
3942     */
3943     if (machine->use_x11) {
3944     if (machine->machine_type == MACHINE_ARC) {
3945     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3946     add_environment_string(cpu, "CONSOLEIN=multi()key()keyboard()console()", &addr);
3947     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3948     add_environment_string(cpu, "CONSOLEOUT=multi()video()monitor()console()", &addr);
3949     } else {
3950     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3951     add_environment_string(cpu, "ConsoleIn=keyboard()", &addr);
3952     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3953     add_environment_string(cpu, "ConsoleOut=video()", &addr);
3954    
3955     /* g for graphical mode. G for graphical mode
3956     with SGI logo visible on Irix? */
3957     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3958     add_environment_string(cpu, "console=g", &addr);
3959     }
3960     } else {
3961     if (machine->machine_type == MACHINE_ARC) {
3962     /* TODO: serial console for ARC? */
3963     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3964     add_environment_string(cpu, "CONSOLEIN=multi()serial(0)", &addr);
3965     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3966     add_environment_string(cpu, "CONSOLEOUT=multi()serial(0)", &addr);
3967     } else {
3968     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3969     add_environment_string(cpu, "ConsoleIn=serial(0)", &addr);
3970     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3971     add_environment_string(cpu, "ConsoleOut=serial(0)", &addr);
3972    
3973     /* 'd' or 'd2' in Irix, 'ttyS0' in Linux? */
3974     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3975     add_environment_string(cpu, "console=d", &addr); /* d2 = serial? */
3976     }
3977     }
3978    
3979     if (machine->machine_type == MACHINE_SGI) {
3980     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3981     add_environment_string(cpu, "AutoLoad=No", &addr);
3982     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3983     add_environment_string(cpu, "diskless=0", &addr);
3984     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3985     add_environment_string(cpu, "volume=80", &addr);
3986     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3987     add_environment_string(cpu, "sgilogo=y", &addr);
3988    
3989     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3990     add_environment_string(cpu, "monitor=h", &addr);
3991     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3992     add_environment_string(cpu, "TimeZone=GMT", &addr);
3993     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3994     add_environment_string(cpu, "nogfxkbd=1", &addr);
3995    
3996     /* TODO: 'xio(0)pci(15)scsi(0)disk(1)rdisk(0)partition(0)' on IP30 at least */
3997    
3998     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3999     add_environment_string(cpu, "SystemPartition=pci(0)scsi(0)disk(2)rdisk(0)partition(8)", &addr);
4000     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4001     add_environment_string(cpu, "OSLoadPartition=pci(0)scsi(0)disk(2)rdisk(0)partition(0)", &addr);
4002     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4003     add_environment_string(cpu, "OSLoadFilename=/unix", &addr);
4004     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4005     add_environment_string(cpu, "OSLoader=sash", &addr);
4006    
4007     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4008     add_environment_string(cpu, "rbaud=9600", &addr);
4009     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4010     add_environment_string(cpu, "rebound=y", &addr);
4011     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4012     add_environment_string(cpu, "crt_option=1", &addr);
4013     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4014     add_environment_string(cpu, "netaddr=10.0.0.1", &addr);
4015    
4016     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4017     add_environment_string(cpu, "keybd=US", &addr);
4018    
4019     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4020     add_environment_string(cpu, "cpufreq=3", &addr);
4021     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4022     add_environment_string(cpu, "dbaud=9600", &addr);
4023     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4024     add_environment_string(cpu, eaddr_string, &addr);
4025     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4026     add_environment_string(cpu, "verbose=istrue", &addr);
4027     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4028     add_environment_string(cpu, "showconfig=istrue", &addr);
4029     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4030     add_environment_string(cpu, "diagmode=v", &addr);
4031     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4032     add_environment_string(cpu, "kernname=unix", &addr);
4033     } else {
4034     char *tmp;
4035     tmp = malloc(strlen(bootarg) + strlen("OSLOADOPTIONS=") + 2);
4036     sprintf(tmp, "OSLOADOPTIONS=%s", bootarg);
4037     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4038     add_environment_string(cpu, tmp, &addr);
4039    
4040     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4041     add_environment_string(cpu, "OSLOADPARTITION=scsi(0)cdrom(6)fdisk(0);scsi(0)disk(0)rdisk(0)partition(1)", &addr);
4042    
4043     store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
4044     add_environment_string(cpu, "SYSTEMPARTITION=scsi(0)cdrom(6)fdisk(0);scsi(0)disk(0)rdisk(0)partition(1)", &addr);
4045     }
4046    
4047     /* End the environment strings with an empty zero-terminated
4048     string, and the envp array with a NULL pointer. */
4049     add_environment_string(cpu, "", &addr); /* the end */
4050     store_pointer_and_advance(cpu, &addr2,
4051     0, arc_wordlen==sizeof(uint64_t));
4052    
4053     no_arc_prom_emulation: /* TODO: ugly, get rid of the goto */
4054    
4055     /* Return address: (0x20 = ReturnFromMain()) */
4056     cpu->cd.mips.gpr[MIPS_GPR_RA] = ARC_FIRMWARE_ENTRIES + 0x20;
4057    
4058     break;
4059    
4060     case MACHINE_MESHCUBE:
4061     machine->machine_name = "MeshCube";
4062    
4063     if (machine->physical_ram_in_mb != 64)
4064     fprintf(stderr, "WARNING! MeshCubes are supposed to have exactly 64 MB RAM. Continuing anyway.\n");
4065     if (machine->use_x11)
4066     fprintf(stderr, "WARNING! MeshCube with -X is meaningless. Continuing anyway.\n");
4067    
4068     /* First of all, the MeshCube has an Au1500 in it: */
4069     machine->md_interrupt = au1x00_interrupt;
4070     machine->au1x00_ic_data = dev_au1x00_init(machine, mem);
4071    
4072     /*
4073     * TODO: Which non-Au1500 devices, and at what addresses?
4074     *
4075     * "4G Systems MTX-1 Board" at ?
4076     * 1017fffc, 14005004, 11700000, 11700008, 11900014,
4077     * 1190002c, 11900100, 11900108, 1190010c,
4078     * 10400040 - 10400074,
4079     * 14001000 (possibly LCD?)
4080     * 11100028 (possibly ttySx?)
4081     *
4082     * "usb_ohci=base:0x10100000,len:0x100000,irq:26"
4083     */
4084    
4085     device_add(machine, "random addr=0x1017fffc len=4");
4086    
4087     /*
4088     * TODO: A Linux kernel wants "memsize" from somewhere... I
4089     * haven't found any docs on how it is used though.
4090     */
4091    
4092     cpu->cd.mips.gpr[MIPS_GPR_A0] = 1;
4093     cpu->cd.mips.gpr[MIPS_GPR_A1] = 0xa0001000ULL;
4094     store_32bit_word(cpu, cpu->cd.mips.gpr[MIPS_GPR_A1],
4095     0xa0002000ULL);
4096     store_string(cpu, 0xa0002000ULL, "something=somethingelse");
4097    
4098     cpu->cd.mips.gpr[MIPS_GPR_A2] = 0xa0003000ULL;
4099     store_string(cpu, 0xa0002000ULL, "hello=world\n");
4100    
4101     break;
4102    
4103     case MACHINE_NETGEAR:
4104     machine->machine_name = "NetGear WG602";
4105    
4106     if (machine->use_x11)
4107     fprintf(stderr, "WARNING! NetGear with -X is meaningless. Continuing anyway.\n");
4108     if (machine->physical_ram_in_mb != 16)
4109     fprintf(stderr, "WARNING! Real NetGear WG602 boxes have exactly 16 MB RAM. Continuing anyway.\n");
4110    
4111     /*
4112     * Lots of info about the IDT 79RC 32334
4113     * http://www.idt.com/products/pages/Integrated_Processors-79RC32334.html
4114     */
4115     device_add(machine, "8250 addr=0x18000800 addr_mult=4 irq=0");
4116     break;
4117    
4118     case MACHINE_WRT54G:
4119     machine->machine_name = "Linksys WRT54G";
4120    
4121     if (machine->use_x11)
4122     fprintf(stderr, "WARNING! Linksys WRT54G with -X is meaningless. Continuing anyway.\n");
4123    
4124     /* 200 MHz default */
4125     if (machine->emulated_hz == 0)
4126     machine->emulated_hz = 200000000;
4127    
4128     /*
4129     * Linux should be loaded at 0x80001000.
4130     * RAM: 16 or 32 MB, Flash RAM: 4 or 8 MB.
4131     * http://www.bumpclub.ee/~jaanus/wrt54g/vana/minicom.cap:
4132     *
4133     * Starting program at 0x80001000
4134     * CPU revision is: 00029007
4135     * Primary instruction cache 8kb, linesize 16 bytes (2 ways)
4136     * Primary data cache 4kb, linesize 16 bytes (2 ways)
4137     * memory: 01000000 @ 00000000 (usable)
4138     * Kernel command line: root=/dev/mtdblock2 rootfstype=squashfs init=/etc/preinit noinitrd console=ttyS0,115200
4139     * CPU: BCM4712 rev 1 at 200 MHz
4140     * Calibrating delay loop... 199.47 BogoMIPS
4141     * ttyS00 at 0xb8000300 (irq = 3) is a 16550A
4142     * ttyS01 at 0xb8000400 (irq = 0) is a 16550A
4143     * Flash device: 0x400000 at 0x1c000000
4144     * ..
4145     */
4146    
4147     /* TODO: What should the initial register contents be? */
4148     #if 1
4149     {
4150     int i;
4151     for (i=0; i<32; i++)
4152     cpu->cd.mips.gpr[i] = 0x01230000 + (i << 8) + 0x55;
4153     }
4154     #endif
4155    
4156     break;
4157    
4158     case MACHINE_SONYNEWS:
4159     /*
4160     * There are several models, according to
4161     * http://www.netbsd.org/Ports/newsmips/:
4162     *
4163     * "R3000 and hyper-bus based models"
4164     * NWS-3470D, -3410, -3460, -3710, -3720
4165     *
4166     * "R4000/4400 and apbus based models"
4167     * NWS-5000
4168     *
4169     * For example: (found using google)
4170     *
4171     * cpu_model = news3700
4172     * SONY NET WORK STATION, Model NWS-3710, Machine ID #30145
4173     * cpu0: MIPS R3000 (0x220) Rev. 2.0 with MIPS R3010 Rev.2.0
4174     * 64KB/4B direct-mapped I, 64KB/4B direct-mapped w-thr. D
4175     *
4176     * See http://katsu.watanabe.name/doc/sonynews/model.html
4177     * for more details.
4178     */
4179     cpu->byte_order = EMUL_BIG_ENDIAN;
4180     machine->machine_name = "Sony NeWS (NET WORK STATION)";
4181    
4182     /* This is just a test. TODO */
4183     {
4184     int i;
4185     for (i=0; i<32; i++)
4186     cpu->cd.mips.gpr[i] =
4187     0x01230000 + (i << 8) + 0x55;
4188     }
4189    
4190     machine->main_console_handle =
4191     dev_zs_init(machine, mem, 0x1e950000, 0, 1, "zs console");
4192    
4193     break;
4194    
4195     case MACHINE_BAREPPC:
4196     /*
4197     * A "bare" PPC machine.
4198     *
4199     * NOTE: NO devices at all.
4200     */
4201     machine->machine_name = "\"Bare\" PPC machine";
4202     break;
4203    
4204     case MACHINE_TESTPPC:
4205     /*
4206     * A PPC test machine, similar to the test machine for MIPS.
4207     */
4208     machine->machine_name = "PPC test machine";
4209    
4210     /* TODO: interrupt for PPC? */
4211     machine->main_console_handle = dev_cons_init(
4212     machine, mem, DEV_CONS_ADDRESS, "console", 0);
4213    
4214     snprintf(tmpstr, sizeof(tmpstr) - 1, "mp addr=0x%llx",
4215     (long long)DEV_MP_ADDRESS);
4216     device_add(machine, tmpstr);
4217    
4218     fb = dev_fb_init(machine, mem, 0x12000000, VFB_GENERIC,
4219     640,480, 640,480, 24, "generic", 1);
4220     break;
4221    
4222     case MACHINE_WALNUT:
4223     /*
4224     * NetBSD/evbppc (http://www.netbsd.org/Ports/evbppc/)
4225     */
4226     machine->machine_name = "Walnut evaluation board";
4227    
4228     break;
4229    
4230     case MACHINE_PMPPC:
4231     /*
4232     * NetBSD/pmppc (http://www.netbsd.org/Ports/pmppc/)
4233     */
4234     machine->machine_name = "Artesyn's PM/PPC board";
4235    
4236     dev_pmppc_init(mem);
4237    
4238     /* com0 = 0xff600300, com1 = 0xff600400 */
4239     machine->main_console_handle = dev_ns16550_init(machine, mem,
4240     0xff600300, 0, 1, 1, "serial 0");
4241     dev_ns16550_init(machine, mem,
4242     0xff600400, 0, 1, 0, "serial 1");
4243    
4244     break;
4245    
4246     case MACHINE_SANDPOINT:
4247     /*
4248     * NetBSD/sandpoint (http://www.netbsd.org/Ports/sandpoint/)
4249     */
4250     machine->machine_name = "Motorola Sandpoint";
4251    
4252     {
4253     int i;
4254     for (i=0; i<32; i++)
4255     cpu->cd.ppc.gpr[i] =
4256     0x12340000 + (i << 8) + 0x55;
4257     }
4258    
4259     break;
4260    
4261     case MACHINE_BEBOX:
4262     /*
4263     * NetBSD/bebox (http://www.netbsd.org/Ports/bebox/)
4264     */
4265     machine->machine_name = "BeBox";
4266    
4267     device_add(machine, "bebox");
4268    
4269     /* Serial, used by NetBSD: */
4270     machine->main_console_handle = dev_ns16550_init(machine, mem,
4271     0x800003f8, 0, 1, 1, "serial 0");
4272    
4273     /* Serial, used by Linux: */
4274     dev_ns16550_init(machine, mem, 0x800002f8, 0, 1, 0, "serial 1");
4275    
4276     /* This is used by Linux too: */
4277     dev_vga_init(machine, mem, 0xc00b8000ULL, 0x800003c0ULL, 80, 25,
4278     machine->machine_name);
4279    
4280     store_32bit_word(cpu, 0x3010,
4281     machine->physical_ram_in_mb * 1048576);
4282    
4283     /* TODO: List of stuff, see http://www.beatjapan.org/
4284     mirror/www.be.com/aboutbe/benewsletter/
4285     Issue27.html#Cookbook for the details. */
4286     store_32bit_word(cpu, 0x301c, 0);
4287    
4288     /* NetBSD/bebox: r3 = startkernel, r4 = endkernel,
4289     r5 = args, r6 = ptr to bootinfo? */
4290     cpu->cd.ppc.gpr[3] = 0x3100;
4291     cpu->cd.ppc.gpr[4] = 0x200000;
4292     cpu->cd.ppc.gpr[5] = 0x2000;
4293     store_string(cpu, cpu->cd.ppc.gpr[5], "-a");
4294     cpu->cd.ppc.gpr[6] = machine->physical_ram_in_mb * 1048576
4295     - 0x100;
4296    
4297     /* See NetBSD's bebox/include/bootinfo.h for details */
4298     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 0, 12); /* next */
4299     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 4, 0); /* mem */
4300     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 8,
4301     machine->physical_ram_in_mb * 1048576);
4302    
4303     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 12, 20); /* next */
4304     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 16, 1); /* console */
4305     store_buf(cpu, cpu->cd.ppc.gpr[6] + 20, "com", 4);
4306     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 24, 0x3f8);/* addr */
4307     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 28, 9600);/* speed */
4308    
4309     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 32, 0); /* next */
4310     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 36, 2); /* clock */
4311     store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 40, 100);
4312    
4313     break;
4314    
4315     case MACHINE_PREP:
4316     /*
4317     * NetBSD/prep (http://www.netbsd.org/Ports/prep/)
4318     */
4319     machine->machine_name = "PowerPC Reference Platform";
4320    
4321     {
4322     int i;
4323     for (i=0; i<32; i++)
4324     cpu->cd.ppc.gpr[i] =
4325     0x12340000 + (i << 8) + 0x55;
4326     }
4327    
4328     /* Linux on PReP has 0xdeadc0de at address 0? (See
4329     http://joshua.raleigh.nc.us/docs/linux-2.4.10_html/113568.html) */
4330     store_32bit_word(cpu, 0, 0xdeadc0de);
4331    
4332     /* r6 should point to "residual data"? */
4333     cpu->cd.ppc.gpr[6] = machine->physical_ram_in_mb * 1048576
4334     - 0x1000;
4335    
4336     break;
4337    
4338     case MACHINE_MACPPC:
4339     /*
4340     * NetBSD/macppc (http://www.netbsd.org/Ports/macppc/)
4341     * OpenBSD/macppc (http://www.openbsd.org/macppc.html)
4342     */
4343     machine->machine_name = "Macintosh (PPC)";
4344    
4345     /* r5 = OpenFirmware entry point */
4346     cpu->cd.ppc.gpr[5] = cpu->cd.ppc.of_emul_addr;
4347    
4348     break;
4349    
4350     case MACHINE_DB64360:
4351     /* For playing with PMON2000 for PPC: */
4352     machine->machine_name = "DB64360";
4353    
4354     machine->main_console_handle = dev_ns16550_init(machine, mem,
4355     0x1d000020, 0, 4, 1, "serial console");
4356    
4357     {
4358     int i;
4359     for (i=0; i<32; i++)
4360     cpu->cd.ppc.gpr[i] =
4361     0x12340000 + (i << 8) + 0x55;
4362     }
4363    
4364     break;
4365    
4366     case MACHINE_BARESPARC:
4367     /* A bare SPARC machine, with no devices. */
4368     machine->machine_name = "\"Bare\" SPARC machine";
4369     break;
4370    
4371     case MACHINE_ULTRA1:
4372     /*
4373     * NetBSD/sparc64 (http://www.netbsd.org/Ports/sparc64/)
4374     * OpenBSD/sparc64 (http://www.openbsd.org/sparc64.html)
4375     */
4376     machine->machine_name = "Sun Ultra1";
4377     break;
4378    
4379     case MACHINE_BAREURISC:
4380     machine->machine_name = "\"Bare\" URISC machine";
4381     break;
4382    
4383     case MACHINE_TESTURISC:
4384     machine->machine_name = "URISC test machine";
4385    
4386     /* TODO */
4387     /* A special "device" for accessing normal devices
4388     using urisc accesses? */
4389    
4390     device_add(machine, "urisc addr=0x12341234");
4391    
4392     break;
4393    
4394     case MACHINE_BAREHPPA:
4395     machine->machine_name = "\"Bare\" HPPA machine";
4396     break;
4397    
4398     case MACHINE_TESTHPPA:
4399     machine->machine_name = "HPPA test machine";
4400    
4401     /* TODO */
4402     break;
4403    
4404     case MACHINE_BAREALPHA:
4405     machine->machine_name = "\"Bare\" Alpha machine";
4406     break;
4407    
4408     case MACHINE_TESTALPHA:
4409     machine->machine_name = "Alpha test machine";
4410    
4411     /* TODO */
4412     break;
4413    
4414     default:
4415     fatal("Unknown emulation type %i\n", machine->machine_type);
4416     exit(1);
4417     }
4418    
4419     if (machine->machine_name != NULL)
4420     debug("machine: %s", machine->machine_name);
4421    
4422     if (machine->emulated_hz > 0)
4423     debug(" (%.2f MHz)", (float)machine->emulated_hz / 1000000);
4424     debug("\n");
4425    
4426     if (machine->emulated_hz < 1)
4427     machine->emulated_hz = 1000000;
4428    
4429     if (bootstr != NULL) {
4430     debug("bootstring%s: %s", (bootarg!=NULL &&
4431     strlen(bootarg) >= 1)? "(+bootarg)" : "", bootstr);
4432     if (bootarg != NULL && strlen(bootarg) >= 1)
4433     debug(" %s", bootarg);
4434     debug("\n");
4435     }
4436     }
4437    
4438    
4439     /*
4440     * machine_memsize_fix():
4441     *
4442     * Sets physical_ram_in_mb (if not already set), and memory_offset_in_mb,
4443     * depending on machine type.
4444     */
4445     void machine_memsize_fix(struct machine *m)
4446     {
4447     if (m == NULL) {
4448     fatal("machine_defaultmemsize(): m == NULL?\n");
4449     exit(1);
4450     }
4451    
4452     if (m->physical_ram_in_mb == 0) {
4453     switch (m->machine_type) {
4454     case MACHINE_PS2:
4455     m->physical_ram_in_mb = 32;
4456     break;
4457     case MACHINE_SGI:
4458     m->physical_ram_in_mb = 64;
4459     break;
4460     case MACHINE_HPCMIPS:
4461     /* Most have 32 MB by default. */
4462     m->physical_ram_in_mb = 32;
4463     switch (m->machine_subtype) {
4464     case MACHINE_HPCMIPS_CASIO_BE300:
4465     m->physical_ram_in_mb = 16;
4466     break;
4467     case MACHINE_HPCMIPS_CASIO_E105:
4468     m->physical_ram_in_mb = 32;
4469     break;
4470     case MACHINE_HPCMIPS_AGENDA_VR3:
4471     m->physical_ram_in_mb = 16;
4472     break;
4473     }
4474     break;
4475     case MACHINE_MESHCUBE:
4476     m->physical_ram_in_mb = 64;
4477     break;
4478     case MACHINE_NETGEAR:
4479     m->physical_ram_in_mb = 16;
4480     break;
4481     case MACHINE_WRT54G:
4482     m->physical_ram_in_mb = 32;
4483     break;
4484     case MACHINE_ARC:
4485     switch (m->machine_subtype) {
4486     case MACHINE_ARC_JAZZ_PICA:
4487     m->physical_ram_in_mb = 64;
4488     break;
4489     case MACHINE_ARC_JAZZ_M700:
4490     m->physical_ram_in_mb = 64;
4491     break;
4492     default:
4493     m->physical_ram_in_mb = 32;
4494     }
4495     break;
4496     case MACHINE_DEC:
4497     switch (m->machine_subtype) {
4498     case MACHINE_DEC_PMAX_3100:
4499     m->physical_ram_in_mb = 24;
4500     break;
4501     default:
4502     m->physical_ram_in_mb = 32;
4503     }
4504     break;
4505     case MACHINE_BEBOX:
4506     m->physical_ram_in_mb = 64;
4507     break;
4508     case MACHINE_BAREURISC:
4509     case MACHINE_TESTURISC:
4510     m->physical_ram_in_mb = 2;
4511     break;
4512     }
4513     }
4514    
4515     /* Special hack for WRT54G and hpcmips machines: */
4516     if (m->machine_type == MACHINE_WRT54G ||
4517     m->machine_type == MACHINE_HPCMIPS) {
4518     m->dbe_on_nonexistant_memaccess = 0;
4519     }
4520    
4521     /* Special SGI memory offsets: */
4522     if (m->machine_type == MACHINE_SGI) {
4523     switch (m->machine_subtype) {
4524     case 20:
4525     case 22:
4526     case 24:
4527     case 26:
4528     m->memory_offset_in_mb = 128;
4529     break;
4530     case 28:
4531     case 30:
4532     m->memory_offset_in_mb = 512;
4533     break;
4534     }
4535     }
4536    
4537     if (m->physical_ram_in_mb == 0)
4538     m->physical_ram_in_mb = DEFAULT_RAM_IN_MB;
4539     }
4540    
4541    
4542     /*
4543     * machine_default_cputype():
4544     *
4545     * Sets m->cpu_name, if it isn't already set, depending on the machine
4546     * type.
4547     */
4548     void machine_default_cputype(struct machine *m)
4549     {
4550     if (m == NULL) {
4551     fatal("machine_default_cputype(): m == NULL?\n");
4552     exit(1);
4553     }
4554    
4555     if (m->cpu_name != NULL)
4556     return;
4557    
4558     switch (m->machine_type) {
4559     case MACHINE_BAREMIPS:
4560     case MACHINE_TESTMIPS:
4561     m->cpu_name = strdup("R4000");
4562     break;
4563     case MACHINE_PS2:
4564     m->cpu_name = strdup("R5900");
4565     break;
4566     case MACHINE_DEC:
4567     if (m->machine_subtype > 2)
4568     m->cpu_name = strdup("R3000A");
4569     if (m->machine_subtype > 1 && m->cpu_name == NULL)
4570     m->cpu_name = strdup("R3000");
4571     if (m->cpu_name == NULL)
4572     m->cpu_name = strdup("R2000");
4573     break;
4574     case MACHINE_SONYNEWS:
4575     m->cpu_name = strdup("R3000");
4576     break;
4577     case MACHINE_HPCMIPS:
4578     switch (m->machine_subtype) {
4579     case MACHINE_HPCMIPS_CASIO_BE300:
4580     m->cpu_name = strdup("VR4131");
4581     break;
4582     case MACHINE_HPCMIPS_CASIO_E105:
4583     m->cpu_name = strdup("VR4121");
4584     break;
4585     case MACHINE_HPCMIPS_NEC_MOBILEPRO_770:
4586     case MACHINE_HPCMIPS_NEC_MOBILEPRO_780:
4587     case MACHINE_HPCMIPS_NEC_MOBILEPRO_800:
4588     case MACHINE_HPCMIPS_NEC_MOBILEPRO_880:
4589     m->cpu_name = strdup("VR4121");
4590     break;
4591     case MACHINE_HPCMIPS_AGENDA_VR3:
4592     m->cpu_name = strdup("VR4181");
4593     break;
4594     case MACHINE_HPCMIPS_IBM_WORKPAD_Z50:
4595     m->cpu_name = strdup("VR4121");
4596     break;
4597     default:
4598     printf("Unimplemented HPCMIPS model?\n");
4599     exit(1);
4600     }
4601     break;
4602     case MACHINE_COBALT:
4603     m->cpu_name = strdup("RM5200");
4604     break;
4605     case MACHINE_MESHCUBE:
4606     m->cpu_name = strdup("R4400");
4607     /* TODO: Should be AU1500, but Linux doesn't like
4608     the absence of caches in the emulator */
4609     break;
4610     case MACHINE_NETGEAR:
4611     m->cpu_name = strdup("RC32334");
4612     break;
4613     case MACHINE_WRT54G:
4614     m->cpu_name = strdup("BCM4712");
4615     break;
4616     case MACHINE_ARC:
4617     switch (m->machine_subtype) {
4618     case MACHINE_ARC_JAZZ_PICA:
4619     m->cpu_name = strdup("R4000");
4620     break;
4621     default:
4622     m->cpu_name = strdup("R4400");
4623     }
4624     break;
4625     case MACHINE_SGI:
4626     if (m->machine_subtype <= 12)
4627     m->cpu_name = strdup("R3000");
4628     if (m->cpu_name == NULL && m->machine_subtype == 35)
4629     m->cpu_name = strdup("R12000");
4630     if (m->cpu_name == NULL && (m->machine_subtype == 25 ||
4631     m->machine_subtype == 27 ||
4632     m->machine_subtype == 28 ||
4633     m->machine_subtype == 30 ||
4634     m->machine_subtype == 32))
4635     m->cpu_name = strdup("R10000");
4636     if (m->cpu_name == NULL && (m->machine_subtype == 21 ||
4637     m->machine_subtype == 26))
4638     m->cpu_name = strdup("R8000");
4639     if (m->cpu_name == NULL && m->machine_subtype == 24)
4640     m->cpu_name = strdup("R5000");
4641    
4642     /* Other SGIs should probably work with
4643     R4000, R4400 or R5000 or similar: */
4644     if (m->cpu_name == NULL)
4645     m->cpu_name = strdup("R4400");
4646     break;
4647    
4648     /* PowerPC: */
4649     case MACHINE_BAREPPC:
4650     case MACHINE_TESTPPC:
4651     m->cpu_name = strdup("PPC970");
4652     break;
4653     case MACHINE_WALNUT:
4654     /* For NetBSD/evbppc. */
4655     m->cpu_name = strdup("PPC405GP");
4656     break;
4657     case MACHINE_PMPPC:
4658     /* For NetBSD/pmppc. */
4659     m->cpu_name = strdup("PPC750");
4660     break;
4661     case MACHINE_SANDPOINT:
4662     /*
4663     * For NetBSD/sandpoint. According to NetBSD's page:
4664     *
4665     * "Unity" module has an MPC8240.
4666     * "Altimus" module has an MPC7400 (G4) or an MPC107.
4667     */
4668     m->cpu_name = strdup("MPC7400");
4669     break;
4670     case MACHINE_BEBOX:
4671     /* For NetBSD/bebox. Dual 133 MHz 603e CPUs, for example. */
4672     m->cpu_name = strdup("PPC603e");
4673     break;
4674     case MACHINE_PREP:
4675     /* For NetBSD/prep. TODO */
4676     m->cpu_name = strdup("PPC603e");
4677     break;
4678     case MACHINE_MACPPC:
4679     switch (m->machine_subtype) {
4680     case MACHINE_MACPPC_G4:
4681     m->cpu_name = strdup("G4e");
4682     break;
4683     case MACHINE_MACPPC_G5:
4684     m->cpu_name = strdup("PPC970");
4685     break;
4686     }
4687     break;
4688     case MACHINE_DB64360:
4689     m->cpu_name = strdup("PPC750");
4690     break;
4691    
4692     /* SPARC: */
4693     case MACHINE_BARESPARC:
4694     m->cpu_name = strdup("SPARCV9");
4695     break;
4696     case MACHINE_ULTRA1:
4697     m->cpu_name = strdup("SPARCV9");
4698     break;
4699    
4700     /* URISC: */
4701     case MACHINE_BAREURISC:
4702     case MACHINE_TESTURISC:
4703     m->cpu_name = strdup("URISC");
4704     break;
4705    
4706     /* HPPA: */
4707     case MACHINE_BAREHPPA:
4708     case MACHINE_TESTHPPA:
4709     m->cpu_name = strdup("HPPA2.0");
4710     break;
4711    
4712     /* Alpha: */
4713     case MACHINE_BAREALPHA:
4714     case MACHINE_TESTALPHA:
4715     m->cpu_name = strdup("EV4");
4716     break;
4717     }
4718    
4719     if (m->cpu_name == NULL) {
4720     fprintf(stderr, "machine_default_cputype(): no default"
4721     " cpu for machine type %i subtype %i\n",
4722     m->machine_type, m->machine_subtype);
4723     exit(1);
4724     }
4725     }
4726    
4727    
4728     /*
4729     * machine_dumpinfo():
4730     *
4731     * Dumps info about a machine in some kind of readable format. (Used by
4732     * the 'machine' debugger command.)
4733     */
4734     void machine_dumpinfo(struct machine *m)
4735     {
4736     int i;
4737    
4738     debug("serial nr: %i", m->serial_nr);
4739     if (m->nr_of_nics > 0)
4740     debug(" (nr of nics: %i)", m->nr_of_nics);
4741     debug("\n");
4742    
4743     debug("memory: %i MB", m->physical_ram_in_mb);
4744     if (m->memory_offset_in_mb != 0)
4745     debug(" (offset by %i MB)", m->memory_offset_in_mb);
4746     if (m->random_mem_contents)
4747     debug(", randomized contents");
4748     if (m->dbe_on_nonexistant_memaccess)
4749     debug(", dbe_on_nonexistant_memaccess");
4750     debug("\n");
4751    
4752     if (m->single_step_on_bad_addr)
4753     debug("single-step on bad addresses\n");
4754    
4755     if (m->bintrans_enable)
4756     debug("bintrans enabled (%i MB cache)\n",
4757     (int) (m->bintrans_size / 1048576));
4758     else
4759     debug("bintrans disabled, other speedtricks %s\n",
4760     m->speed_tricks? "enabled" : "disabled");
4761    
4762     debug("clock: ");
4763     if (m->automatic_clock_adjustment)
4764     debug("adjusted automatically");
4765     else
4766     debug("fixed at %i Hz", m->emulated_hz);
4767     debug("\n");
4768    
4769     if (!m->prom_emulation)
4770     debug("PROM emulation disabled\n");
4771    
4772     for (i=0; i<m->ncpus; i++)
4773     cpu_dumpinfo(m, m->cpus[i]);
4774    
4775     if (m->ncpus > 1)
4776     debug("Bootstrap cpu is nr %i\n", m->bootstrap_cpu);
4777    
4778     if (m->slow_serial_interrupts_hack_for_linux)
4779     debug("Using slow_serial_interrupts_hack_for_linux\n");
4780    
4781     if (m->use_x11) {
4782     debug("Using X11");
4783     if (m->x11_scaledown > 1)
4784     debug(", scaledown %i", m->x11_scaledown);
4785     if (m->x11_n_display_names > 0) {
4786     for (i=0; i<m->x11_n_display_names; i++) {
4787     debug(i? ", " : " (");
4788     debug("\"%s\"", m->x11_display_names[i]);
4789     }
4790     debug(")");
4791     }
4792     debug("\n");
4793     }
4794    
4795     diskimage_dump_info(m);
4796    
4797     if (m->force_netboot)
4798     debug("Forced netboot\n");
4799     }
4800    
4801    
4802     /*
4803     * machine_entry_new():
4804     *
4805     * This function creates a new machine_entry struct, and fills it with some
4806     * valid data; it is up to the caller to add additional data that weren't
4807     * passed as arguments to this function.
4808     *
4809     * For internal use.
4810     */
4811     static struct machine_entry *machine_entry_new(const char *name,
4812     int arch, int oldstyle_type, int n_aliases, int n_subtypes)
4813     {
4814     struct machine_entry *me;
4815    
4816     me = malloc(sizeof(struct machine_entry));
4817     if (me == NULL) {
4818     fprintf(stderr, "machine_entry_new(): out of memory (1)\n");
4819     exit(1);
4820     }
4821    
4822     memset(me, 0, sizeof(struct machine_entry));
4823    
4824     me->name = name;
4825     me->arch = arch;
4826     me->machine_type = oldstyle_type;
4827     me->n_aliases = n_aliases;
4828     me->aliases = malloc(sizeof(char *) * n_aliases);
4829     if (me->aliases == NULL) {
4830     fprintf(stderr, "machine_entry_new(): out of memory (2)\n");
4831     exit(1);
4832     }
4833     me->n_subtypes = n_subtypes;
4834    
4835     if (n_subtypes > 0) {
4836     me->subtype = malloc(sizeof(struct machine_entry_subtype *) *
4837     n_subtypes);
4838     if (me->subtype == NULL) {
4839     fprintf(stderr, "machine_entry_new(): out of "
4840     "memory (3)\n");
4841     exit(1);
4842     }
4843     }
4844    
4845     return me;
4846     }
4847    
4848    
4849     /*
4850     * machine_entry_subtype_new():
4851     *
4852     * This function creates a new machine_entry_subtype struct, and fills it with
4853     * some valid data; it is up to the caller to add additional data that weren't
4854     * passed as arguments to this function.
4855     *
4856     * For internal use.
4857     */
4858     static struct machine_entry_subtype *machine_entry_subtype_new(
4859     const char *name, int oldstyle_type, int n_aliases)
4860     {
4861     struct machine_entry_subtype *mes;
4862    
4863     mes = malloc(sizeof(struct machine_entry_subtype));
4864     if (mes == NULL) {
4865     fprintf(stderr, "machine_entry_subtype_new(): out "
4866     "of memory (1)\n");
4867     exit(1);
4868     }
4869    
4870     memset(mes, 0, sizeof(struct machine_entry_subtype));
4871     mes->name = name;
4872     mes->machine_subtype = oldstyle_type;
4873     mes->n_aliases = n_aliases;
4874     mes->aliases = malloc(sizeof(char *) * n_aliases);
4875     if (mes->aliases == NULL) {
4876     fprintf(stderr, "machine_entry_subtype_new(): "
4877     "out of memory (2)\n");
4878     exit(1);
4879     }
4880    
4881     return mes;
4882     }
4883    
4884    
4885     /*
4886     * machine_list_available_types_and_cpus():
4887     *
4888     * List all available machine types (for example when running the emulator
4889     * with just -H as command line argument).
4890     */
4891     void machine_list_available_types_and_cpus(void)
4892     {
4893     struct machine_entry *me;
4894     int iadd = 8;
4895    
4896     debug("Available CPU types:\n\n");
4897    
4898     debug_indentation(iadd);
4899     cpu_list_available_types();
4900     debug_indentation(-iadd);
4901    
4902     debug("\nMost of the CPU types are bogus, and not really implemented."
4903     " The main effect of\nselecting a specific CPU type is to choose "
4904     "what kind of 'id' it will have.\n\nAvailable machine types (with "
4905     "aliases) and their subtypes:\n\n");
4906    
4907     debug_indentation(iadd);
4908     me = first_machine_entry;
4909    
4910     if (me == NULL)
4911     fatal("No machines defined!\n");
4912    
4913     while (me != NULL) {
4914     int i, j, iadd = 4;
4915    
4916     debug("%s", me->name);
4917     debug(" (");
4918     for (i=0; i<me->n_aliases; i++)
4919     debug("%s\"%s\"", i? ", " : "", me->aliases[i]);
4920     debug(")\n");
4921    
4922     debug_indentation(iadd);
4923     for (i=0; i<me->n_subtypes; i++) {
4924     struct machine_entry_subtype *mes;
4925     mes = me->subtype[i];
4926     debug("- %s", mes->name);
4927     debug(" (");
4928     for (j=0; j<mes->n_aliases; j++)
4929     debug("%s\"%s\"", j? ", " : "",
4930     mes->aliases[j]);
4931     debug(")\n");
4932     }
4933     debug_indentation(-iadd);
4934    
4935     me = me->next;
4936     }
4937     debug_indentation(-iadd);
4938    
4939     debug("\nMost of the machine types are bogus too. Please read the "
4940     "GXemul\ndocumentation for information about which machine"
4941     " types that actually\nwork. Use the alias when selecting a "
4942     "machine type or subtype, not the\nreal name.\n");
4943    
4944     debug("\n");
4945    
4946     useremul_list_emuls();
4947     }
4948    
4949    
4950     /*
4951     * machine_init():
4952     *
4953     * This function should be called before any other machine_*() function
4954     * is used.
4955     */
4956     void machine_init(void)
4957     {
4958     struct machine_entry *me;
4959    
4960     /*
4961     * NOTE: This list is in reverse order, so that the
4962     * entries will appear in normal order when listed. :-)
4963     */
4964    
4965     /* Walnut: (NetBSD/evbppc) */
4966     me = machine_entry_new("Walnut evaluation board", ARCH_PPC,
4967     MACHINE_WALNUT, 2, 0);
4968     me->aliases[0] = "walnut";
4969     me->aliases[1] = "evbppc";
4970     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
4971     me->next = first_machine_entry; first_machine_entry = me;
4972     }
4973    
4974     /* Test-machine for URISC: */
4975     me = machine_entry_new("Test-machine for URISC", ARCH_URISC,
4976     MACHINE_TESTURISC, 1, 0);
4977     me->aliases[0] = "testurisc";
4978     if (cpu_family_ptr_by_number(ARCH_URISC) != NULL) {
4979     me->next = first_machine_entry; first_machine_entry = me;
4980     }
4981    
4982     /* Test-machine for PPC: */
4983     me = machine_entry_new("Test-machine for PPC", ARCH_PPC,
4984     MACHINE_TESTPPC, 1, 0);
4985     me->aliases[0] = "testppc";
4986     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
4987     me->next = first_machine_entry; first_machine_entry = me;
4988     }
4989    
4990     /* Test-machine for MIPS: */
4991     me = machine_entry_new("Test-machine for MIPS", ARCH_MIPS,
4992     MACHINE_TESTMIPS, 1, 0);
4993     me->aliases[0] = "testmips";
4994     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
4995     me->next = first_machine_entry; first_machine_entry = me;
4996     }
4997    
4998     /* Test-machine for HPPA: */
4999     me = machine_entry_new("Test-machine for HPPA", ARCH_HPPA,
5000     MACHINE_TESTHPPA, 1, 0);
5001     me->aliases[0] = "testhppa";
5002     if (cpu_family_ptr_by_number(ARCH_HPPA) != NULL) {
5003     me->next = first_machine_entry; first_machine_entry = me;
5004     }
5005    
5006     /* Test-machine for Alpha: */
5007     me = machine_entry_new("Test-machine for Alpha", ARCH_ALPHA,
5008     MACHINE_TESTALPHA, 1, 0);
5009     me->aliases[0] = "testalpha";
5010     if (cpu_family_ptr_by_number(ARCH_ALPHA) != NULL) {
5011     me->next = first_machine_entry; first_machine_entry = me;
5012     }
5013    
5014     /* Sun Ultra1: */
5015     me = machine_entry_new("Sun Ultra1", ARCH_SPARC, MACHINE_ULTRA1, 1, 0);
5016     me->aliases[0] = "ultra1";
5017     if (cpu_family_ptr_by_number(ARCH_SPARC) != NULL) {
5018     me->next = first_machine_entry; first_machine_entry = me;
5019     }
5020    
5021     /* Sony Playstation 2: */
5022     me = machine_entry_new("Sony Playstation 2", ARCH_MIPS,
5023     MACHINE_PS2, 2, 0);
5024     me->aliases[0] = "playstation2";
5025     me->aliases[1] = "ps2";
5026     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5027     me->next = first_machine_entry; first_machine_entry = me;
5028     }
5029    
5030     /* Sony NeWS: */
5031     me = machine_entry_new("Sony NeWS", ARCH_MIPS,
5032     MACHINE_SONYNEWS, 2, 0);
5033     me->aliases[0] = "sonynews";
5034     me->aliases[1] = "news";
5035     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5036     me->next = first_machine_entry; first_machine_entry = me;
5037     }
5038    
5039     /* SGI: */
5040     me = machine_entry_new("SGI", ARCH_MIPS, MACHINE_SGI, 2, 9);
5041     me->aliases[0] = "silicon graphics";
5042     me->aliases[1] = "sgi";
5043     me->subtype[0] = machine_entry_subtype_new("IP19", 19, 1);
5044     me->subtype[0]->aliases[0] = "ip19";
5045     me->subtype[1] = machine_entry_subtype_new("IP20", 20, 1);
5046     me->subtype[1]->aliases[0] = "ip20";
5047     me->subtype[2] = machine_entry_subtype_new("IP22", 22, 2);
5048     me->subtype[2]->aliases[0] = "ip22";
5049     me->subtype[2]->aliases[1] = "indy";
5050     me->subtype[3] = machine_entry_subtype_new("IP24", 24, 1);
5051     me->subtype[3]->aliases[0] = "ip24";
5052     me->subtype[4] = machine_entry_subtype_new("IP27", 27, 3);
5053     me->subtype[4]->aliases[0] = "ip27";
5054     me->subtype[4]->aliases[1] = "origin 200";
5055     me->subtype[4]->aliases[2] = "origin 2000";
5056     me->subtype[5] = machine_entry_subtype_new("IP28", 28, 1);
5057     me->subtype[5]->aliases[0] = "ip28";
5058     me->subtype[6] = machine_entry_subtype_new("IP30", 30, 2);
5059     me->subtype[6]->aliases[0] = "ip30";
5060     me->subtype[6]->aliases[1] = "octane";
5061     me->subtype[7] = machine_entry_subtype_new("IP32", 32, 2);
5062     me->subtype[7]->aliases[0] = "ip32";
5063     me->subtype[7]->aliases[1] = "o2";
5064     me->subtype[8] = machine_entry_subtype_new("IP35", 35, 1);
5065     me->subtype[8]->aliases[0] = "ip35";
5066     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5067     me->next = first_machine_entry; first_machine_entry = me;
5068     }
5069    
5070     /* PReP: (NetBSD/prep etc.) */
5071     me = machine_entry_new("PowerPC Reference Platform", ARCH_PPC,
5072     MACHINE_PREP, 1, 0);
5073     me->aliases[0] = "prep";
5074     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5075     me->next = first_machine_entry; first_machine_entry = me;
5076     }
5077    
5078     /* NetGear: */
5079     me = machine_entry_new("NetGear WG602", ARCH_MIPS,
5080     MACHINE_NETGEAR, 2, 0);
5081     me->aliases[0] = "netgear";
5082     me->aliases[1] = "wg602";
5083     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5084     me->next = first_machine_entry; first_machine_entry = me;
5085     }
5086    
5087     /* Motorola Sandpoint: (NetBSD/sandpoint) */
5088     me = machine_entry_new("Motorola Sandpoint",
5089     ARCH_PPC, MACHINE_SANDPOINT, 1, 0);
5090     me->aliases[0] = "sandpoint";
5091     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5092     me->next = first_machine_entry; first_machine_entry = me;
5093     }
5094    
5095     /* Meshcube: */
5096     me = machine_entry_new("Meshcube", ARCH_MIPS, MACHINE_MESHCUBE, 1, 0);
5097     me->aliases[0] = "meshcube";
5098     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5099     me->next = first_machine_entry; first_machine_entry = me;
5100     }
5101    
5102     /* Macintosh (PPC): */
5103     me = machine_entry_new("Macintosh (PPC)", ARCH_PPC,
5104     MACHINE_MACPPC, 1, 2);
5105     me->aliases[0] = "macppc";
5106     me->subtype[0] = machine_entry_subtype_new("MacPPC G4",
5107     MACHINE_MACPPC_G4, 1);
5108     me->subtype[0]->aliases[0] = "g4";
5109     me->subtype[1] = machine_entry_subtype_new("MacPPC G5",
5110     MACHINE_MACPPC_G5, 1);
5111     me->subtype[1]->aliases[0] = "g5";
5112     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5113     me->next = first_machine_entry; first_machine_entry = me;
5114     }
5115    
5116     /* Linksys: */
5117     me = machine_entry_new("Linksys WRT54G", ARCH_MIPS,
5118     MACHINE_WRT54G, 2, 0);
5119     me->aliases[0] = "linksys";
5120     me->aliases[1] = "wrt54g";
5121     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5122     me->next = first_machine_entry; first_machine_entry = me;
5123     }
5124    
5125     /* HPCmips: */
5126     me = machine_entry_new("Handheld MIPS (HPC)",
5127     ARCH_MIPS, MACHINE_HPCMIPS, 2, 8);
5128     me->aliases[0] = "hpcmips";
5129     me->aliases[1] = "hpc";
5130     me->subtype[0] = machine_entry_subtype_new(
5131     "Casio Cassiopeia BE-300", MACHINE_HPCMIPS_CASIO_BE300, 2);
5132     me->subtype[0]->aliases[0] = "be-300";
5133     me->subtype[0]->aliases[1] = "be300";
5134     me->subtype[1] = machine_entry_subtype_new(
5135     "Casio Cassiopeia E-105", MACHINE_HPCMIPS_CASIO_E105, 2);
5136     me->subtype[1]->aliases[0] = "e-105";
5137     me->subtype[1]->aliases[1] = "e105";
5138     me->subtype[2] = machine_entry_subtype_new(
5139     "Agenda VR3", MACHINE_HPCMIPS_AGENDA_VR3, 2);
5140     me->subtype[2]->aliases[0] = "agenda";
5141     me->subtype[2]->aliases[1] = "vr3";
5142     me->subtype[3] = machine_entry_subtype_new(
5143     "IBM WorkPad Z50", MACHINE_HPCMIPS_IBM_WORKPAD_Z50, 2);
5144     me->subtype[3]->aliases[0] = "workpad";
5145     me->subtype[3]->aliases[1] = "z50";
5146     me->subtype[4] = machine_entry_subtype_new(
5147     "NEC MobilePro 770", MACHINE_HPCMIPS_NEC_MOBILEPRO_770, 1);
5148     me->subtype[4]->aliases[0] = "mobilepro770";
5149     me->subtype[5] = machine_entry_subtype_new(
5150     "NEC MobilePro 780", MACHINE_HPCMIPS_NEC_MOBILEPRO_780, 1);
5151     me->subtype[5]->aliases[0] = "mobilepro780";
5152     me->subtype[6] = machine_entry_subtype_new(
5153     "NEC MobilePro 800", MACHINE_HPCMIPS_NEC_MOBILEPRO_800, 1);
5154     me->subtype[6]->aliases[0] = "mobilepro800";
5155     me->subtype[7] = machine_entry_subtype_new(
5156     "NEC MobilePro 880", MACHINE_HPCMIPS_NEC_MOBILEPRO_880, 1);
5157     me->subtype[7]->aliases[0] = "mobilepro880";
5158     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5159     me->next = first_machine_entry; first_machine_entry = me;
5160     }
5161    
5162     /* Generic "bare" URISC machine: */
5163     me = machine_entry_new("Generic \"bare\" URISC machine", ARCH_URISC,
5164     MACHINE_BAREURISC, 1, 0);
5165     me->aliases[0] = "bareurisc";
5166     if (cpu_family_ptr_by_number(ARCH_URISC) != NULL) {
5167     me->next = first_machine_entry; first_machine_entry = me;
5168     }
5169    
5170     /* Generic "bare" SPARC machine: */
5171     me = machine_entry_new("Generic \"bare\" SPARC machine", ARCH_SPARC,
5172     MACHINE_BARESPARC, 1, 0);
5173     me->aliases[0] = "baresparc";
5174     if (cpu_family_ptr_by_number(ARCH_SPARC) != NULL) {
5175     me->next = first_machine_entry; first_machine_entry = me;
5176     }
5177    
5178     /* Generic "bare" PPC machine: */
5179     me = machine_entry_new("Generic \"bare\" PPC machine", ARCH_PPC,
5180     MACHINE_BAREPPC, 1, 0);
5181     me->aliases[0] = "bareppc";
5182     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5183     me->next = first_machine_entry; first_machine_entry = me;
5184     }
5185    
5186     /* Generic "bare" MIPS machine: */
5187     me = machine_entry_new("Generic \"bare\" MIPS machine", ARCH_MIPS,
5188     MACHINE_BAREMIPS, 1, 0);
5189     me->aliases[0] = "baremips";
5190     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5191     me->next = first_machine_entry; first_machine_entry = me;
5192     }
5193    
5194     /* Generic "bare" HPPA machine: */
5195     me = machine_entry_new("Generic \"bare\" HPPA machine", ARCH_HPPA,
5196     MACHINE_BAREHPPA, 1, 0);
5197     me->aliases[0] = "barehppa";
5198     if (cpu_family_ptr_by_number(ARCH_HPPA) != NULL) {
5199     me->next = first_machine_entry; first_machine_entry = me;
5200     }
5201    
5202     /* Generic "bare" Alpha machine: */
5203     me = machine_entry_new("Generic \"bare\" Alpha machine", ARCH_ALPHA,
5204     MACHINE_BAREALPHA, 1, 0);
5205     me->aliases[0] = "barealpha";
5206     if (cpu_family_ptr_by_number(ARCH_ALPHA) != NULL) {
5207     me->next = first_machine_entry; first_machine_entry = me;
5208     }
5209    
5210     /* DECstation: */
5211     me = machine_entry_new("DECstation/DECsystem",
5212     ARCH_MIPS, MACHINE_DEC, 3, 9);
5213     me->aliases[0] = "decstation";
5214     me->aliases[1] = "decsystem";
5215     me->aliases[2] = "dec";
5216     me->subtype[0] = machine_entry_subtype_new(
5217     "DECstation 3100 (PMAX)", MACHINE_DEC_PMAX_3100, 3);
5218     me->subtype[0]->aliases[0] = "pmax";
5219     me->subtype[0]->aliases[1] = "3100";
5220     me->subtype[0]->aliases[2] = "2100";
5221    
5222     me->subtype[1] = machine_entry_subtype_new(
5223     "DECstation 5000/200 (3MAX)", MACHINE_DEC_3MAX_5000, 2);
5224     me->subtype[1]->aliases[0] = "3max";
5225     me->subtype[1]->aliases[1] = "5000/200";
5226    
5227     me->subtype[2] = machine_entry_subtype_new(
5228     "DECstation 5000/1xx (3MIN)", MACHINE_DEC_3MIN_5000, 2);
5229     me->subtype[2]->aliases[0] = "3min";
5230     me->subtype[2]->aliases[1] = "5000/1xx";
5231    
5232     me->subtype[3] = machine_entry_subtype_new(
5233     "DECstation 5000 (3MAXPLUS)", MACHINE_DEC_3MAXPLUS_5000, 2);
5234     me->subtype[3]->aliases[0] = "3maxplus";
5235     me->subtype[3]->aliases[1] = "3max+";
5236    
5237     me->subtype[4] = machine_entry_subtype_new(
5238     "DECsystem 58x0", MACHINE_DEC_5800, 2);
5239     me->subtype[4]->aliases[0] = "5800";
5240     me->subtype[4]->aliases[1] = "58x0";
5241    
5242     me->subtype[5] = machine_entry_subtype_new(
5243     "DECsystem 5400", MACHINE_DEC_5400, 1);
5244     me->subtype[5]->aliases[0] = "5400";
5245    
5246     me->subtype[6] = machine_entry_subtype_new(
5247     "DECstation Maxine (5000)", MACHINE_DEC_MAXINE_5000, 1);
5248     me->subtype[6]->aliases[0] = "maxine";
5249    
5250     me->subtype[7] = machine_entry_subtype_new(
5251     "DECsystem 5500", MACHINE_DEC_5500, 1);
5252     me->subtype[7]->aliases[0] = "5500";
5253    
5254     me->subtype[8] = machine_entry_subtype_new(
5255     "DECstation MipsMate (5100)", MACHINE_DEC_MIPSMATE_5100, 2);
5256     me->subtype[8]->aliases[0] = "5100";
5257     me->subtype[8]->aliases[1] = "mipsmate";
5258    
5259     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5260     me->next = first_machine_entry; first_machine_entry = me;
5261     }
5262    
5263     /* DB64360: (for playing with PMON for PPC) */
5264     me = machine_entry_new("DB64360", ARCH_PPC, MACHINE_DB64360, 1, 0);
5265     me->aliases[0] = "db64360";
5266     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5267     me->next = first_machine_entry; first_machine_entry = me;
5268     }
5269    
5270     /* Cobalt: */
5271     me = machine_entry_new("Cobalt", ARCH_MIPS, MACHINE_COBALT, 1, 0);
5272     me->aliases[0] = "cobalt";
5273     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5274     me->next = first_machine_entry; first_machine_entry = me;
5275     }
5276    
5277     /* BeBox: (NetBSD/bebox) */
5278     me = machine_entry_new("BeBox", ARCH_PPC, MACHINE_BEBOX, 1, 0);
5279     me->aliases[0] = "bebox";
5280     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5281     me->next = first_machine_entry; first_machine_entry = me;
5282     }
5283    
5284     /* Artesyn's PM/PPC board: (NetBSD/pmppc) */
5285     me = machine_entry_new("Artesyn's PM/PPC board", ARCH_PPC,
5286     MACHINE_PMPPC, 1, 0);
5287     me->aliases[0] = "pmppc";
5288     if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5289     me->next = first_machine_entry; first_machine_entry = me;
5290     }
5291    
5292     /* ARC: */
5293     me = machine_entry_new("ARC", ARCH_MIPS, MACHINE_ARC, 1, 8);
5294     me->aliases[0] = "arc";
5295    
5296     me->subtype[0] = machine_entry_subtype_new(
5297     "Acer PICA-61", MACHINE_ARC_JAZZ_PICA, 3);
5298     me->subtype[0]->aliases[0] = "pica-61";
5299     me->subtype[0]->aliases[1] = "acer pica";
5300     me->subtype[0]->aliases[2] = "pica";
5301    
5302     me->subtype[1] = machine_entry_subtype_new(
5303     "Deskstation Tyne", MACHINE_ARC_DESKTECH_TYNE, 3);
5304     me->subtype[1]->aliases[0] = "deskstation tyne";
5305     me->subtype[1]->aliases[1] = "desktech";
5306     me->subtype[1]->aliases[2] = "tyne";
5307    
5308     me->subtype[2] = machine_entry_subtype_new(
5309     "Jazz Magnum", MACHINE_ARC_JAZZ_MAGNUM, 2);
5310     me->subtype[2]->aliases[0] = "magnum";
5311     me->subtype[2]->aliases[1] = "jazz magnum";
5312    
5313     me->subtype[3] = machine_entry_subtype_new(
5314     "NEC-R94", MACHINE_ARC_NEC_R94, 2);
5315     me->subtype[3]->aliases[0] = "nec-r94";
5316     me->subtype[3]->aliases[1] = "r94";
5317    
5318     me->subtype[4] = machine_entry_subtype_new(
5319     "NEC-RD94", MACHINE_ARC_NEC_RD94, 2);
5320     me->subtype[4]->aliases[0] = "nec-rd94";
5321     me->subtype[4]->aliases[1] = "rd94";
5322    
5323     me->subtype[5] = machine_entry_subtype_new(
5324     "NEC-R96", MACHINE_ARC_NEC_R96, 2);
5325     me->subtype[5]->aliases[0] = "nec-r96";
5326     me->subtype[5]->aliases[1] = "r96";
5327    
5328     me->subtype[6] = machine_entry_subtype_new(
5329     "NEC-R98", MACHINE_ARC_NEC_R98, 2);
5330     me->subtype[6]->aliases[0] = "nec-r98";
5331     me->subtype[6]->aliases[1] = "r98";
5332    
5333     me->subtype[7] = machine_entry_subtype_new(
5334     "Olivetti M700", MACHINE_ARC_JAZZ_M700, 2);
5335     me->subtype[7]->aliases[0] = "olivetti";
5336     me->subtype[7]->aliases[1] = "m700";
5337    
5338     if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5339     me->next = first_machine_entry; first_machine_entry = me;
5340     }
5341     }
5342    

  ViewVC Help
Powered by ViewVC 1.1.26