|
|
1.1 root 1: #! /bin/sh
2:
3: # $Id: sparc-bus-auto.sh,v 1.1 2006/09/30 12:55:59 fredette Exp $
4:
5: # ic/sparc/sparc-bus-auto.sh - automatically generates C code
6: # for SPARC bus emulation support:
7:
8: #
9: # Copyright (c) 2003, 2005 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: sparc-bus-auto.sh,v 1.1 2006/09/30 12:55:59 fredette Exp $");
52:
53: /* it was easiest, but probably not the most correct, to reuse the
54: m68020 bus router, at least for the early SPARCs. there are
55: probably real differences between the m68020 bus router and the bus
56: router used by the MB89600, for example, but I don't have a
57: datasheet for the latter. the placement of devices in the Sun
58: 4/2x0 address space, however, hints that the two probably are very
59: similar. */
60:
61: /* we use OP3, OP2, OP1, and OP0 to represent bytes of lesser
62: significance to more significance, respectively, matching Table 5-5
63: in the MC68020 User's Manual (linear page 56 in my .ps copy).
64:
65: the Motorola OPn convention numbers bytes by decreasing
66: significance (OP2 is less significant than OP1), and since Motorola
67: CPUs are big-endian, this means that a higher numbered byte is
68: meant to go to a higher address, which is good, because we can then
69: use this to easily form indexes for TME_BUS_LANE_ROUTE, which
70: expects a higher numbered index to correspond to a higher address
71: in memory.
72:
73: however, since the same Motorola OPn convention always calls the
74: least significant byte of any value OP3, regardless of the total
75: size of the value, we need to adjust each OPn given the total
76: size of the value, so that OP3 in a 24-bit value means address + 2,
77: but OP3 in a 32-bit value means address + 3: */
78: #define SIZ8_OP(n) ((n) - 3)
79: #define SIZ16_OP(n) ((n) - 2)
80: #define SIZ24_OP(n) ((n) - 1)
81: #define SIZ32_OP(n) ((n) - 0)
82: EOF
83:
84: # emit the 32-bit bus router:
85: if $header; then :; else
86: echo ""
87: echo "/* the 32-bit bus router used on the early SPARCs: */"
88: echo "static const tme_bus_lane_t tme_sparc32_router[TME_SPARC_BUS_ROUTER_SIZE(TME_BUS32_LOG2)] = {"
89:
90: # permute over maximum cycle size:
91: for transfer in 1 2 3 4; do
92: # these are real 68020 SIZ1 and SIZ0 bits:
93: case ${transfer} in
94: 1) transfer_bits="01" ;;
95: 2) transfer_bits="10" ;;
96: 3) transfer_bits="11" ;;
97: 4) transfer_bits="00" ;;
98: esac
99:
100: # permute over A1 and A0:
101: for address in 0 1 2 3; do
102: case $address in
103: 0) address_bits=00 ;;
104: 1) address_bits=01 ;;
105: 2) address_bits=10 ;;
106: 3) address_bits=11 ;;
107: esac
108:
109: # permute over the size of the responding device's port:
110: for port_size in 1 2 4; do
111:
112: # permute over the byte lane position of the responding device's port:
113: for port_pos in 0 1 2 3; do
114:
115: # get a string describing the byte lanes connected
116: # to this device. NB that the sparc 32-bit bus
117: # router assumes that 8-bit devices are always
118: # connected to D31-D24, and that 16-bit devices
119: # are always connected to D31-D24 and D23-D16, and
120: # cannot dynamically adapt to other
121: # configurations:
122: port_pos_end=`expr ${port_pos} + ${port_size}`
123: port_pos_lane=$port_pos
124: port_lanes=""
125: while test `expr ${port_pos_lane} \< ${port_pos_end}` = 1; do
126: port_lanes=" D"`expr \( \( ${port_pos_lane} + 1 \) \* 8 \) - 1`"-D"`expr ${port_pos_lane} \* 8`"${port_lanes}"
127: port_pos_lane=`expr ${port_pos_lane} + 1`
128: done
129: if test `expr ${port_pos_end} \> 4` = 1; then
130: port_lanes="${port_lanes} - invalid, array placeholder"
131: elif ( test $port_size = 1 && test $port_pos != 3 ) \
132: || ( test $port_size = 2 && test $port_pos != 2 ); then
133: port_lanes="${port_lanes} - incorrect for 32-bit sparc"
134: fi
135:
136: # find the byte lane that would provide OP3. note
137: # that it may not exist (lane < 0), or that it may
138: # not be within the port:
139: opn=`expr 4 - ${transfer}`
140: opn_lane=`expr 3 - \( ${address} % ${port_size} \)`
141: op3_lane=`expr ${opn_lane} - \( 3 - ${opn} \)`
142:
143: echo ""
144: echo " /* [sparc] initiator maximum cycle size: "`expr ${transfer} \* 8`" bits"
145: echo " [sparc] initiator A1,A0: ${address_bits}"
146: echo " [gen] responder port size: "`expr ${port_size} \* 8`" bits"
147: echo " [gen] responder port least lane: ${port_pos} (lanes${port_lanes})"
148: echo " (code ${transfer}.${address}.${port_size}.${port_pos}, OP3 lane ${op3_lane}): */"
149:
150: # emit the bus router information for each lane:
151: for lane in 0 1 2 3; do
152: lane_warn=
153:
154: # if the sparc expects this byte lane to be connected
155: # to the device at this port size:
156: if test `expr ${lane} \< \( 4 - ${port_size} \)` = 0; then
157:
158: # if this lane is routed by the sparc when
159: # reading at this transfer size and
160: # address alignment:
161: opn=`expr 3 - \( ${lane} - ${op3_lane} \)`
162: if test `expr ${opn} \> 3` = 0 \
163: && test `expr ${opn} \< \( 4 - ${transfer} \)` = 0; then
164: lane_read="OP(${opn})"
165:
166: # otherwise this lane isn't routed by the
167: # sparc when reading at this transfer size
168: # and address alignment:
169: else
170: lane_read="IGNORE"
171: fi
172:
173: # otherwise the sparc does not expect this byte
174: # lane to be connected to the device at this
175: # port size:
176: else
177: lane_read="IGNORE"
178:
179: # if this lane is connected to the device
180: # anyways, issue a warning:
181: if test `expr ${lane} \< ${port_pos}` = 0 \
182: && test `expr ${lane} \< ${port_pos_end}` = 1; then
183: lane_warn=" | TME_BUS_LANE_WARN"
184: fi
185: fi
186:
187: # dispatch on how this lane is routed by the
188: # sparc when writing at this transfer size and
189: # address alignment:
190: case "${transfer_bits}${address_bits}.${lane}" in
191: 01??.3) lane_write="OP(3)" ;;
192: 01??.2) lane_write="OP(3)" ;;
193: 01??.1) lane_write="OP(3)" ;;
194: 01??.0) lane_write="OP(3)" ;;
195:
196: 10?0.3) lane_write="OP(2)" ;;
197: 10?0.2) lane_write="OP(3)" ;;
198: 10?0.1) lane_write="OP(2)" ;;
199: 10?0.0) lane_write="OP(3)" ;;
200:
201: 10?1.3) lane_write="OP(2)" ;;
202: 10?1.2) lane_write="OP(2)" ;;
203: 10?1.1) lane_write="OP(3)" ;;
204: 10?1.0) lane_write="OP(2)" ;;
205:
206: 1100.3) lane_write="OP(1)" ;;
207: 1100.2) lane_write="OP(2)" ;;
208: 1100.1) lane_write="OP(3)" ;;
209: 1100.0) lane_write="UNDEF" ;; # XXX this is supposed to be OP0, but we can't deal with that
210:
211: 1101.3) lane_write="OP(1)" ;;
212: 1101.2) lane_write="OP(1)" ;;
213: 1101.1) lane_write="OP(2)" ;;
214: 1101.0) lane_write="OP(3)" ;;
215:
216: 1110.3) lane_write="OP(1)" ;;
217: 1110.2) lane_write="OP(2)" ;;
218: 1110.1) lane_write="OP(1)" ;;
219: 1110.0) lane_write="OP(2)" ;;
220:
221: 1111.3) lane_write="OP(1)" ;;
222: 1111.2) lane_write="OP(1)" ;;
223: 1111.1) lane_write="OP(2)" ;;
224: 1111.0) lane_write="OP(1)" ;;
225:
226: 0000.3) lane_write="OP(0)" ;;
227: 0000.2) lane_write="OP(1)" ;;
228: 0000.1) lane_write="OP(2)" ;;
229: 0000.0) lane_write="OP(3)" ;;
230:
231: 0001.3) lane_write="OP(0)" ;;
232: 0001.2) lane_write="OP(0)" ;;
233: 0001.1) lane_write="OP(1)" ;;
234: 0001.0) lane_write="OP(2)" ;;
235:
236: 0010.3) lane_write="OP(0)" ;;
237: 0010.2) lane_write="OP(1)" ;;
238: 0010.1) lane_write="OP(0)" ;;
239: 0010.0) lane_write="OP(1)" ;;
240:
241: 0011.3) lane_write="OP(0)" ;;
242: 0011.2) lane_write="OP(0)" ;;
243: 0011.1) lane_write="OP(1)" ;;
244: 0011.0) lane_write="OP(0)" ;;
245:
246: esac
247:
248: # emit the comment for this lane:
249: echo -n " /* D"`expr \( \( ${lane} + 1 \) \* 8 \) - 1`"-D"`expr ${lane} \* 8`" */ "
250:
251: # if this port size/position combination is
252: # invalid, override everything and abort if
253: # this router entry is ever touched:
254: if test `expr ${port_pos_end} \> 4` = 1; then
255: echo "TME_BUS_LANE_ABORT,"
256: else
257: if test $lane_read != "IGNORE"; then
258: if test $lane_read != $lane_write; then
259: echo "$PROG internal error: code ${transfer}.${address}.${port_size}.${port_pos}, reading $lane_read but writing $lane_write" 1>&2
260: exit 1
261: fi
262: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_read)"
263: elif test $lane_write = "UNDEF"; then
264: echo -n "TME_BUS_LANE_UNDEF"
265: else
266: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_write) | TME_BUS_LANE_ROUTE_WRITE_IGNORE"
267: fi
268: echo "${lane_warn},"
269: fi
270: done
271: done
272: done
273: done
274: done
275: echo "};"
276: fi
277:
278: cat <<EOF
279: #undef SIZ8_OP
280: #undef SIZ16_OP
281: #undef SIZ24_OP
282: #undef SIZ32_OP
283: EOF
284:
285: # done:
286: exit 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.