1 /*
2 * Copyright (C) 2004-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: DEC KN220 (DECsystem 5500) devices
29 *
30 * o) I/O board
31 * o) SGEC (ethernet) (Called "ne" in Ultrix.)
32 *
33 * TODO: Study docs.
34 */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "devices.h"
41 #include "memory.h"
42 #include "misc.h"
43
44 #define IOBOARD_DEBUG
45
46 struct dec5500_ioboard_data {
47 int dummy;
48 };
49
50 #define SGEC_DEBUG
51
52 struct sgec_data {
53 int irq_nr;
54 };
55
56
57 /*
58 * dev_dec5500_ioboard_access():
59 */
DEVICE_ACCESS(dec5500_ioboard)60 DEVICE_ACCESS(dec5500_ioboard)
61 {
62 /* struct dec5500_ioboard_data *d =
63 (struct dec5500_ioboard_data *) extra; */
64 uint64_t idata = 0, odata = 0;
65
66 if (writeflag == MEM_WRITE)
67 idata = memory_readmax64(cpu, data, len);
68
69 #ifdef IOBOARD_DEBUG
70 if (writeflag == MEM_WRITE)
71 debug("[ dec5500_ioboard: write to address 0x%llx, "
72 "data=0x%016llx ]\n", (long long)relative_addr,
73 (long long)idata);
74 else
75 debug("[ dec5500_ioboard: read from address 0x%llx ]\n",
76 (long long)relative_addr);
77 #endif
78
79 switch (relative_addr) {
80 case 0:
81 if (writeflag == MEM_READ)
82 /*
83 * TODO: One of these bits indicate I/O board
84 * present.
85 */
86 odata = 0xffffffffULL;
87 break;
88
89 default:
90 if (writeflag == MEM_WRITE)
91 debug("[ dec5500_ioboard: unimplemented write to "
92 "address 0x%llx, data=0x%016llx ]\n",
93 (long long)relative_addr, (long long)idata);
94 else
95 debug("[ dec5500_ioboard: unimplemented read from"
96 " address 0x%llx ]\n", (long long)relative_addr);
97 }
98
99 if (writeflag == MEM_READ)
100 memory_writemax64(cpu, data, len, odata);
101
102 return 1;
103 }
104
105
106 /*
107 * dev_sgec_access():
108 */
DEVICE_ACCESS(sgec)109 DEVICE_ACCESS(sgec)
110 {
111 /* struct sgec_data *d = (struct sgec_data *) extra; */
112 uint64_t idata = 0, odata = 0;
113
114 idata = memory_readmax64(cpu, data, len);
115
116 #ifdef SGEC_DEBUG
117 if (writeflag == MEM_WRITE)
118 debug("[ sgec: write to address 0x%llx, data=0x%016llx ]\n",
119 (long long)relative_addr, (long long)idata);
120 else
121 debug("[ sgec: read from address 0x%llx ]\n",
122 (long long)relative_addr);
123 #endif
124
125 switch (relative_addr) {
126 case 0x14:
127 if (writeflag == MEM_READ)
128 odata = 0x80000000;
129 break;
130
131 default:
132 if (writeflag == MEM_WRITE)
133 debug("[ sgec: unimplemented write to address 0x%llx,"
134 " data=0x%016llx ]\n", (long long)relative_addr,
135 (long long)idata);
136 else
137 debug("[ sgec: unimplemented read from address "
138 "0x%llx ]\n", (long long)relative_addr);
139 }
140
141 if (writeflag == MEM_READ)
142 memory_writemax64(cpu, data, len, odata);
143
144 return 1;
145 }
146
147
148 /*
149 * dev_sgec_init():
150 */
dev_sgec_init(struct memory * mem,uint64_t baseaddr,int irq_nr)151 void dev_sgec_init(struct memory *mem, uint64_t baseaddr, int irq_nr)
152 {
153 struct sgec_data *d;
154
155 CHECK_ALLOCATION(d = (struct sgec_data *) malloc(sizeof(struct sgec_data)));
156 memset(d, 0, sizeof(struct sgec_data));
157
158 d->irq_nr = irq_nr;
159
160 memory_device_register(mem, "sgec", baseaddr, DEV_SGEC_LENGTH,
161 dev_sgec_access, (void *)d, DM_DEFAULT, NULL);
162 }
163
164
165 /*
166 * dev_dec5500_ioboard_init():
167 */
dev_dec5500_ioboard_init(struct cpu * cpu,struct memory * mem,uint64_t baseaddr)168 struct dec5500_ioboard_data *dev_dec5500_ioboard_init(struct cpu *cpu,
169 struct memory *mem, uint64_t baseaddr)
170 {
171 struct dec5500_ioboard_data *d;
172
173 CHECK_ALLOCATION(d = (struct dec5500_ioboard_data *) malloc(sizeof(struct dec5500_ioboard_data)));
174 memset(d, 0, sizeof(struct dec5500_ioboard_data));
175
176 memory_device_register(mem, "dec5500_ioboard", baseaddr,
177 DEV_DEC5500_IOBOARD_LENGTH, dev_dec5500_ioboard_access,
178 (void *)d, DM_DEFAULT, NULL);
179
180 return d;
181 }
182
183