|
|
1.1 root 1: #! /bin/sh
2:
3: # $Id: m68k-bus-auto.sh,v 1.2 2003/04/23 19:13:29 fredette Exp $
4:
5: # ic/m68k/m68k-bus-auto.sh - automatically generates C code
6: # for m68k bus emulation support:
7:
8: #
9: # Copyright (c) 2003 Matt Fredette
10: # All rights reserved.
11: #
12: # Redistribution and use in source and binary forms, with or without
13: # modification, are permitted provided that the following conditions
14: # are met:
15: # 1. Redistributions of source code must retain the above copyright
16: # notice, this list of conditions and the following disclaimer.
17: # 2. Redistributions in binary form must reproduce the above copyright
18: # notice, this list of conditions and the following disclaimer in the
19: # documentation and/or other materials provided with the distribution.
20: # 3. All advertising materials mentioning features or use of this software
21: # must display the following acknowledgement:
22: # This product includes software developed by Matt Fredette.
23: # 4. The name of the author may not be used to endorse or promote products
24: # derived from this software without specific prior written permission.
25: #
26: # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27: # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28: # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29: # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
30: # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31: # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32: # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34: # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35: # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: # POSSIBILITY OF SUCH DAMAGE.
37: #
38:
39: header=false
40:
41: for option
42: do
43: case $option in
44: --header) header=true ;;
45: esac
46: done
47:
48: PROG=`basename $0`
49: cat <<EOF
50: /* automatically generated by $PROG, do not edit! */
51: _TME_RCSID("\$Id: m68k-bus-auto.sh,v 1.2 2003/04/23 19:13:29 fredette Exp $");
52:
53: /* we use OP3, OP2, OP1, and OP0 to represent bytes of lesser
54: significance to more significance, respectively, matching Table 5-5
55: in the MC68020 User's Manual (linear page 56 in my .ps copy).
56:
57: the Motorola OPn convention numbers bytes by decreasing
58: significance (OP2 is less significant than OP1), and since Motorola
59: CPUs are big-endian, this means that a higher numbered byte is
60: meant to go to a higher address, which is good, because we can then
61: use this to easily form indexes for TME_BUS_LANE_ROUTE, which
62: expects a higher numbered index to correspond to a higher address
63: in memory.
64:
65: however, since the same Motorola OPn convention always calls the
66: least significant byte of any value OP3, regardless of the total
67: size of the value, we need to adjust each OPn given the total
68: size of the value, so that OP3 in a 24-bit value means address + 2,
69: but OP3 in a 32-bit value means address + 3: */
70: #define SIZ8_OP(n) ((n) - 3)
71: #define SIZ16_OP(n) ((n) - 2)
72: #define SIZ24_OP(n) ((n) - 1)
73: #define SIZ32_OP(n) ((n) - 0)
74: EOF
75:
76: # emit the 16-bit bus router:
77: if $header; then :; else
78: echo ""
79: echo "/* the 16-bit bus router used on the 68000 and 68010: */"
80: echo "const tme_bus_lane_t tme_m68k_router_16[TME_M68K_BUS_ROUTER_SIZE(TME_BUS16_LOG2)] = {"
81:
82: # permute over maximum cycle size:
83: for transfer in 1 2; do
84:
85: # permute over A0:
86: for address in 0 1; do
87: address_bits=$address
88:
89: # permute over the size of the responding device's port:
90: for port_size in 1 2; do
91:
92: # permute over the byte lane position of the responding device's port:
93: for port_pos in 0 1; do
94:
95: # get a string describing the byte lanes driven by
96: # this device:
97: port_pos_end=`expr ${port_pos} + ${port_size}`
98: port_pos_lane=$port_pos
99: port_lanes=""
100: while test `expr ${port_pos_lane} \< ${port_pos_end}` = 1; do
101: port_lanes=" D"`expr \( \( ${port_pos_lane} + 1 \) \* 8 \) - 1`"-D"`expr ${port_pos_lane} \* 8`"${port_lanes}"
102: port_pos_lane=`expr ${port_pos_lane} + 1`
103: done
104: if test `expr ${port_pos_end} \> 2` = 1; then
105: port_lanes="${port_lanes} - invalid, array placeholder"
106: elif test $transfer = 1 \
107: && test $port_size = 1 \
108: && test $port_pos != `expr 1 - ${address}`; then
109: port_lanes="${port_lanes} - incorrect for 16-bit m68k"
110: fi
111:
112: echo ""
113: echo " /* [m68k] initiator maximum cycle size: "`expr ${transfer} \* 8`" bits"
114: echo " [m68k] initiator A0: ${address_bits}"
115: echo " [gen] responding port size: "`expr ${port_size} \* 8`" bits"
116: echo " [gen] responding port least lane: ${port_pos} (lanes${port_lanes})"
117: echo " (code ${transfer}.${address}.${port_size}.${port_pos}): */"
118:
119: # emit the bus router information for each lane:
120: for lane in 0 1; do
121:
122: # dispatch:
123: lane_warn=
124: case "${transfer}:${address}:${lane}" in
125: 2:0:1)
126: lane_read="OP(2)"
127: lane_write="OP(2)"
128: ;;
129: 2:0:0)
130: lane_read="OP(3)"
131: lane_write="OP(3)"
132: ;;
133: 2:1:[01])
134: lane_read="ABORT"
135: lane_write="ABORT"
136: ;;
137: 1:0:1 | 1:1:0)
138: lane_read="OP(3)"
139: lane_write="OP(3)"
140: ;;
141: 1:0:0 | 1:1:1)
142: lane_read="IGNORE"
143: lane_write="OP(3)"
144: if test $port_size = 1 \
145: && test $port_pos != `expr 1 - ${address}`; then
146: lane_warn=" | TME_BUS_LANE_WARN"
147: fi
148: ;;
149: *)
150: echo "$PROG internal error: unhandled 16-bit bus case ${transfer}:${address}:${lane}" 1>&2
151: exit 1
152: ;;
153: esac
154:
155: # emit the comment for this lane:
156: echo -n " /* D"`expr \( \( ${lane} + 1 \) \* 8 \) - 1`"-D"`expr ${lane} \* 8`" */ "
157:
158: # if this port size/position combination is
159: # invalid, override everything and abort if
160: # this router entry is ever touched:
161: if test `expr ${port_pos_end} \> 2` = 1; then
162: echo "TME_BUS_LANE_ABORT,"
163: else
164: if test $lane_read = "ABORT"; then
165: echo -n "TME_BUS_LANE_ABORT"
166: elif test $lane_read != "IGNORE"; then
167: if test $lane_read != $lane_write; then
168: echo "$PROG internal error: code ${transfer}:${address}:${lane}, reading $lane_read but writing $lane_write" 1>&2
169: exit 1
170: fi
171: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_read)"
172: else
173: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_write) | TME_BUS_LANE_ROUTE_WRITE_IGNORE"
174: fi
175: echo "${lane_warn},"
176: fi
177: done
178: done
179: done
180: done
181: done
182: echo "};"
183: fi
184:
185: # emit the 32-bit bus router:
186: if $header; then :; else
187: echo ""
188: echo "/* the 32-bit bus router used on the 68020 and 68030: */"
189: echo "static const tme_bus_lane_t tme_m68k_router_32[TME_M68K_BUS_ROUTER_SIZE(TME_BUS32_LOG2)] = {"
190:
191: # permute over maximum cycle size:
192: for transfer in 1 2 3 4; do
193: # these are real 68020 SIZ1 and SIZ0 bits:
194: case ${transfer} in
195: 1) transfer_bits="01" ;;
196: 2) transfer_bits="10" ;;
197: 3) transfer_bits="11" ;;
198: 4) transfer_bits="00" ;;
199: esac
200:
201: # permute over A1 and A0:
202: for address in 0 1 2 3; do
203: case $address in
204: 0) address_bits=00 ;;
205: 1) address_bits=01 ;;
206: 2) address_bits=10 ;;
207: 3) address_bits=11 ;;
208: esac
209:
210: # permute over the size of the responding device's port:
211: for port_size in 1 2 4; do
212:
213: # permute over the byte lane position of the responding device's port:
214: for port_pos in 0 1 2 3; do
215:
216: # get a string describing the byte lanes connected
217: # to this device. NB that the m68k 32-bit bus
218: # router assumes that 8-bit devices are always
219: # connected to D31-D24, and that 16-bit devices
220: # are always connected to D31-D24 and D23-D16, and
221: # cannot dynamically adapt to other
222: # configurations:
223: port_pos_end=`expr ${port_pos} + ${port_size}`
224: port_pos_lane=$port_pos
225: port_lanes=""
226: while test `expr ${port_pos_lane} \< ${port_pos_end}` = 1; do
227: port_lanes=" D"`expr \( \( ${port_pos_lane} + 1 \) \* 8 \) - 1`"-D"`expr ${port_pos_lane} \* 8`"${port_lanes}"
228: port_pos_lane=`expr ${port_pos_lane} + 1`
229: done
230: if test `expr ${port_pos_end} \> 4` = 1; then
231: port_lanes="${port_lanes} - invalid, array placeholder"
232: elif ( test $port_size = 1 && test $port_pos != 3 ) \
233: || ( test $port_size = 2 && test $port_pos != 2 ); then
234: port_lanes="${port_lanes} - incorrect for 32-bit m68k"
235: fi
236:
237: # find the byte lane that would provide OP3. note
238: # that it may not exist (lane < 0), or that it may
239: # not be within the port:
240: opn=`expr 4 - ${transfer}`
241: opn_lane=`expr 3 - \( ${address} % ${port_size} \)`
242: op3_lane=`expr ${opn_lane} - \( 3 - ${opn} \)`
243:
244: echo ""
245: echo " /* [m68k] initiator maximum cycle size: "`expr ${transfer} \* 8`" bits"
246: echo " [m68k] initiator A1,A0: ${address_bits}"
247: echo " [gen] responder port size: "`expr ${port_size} \* 8`" bits"
248: echo " [gen] responder port least lane: ${port_pos} (lanes${port_lanes})"
249: echo " (code ${transfer}.${address}.${port_size}.${port_pos}, OP3 lane ${op3_lane}): */"
250:
251: # emit the bus router information for each lane:
252: for lane in 0 1 2 3; do
253: lane_warn=
254:
255: # if the m68k expects this byte lane to be connected
256: # to the device at this port size:
257: if test `expr ${lane} \< \( 4 - ${port_size} \)` = 0; then
258:
259: # if this lane is routed by the m68k when
260: # reading at this transfer size and
261: # address alignment:
262: opn=`expr 3 - \( ${lane} - ${op3_lane} \)`
263: if test `expr ${opn} \> 3` = 0 \
264: && test `expr ${opn} \< \( 4 - ${transfer} \)` = 0; then
265: lane_read="OP(${opn})"
266:
267: # otherwise this lane isn't routed by the
268: # m68k when reading at this transfer size
269: # and address alignment:
270: else
271: lane_read="IGNORE"
272: fi
273:
274: # otherwise the m68k does not expect this byte
275: # lane to be connected to the device at this
276: # port size:
277: else
278: lane_read="IGNORE"
279:
280: # if this lane is connected to the device
281: # anyways, issue a warning:
282: if test `expr ${lane} \< ${port_pos}` = 0 \
283: && test `expr ${lane} \< ${port_pos_end}` = 1; then
284: lane_warn=" | TME_BUS_LANE_WARN"
285: fi
286: fi
287:
288: # dispatch on how this lane is routed by the
289: # m68k when writing at this transfer size and
290: # address alignment:
291: case "${transfer_bits}${address_bits}.${lane}" in
292: 01??.3) lane_write="OP(3)" ;;
293: 01??.2) lane_write="OP(3)" ;;
294: 01??.1) lane_write="OP(3)" ;;
295: 01??.0) lane_write="OP(3)" ;;
296:
297: 10?0.3) lane_write="OP(2)" ;;
298: 10?0.2) lane_write="OP(3)" ;;
299: 10?0.1) lane_write="OP(2)" ;;
300: 10?0.0) lane_write="OP(3)" ;;
301:
302: 10?1.3) lane_write="OP(2)" ;;
303: 10?1.2) lane_write="OP(2)" ;;
304: 10?1.1) lane_write="OP(3)" ;;
305: 10?1.0) lane_write="OP(2)" ;;
306:
307: 1100.3) lane_write="OP(1)" ;;
308: 1100.2) lane_write="OP(2)" ;;
309: 1100.1) lane_write="OP(3)" ;;
310: 1100.0) lane_write="UNDEF" ;; # XXX this is supposed to be OP0, but we can't deal with that
311:
312: 1101.3) lane_write="OP(1)" ;;
313: 1101.2) lane_write="OP(1)" ;;
314: 1101.1) lane_write="OP(2)" ;;
315: 1101.0) lane_write="OP(3)" ;;
316:
317: 1110.3) lane_write="OP(1)" ;;
318: 1110.2) lane_write="OP(2)" ;;
319: 1110.1) lane_write="OP(1)" ;;
320: 1110.0) lane_write="OP(2)" ;;
321:
322: 1111.3) lane_write="OP(1)" ;;
323: 1111.2) lane_write="OP(1)" ;;
324: 1111.1) lane_write="OP(2)" ;;
325: 1111.0) lane_write="OP(1)" ;;
326:
327: 0000.3) lane_write="OP(0)" ;;
328: 0000.2) lane_write="OP(1)" ;;
329: 0000.1) lane_write="OP(2)" ;;
330: 0000.0) lane_write="OP(3)" ;;
331:
332: 0001.3) lane_write="OP(0)" ;;
333: 0001.2) lane_write="OP(0)" ;;
334: 0001.1) lane_write="OP(1)" ;;
335: 0001.0) lane_write="OP(2)" ;;
336:
337: 0010.3) lane_write="OP(0)" ;;
338: 0010.2) lane_write="OP(1)" ;;
339: 0010.1) lane_write="OP(0)" ;;
340: 0010.0) lane_write="OP(1)" ;;
341:
342: 0011.3) lane_write="OP(0)" ;;
343: 0011.2) lane_write="OP(0)" ;;
344: 0011.1) lane_write="OP(1)" ;;
345: 0011.0) lane_write="OP(0)" ;;
346:
347: esac
348:
349: # emit the comment for this lane:
350: echo -n " /* D"`expr \( \( ${lane} + 1 \) \* 8 \) - 1`"-D"`expr ${lane} \* 8`" */ "
351:
352: # if this port size/position combination is
353: # invalid, override everything and abort if
354: # this router entry is ever touched:
355: if test `expr ${port_pos_end} \> 4` = 1; then
356: echo "TME_BUS_LANE_ABORT,"
357: else
358: if test $lane_read != "IGNORE"; then
359: if test $lane_read != $lane_write; then
360: echo "$PROG internal error: code ${transfer}.${address}.${port_size}.${port_pos}, reading $lane_read but writing $lane_write" 1>&2
361: exit 1
362: fi
363: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_read)"
364: elif test $lane_write = "UNDEF"; then
365: echo -n "TME_BUS_LANE_UNDEF"
366: else
367: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_write) | TME_BUS_LANE_ROUTE_WRITE_IGNORE"
368: fi
369: echo "${lane_warn},"
370: fi
371: done
372: done
373: done
374: done
375: done
376: echo "};"
377: fi
378:
379: cat <<EOF
380: #undef SIZ8_OP
381: #undef SIZ16_OP
382: #undef SIZ24_OP
383: #undef SIZ32_OP
384: EOF
385:
386: # done:
387: exit 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.