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