sram.c revision 1.23 1 1.23 andvar /* $NetBSD: sram.c,v 1.23 2025/01/27 21:20:25 andvar Exp $ */
2 1.1 oki
3 1.1 oki /*
4 1.1 oki * Copyright (c) 1994 Kazuhisa Shimizu.
5 1.1 oki * All rights reserved.
6 1.1 oki *
7 1.1 oki * Redistribution and use in source and binary forms, with or without
8 1.1 oki * modification, are permitted provided that the following conditions
9 1.1 oki * are met:
10 1.1 oki * 1. Redistributions of source code must retain the above copyright
11 1.1 oki * notice, this list of conditions and the following disclaimer.
12 1.1 oki * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 oki * notice, this list of conditions and the following disclaimer in the
14 1.1 oki * documentation and/or other materials provided with the distribution.
15 1.1 oki * 3. All advertising materials mentioning features or use of this software
16 1.1 oki * must display the following acknowledgement:
17 1.1 oki * This product includes software developed by Kazuhisa Shimizu.
18 1.1 oki * 4. The name of the author may not be used to endorse or promote products
19 1.1 oki * derived from this software without specific prior written permission
20 1.1 oki *
21 1.1 oki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.1 oki * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.1 oki * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.1 oki * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.1 oki * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.1 oki * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.1 oki * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.1 oki * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.1 oki * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 1.1 oki * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.1 oki */
32 1.10 lukem
33 1.10 lukem #include <sys/cdefs.h>
34 1.23 andvar __KERNEL_RCSID(0, "$NetBSD: sram.c,v 1.23 2025/01/27 21:20:25 andvar Exp $");
35 1.1 oki
36 1.1 oki #include <sys/param.h>
37 1.18 isaki #include <sys/systm.h>
38 1.1 oki #include <sys/proc.h>
39 1.1 oki #include <sys/ioctl.h>
40 1.1 oki #include <sys/file.h>
41 1.8 gehenna #include <sys/conf.h>
42 1.17 isaki #include <sys/bus.h>
43 1.17 isaki #include <sys/device.h>
44 1.1 oki
45 1.1 oki #include <machine/sram.h>
46 1.17 isaki #include <x68k/dev/intiovar.h>
47 1.1 oki #include <x68k/dev/sramvar.h>
48 1.1 oki
49 1.21 tsutsui #include "ioconf.h"
50 1.21 tsutsui
51 1.18 isaki #define SRAM_ADDR (0xed0000)
52 1.1 oki
53 1.1 oki #ifdef DEBUG
54 1.1 oki #define SRAM_DEBUG_OPEN 0x01
55 1.1 oki #define SRAM_DEBUG_CLOSE 0x02
56 1.6 minoura #define SRAM_DEBUG_IOCTL 0x04
57 1.6 minoura #define SRAM_DEBUG_DONTDOIT 0x08
58 1.1 oki int sramdebug = SRAM_DEBUG_IOCTL;
59 1.18 isaki #define DPRINTF(flag, msg) do { \
60 1.18 isaki if ((sramdebug & (flag))) \
61 1.18 isaki printf msg; \
62 1.18 isaki } while (0)
63 1.18 isaki #else
64 1.18 isaki #define DPRINTF(flag, msg) /* nothing */
65 1.1 oki #endif
66 1.5 oki
67 1.18 isaki int srammatch(device_t, cfdata_t, void *);
68 1.18 isaki void sramattach(device_t, device_t, void *);
69 1.18 isaki
70 1.8 gehenna dev_type_open(sramopen);
71 1.8 gehenna dev_type_close(sramclose);
72 1.8 gehenna dev_type_ioctl(sramioctl);
73 1.8 gehenna
74 1.18 isaki CFATTACH_DECL_NEW(sram, sizeof(struct sram_softc),
75 1.18 isaki srammatch, sramattach, NULL, NULL);
76 1.18 isaki
77 1.8 gehenna const struct cdevsw sram_cdevsw = {
78 1.19 dholland .d_open = sramopen,
79 1.19 dholland .d_close = sramclose,
80 1.19 dholland .d_read = noread,
81 1.19 dholland .d_write = nowrite,
82 1.19 dholland .d_ioctl = sramioctl,
83 1.19 dholland .d_stop = nostop,
84 1.19 dholland .d_tty = notty,
85 1.19 dholland .d_poll = nopoll,
86 1.19 dholland .d_mmap = nommap,
87 1.19 dholland .d_kqfilter = nokqfilter,
88 1.20 dholland .d_discard = nodiscard,
89 1.19 dholland .d_flag = 0
90 1.8 gehenna };
91 1.1 oki
92 1.18 isaki static int sram_attached;
93 1.18 isaki
94 1.16 isaki /*
95 1.23 andvar * functions for probing.
96 1.1 oki */
97 1.18 isaki int
98 1.18 isaki srammatch(device_t parent, cfdata_t cf, void *aux)
99 1.18 isaki {
100 1.18 isaki struct intio_attach_args *ia = aux;
101 1.18 isaki
102 1.18 isaki if (sram_attached)
103 1.18 isaki return 0;
104 1.18 isaki
105 1.18 isaki if (ia->ia_addr == INTIOCF_ADDR_DEFAULT)
106 1.18 isaki ia->ia_addr = SRAM_ADDR;
107 1.18 isaki
108 1.18 isaki /* Fixed parameter */
109 1.18 isaki if (ia->ia_addr != SRAM_ADDR)
110 1.18 isaki return 0;
111 1.18 isaki
112 1.18 isaki return 1;
113 1.18 isaki }
114 1.18 isaki
115 1.16 isaki void
116 1.18 isaki sramattach(device_t parent, device_t self, void *aux)
117 1.1 oki {
118 1.18 isaki struct sram_softc *sc = device_private(self);
119 1.18 isaki struct intio_attach_args *ia = aux;
120 1.18 isaki bus_space_tag_t iot;
121 1.18 isaki bus_space_handle_t ioh;
122 1.18 isaki
123 1.18 isaki /* Map I/O space */
124 1.18 isaki iot = ia->ia_bst;
125 1.18 isaki if (bus_space_map(iot, ia->ia_addr, SRAM_SIZE, 0, &ioh))
126 1.18 isaki goto out;
127 1.18 isaki
128 1.18 isaki /* Initialize sc */
129 1.18 isaki sc->sc_iot = iot;
130 1.18 isaki sc->sc_ioh = ioh;
131 1.18 isaki
132 1.18 isaki sc->sc_flags = 0;
133 1.18 isaki aprint_normal(": 16k bytes accessible\n");
134 1.18 isaki sram_attached = 1;
135 1.18 isaki return;
136 1.18 isaki
137 1.18 isaki out:
138 1.18 isaki aprint_normal(": not accessible\n");
139 1.1 oki }
140 1.1 oki
141 1.1 oki
142 1.1 oki /*ARGSUSED*/
143 1.15 isaki int
144 1.12 christos sramopen(dev_t dev, int flags, int mode, struct lwp *l)
145 1.1 oki {
146 1.18 isaki struct sram_softc *sc;
147 1.1 oki
148 1.18 isaki DPRINTF(SRAM_DEBUG_OPEN, ("Sram open\n"));
149 1.1 oki
150 1.18 isaki sc = device_lookup_private(&sram_cd, minor(dev));
151 1.18 isaki if (sc == NULL)
152 1.18 isaki return ENXIO;
153 1.1 oki
154 1.18 isaki if (sc->sc_flags & SRF_OPEN)
155 1.18 isaki return EBUSY;
156 1.1 oki
157 1.18 isaki sc->sc_flags |= SRF_OPEN;
158 1.6 minoura if (flags & FREAD)
159 1.18 isaki sc->sc_flags |= SRF_READ;
160 1.6 minoura if (flags & FWRITE)
161 1.18 isaki sc->sc_flags |= SRF_WRITE;
162 1.6 minoura
163 1.18 isaki return 0;
164 1.1 oki }
165 1.1 oki
166 1.1 oki /*ARGSUSED*/
167 1.15 isaki int
168 1.12 christos sramclose(dev_t dev, int flags, int mode, struct lwp *l)
169 1.1 oki {
170 1.18 isaki struct sram_softc *sc;
171 1.18 isaki
172 1.18 isaki DPRINTF(SRAM_DEBUG_CLOSE, ("Sram close\n"));
173 1.1 oki
174 1.18 isaki sc = device_lookup_private(&sram_cd, minor(dev));
175 1.18 isaki if (sc == NULL)
176 1.18 isaki return ENXIO;
177 1.1 oki
178 1.18 isaki if (sc->sc_flags & SRF_OPEN) {
179 1.18 isaki sc->sc_flags = 0;
180 1.1 oki }
181 1.18 isaki sc->sc_flags &= ~(SRF_READ|SRF_WRITE);
182 1.8 gehenna
183 1.18 isaki return 0;
184 1.1 oki }
185 1.6 minoura
186 1.1 oki /*ARGSUSED*/
187 1.15 isaki int
188 1.14 christos sramioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
189 1.1 oki {
190 1.1 oki int error = 0;
191 1.1 oki struct sram_io *sram_io;
192 1.18 isaki struct sram_softc *sc;
193 1.18 isaki
194 1.18 isaki DPRINTF(SRAM_DEBUG_IOCTL, ("Sram ioctl cmd=%lx\n", cmd));
195 1.18 isaki
196 1.18 isaki sc = device_lookup_private(&sram_cd, minor(dev));
197 1.18 isaki if (sc == NULL)
198 1.18 isaki return ENXIO;
199 1.1 oki
200 1.1 oki sram_io = (struct sram_io *)data;
201 1.18 isaki if (sram_io == NULL)
202 1.18 isaki return EFAULT;
203 1.1 oki
204 1.1 oki switch (cmd) {
205 1.1 oki case SIOGSRAM:
206 1.18 isaki if ((sc->sc_flags & SRF_READ) == 0)
207 1.18 isaki return EPERM;
208 1.18 isaki DPRINTF(SRAM_DEBUG_IOCTL,
209 1.18 isaki ("Sram ioctl SIOGSRAM address=%p\n", data));
210 1.18 isaki DPRINTF(SRAM_DEBUG_IOCTL,
211 1.18 isaki ("Sram ioctl SIOGSRAM offset=%x\n", sram_io->offset));
212 1.18 isaki if (sram_io->offset + SRAM_IO_SIZE > SRAM_SIZE)
213 1.18 isaki return EFAULT;
214 1.18 isaki bus_space_read_region_1(sc->sc_iot, sc->sc_ioh, sram_io->offset,
215 1.18 isaki (uint8_t *)&sram_io->sram, SRAM_IO_SIZE);
216 1.1 oki break;
217 1.1 oki case SIOPSRAM:
218 1.18 isaki if ((sc->sc_flags & SRF_WRITE) == 0)
219 1.18 isaki return EPERM;
220 1.18 isaki DPRINTF(SRAM_DEBUG_IOCTL,
221 1.22 isaki ("Sram ioctl SIOPSRAM address=%p\n", data));
222 1.18 isaki DPRINTF(SRAM_DEBUG_IOCTL,
223 1.22 isaki ("Sram ioctl SIOPSRAM offset=%x\n", sram_io->offset));
224 1.18 isaki if (sram_io->offset + SRAM_IO_SIZE > SRAM_SIZE)
225 1.18 isaki return EFAULT;
226 1.6 minoura #ifdef DEBUG
227 1.6 minoura if (sramdebug & SRAM_DEBUG_DONTDOIT) {
228 1.16 isaki printf("Sram ioctl SIOPSRAM: skipping actual write\n");
229 1.6 minoura break;
230 1.6 minoura }
231 1.6 minoura #endif
232 1.17 isaki intio_set_sysport_sramwp(0x31);
233 1.18 isaki bus_space_write_region_1(sc->sc_iot, sc->sc_ioh,
234 1.18 isaki sram_io->offset, (uint8_t *)&sram_io->sram,
235 1.18 isaki SRAM_IO_SIZE);
236 1.17 isaki intio_set_sysport_sramwp(0x00);
237 1.1 oki break;
238 1.1 oki default:
239 1.1 oki error = EINVAL;
240 1.1 oki break;
241 1.1 oki }
242 1.18 isaki return error;
243 1.1 oki }
244