1 /*
2  *  Copyright (C) 2007-2009  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  *  COMMENT: VME bus
29  *
30  *  TODO: Probably almost everything.
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include "cpu.h"
38 #include "device.h"
39 #include "emul.h"
40 #include "machine.h"
41 #include "memory.h"
42 #include "misc.h"
43 
44 #include "thirdparty/mvme88k_vme.h"
45 
46 
47 /*  #define debug fatal  */
48 
49 
50 #define	VME_LEN			0x1000
51 
52 struct vme_data {
53 	uint32_t	reg[VME_LEN / sizeof(uint32_t)];
54 };
55 
56 
DEVICE_ACCESS(vme)57 DEVICE_ACCESS(vme)
58 {
59 	struct vme_data *d = (struct vme_data *) extra;
60 	uint64_t idata = 0, odata = 0;
61 
62 	if (writeflag == MEM_WRITE)
63 		idata = memory_readmax64(cpu, data, len);
64 
65 	if (writeflag == MEM_READ)
66 		odata = d->reg[relative_addr / sizeof(uint32_t)];
67 
68 	switch (relative_addr) {
69 
70 	case 0:	/*  Used by OpenBSD/mvme88k when probing...  */
71 		break;
72 
73 	case VME2_GCSRCTL:
74 		debug("[ vme: unimplemented GCSRCTL ]\n");
75 		break;
76 
77 	case VME2_TCR:
78 		if (writeflag == MEM_READ)
79 			debug("[ vme: unimplemented READ from TCR ]\n");
80 		else
81 			debug("[ vme: unimplemented WRITE to TCR: "
82 			    "0x%x ]\n", (int)idata);
83 		break;
84 
85 	case VME2_T1CMP:
86 		if (writeflag == MEM_WRITE)
87 			d->reg[relative_addr / sizeof(uint32_t)] = idata;
88 		break;
89 
90 	case VME2_T1COUNT:
91 		if (writeflag == MEM_WRITE)
92 			d->reg[relative_addr / sizeof(uint32_t)] = idata;
93 		else {
94 			/*  NOTE! This is a quick hack. TODO: Fix!  */
95 			d->reg[relative_addr / sizeof(uint32_t)] += 100;
96 		}
97 		break;
98 
99 	case VME2_TCTL:
100 		if (writeflag == MEM_WRITE)
101 			d->reg[relative_addr / sizeof(uint32_t)] = idata;
102 
103 		/*  TODO  */
104 		/*  debug("[ vme: unimplemented TCTL ]\n");  */
105 		break;
106 
107 	case VME2_IRQEN:
108 		if (writeflag == MEM_READ)
109 			debug("[ vme: unimplemented READ from IRQEN ]\n");
110 		else
111 			debug("[ vme: unimplemented WRITE to IRQEN: "
112 			    "0x%x ]\n", (int)idata);
113 		break;
114 
115 	case VME2_IRQL3:
116 		if (writeflag == MEM_READ)
117 			debug("[ vme: unimplemented READ from IRQL3 ]\n");
118 		else
119 			debug("[ vme: unimplemented WRITE to IRQL3: "
120 			    "0x%x ]\n", (int)idata);
121 		break;
122 
123 	case VME2_IRQL4:
124 		if (writeflag == MEM_READ)
125 			debug("[ vme: unimplemented READ from IRQL4 ]\n");
126 		else
127 			debug("[ vme: unimplemented WRITE to IRQL4: "
128 			    "0x%x ]\n", (int)idata);
129 		break;
130 
131 	case VME2_VBR:
132 		/*  Vector Base Register.  */
133 		if (writeflag == MEM_WRITE)
134 			d->reg[relative_addr / sizeof(uint32_t)] = idata;
135 		break;
136 
137 	default:if (writeflag == MEM_READ)
138 			debug("[ vme: unimplemented READ from offset 0x%x ]"
139 			    "\n", (int)relative_addr);
140 		else
141 			debug("[ vme: unimplemented WRITE to offset 0x%x: "
142 			    "0x%x ]\n", (int)relative_addr, (int)idata);
143 		exit(1);
144 	}
145 
146 	if (writeflag == MEM_READ)
147 		memory_writemax64(cpu, data, len, odata);
148 
149 	return 1;
150 }
151 
152 
DEVINIT(vme)153 DEVINIT(vme)
154 {
155 	struct vme_data *d;
156 
157 	CHECK_ALLOCATION(d = (struct vme_data *) malloc(sizeof(struct vme_data)));
158 	memset(d, 0, sizeof(struct vme_data));
159 
160 	/*  According to OpenBSD/mvme88k:  */
161 	d->reg[VME2_VBR / sizeof(uint32_t)] =
162 	    VME2_SET_VBR0(6) + VME2_SET_VBR1(7);
163 
164 	memory_device_register(devinit->machine->memory, devinit->name,
165 	    devinit->addr, VME_LEN, dev_vme_access, (void *)d,
166 	    DM_DEFAULT, NULL);
167 
168 	return 1;
169 }
170 
171