/[dynamips]/trunk/dev_mpc860.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/dev_mpc860.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Sat Oct 6 16:33:40 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.8-RC1/dev_mpc860.c
File MIME type: text/plain
File size: 57956 byte(s)
dynamips-0.2.8-RC1

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4 *
5 * MPC860 internal devices.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "utils.h"
13 #include "net.h"
14 #include "cpu.h"
15 #include "vm.h"
16 #include "dynamips.h"
17 #include "memory.h"
18 #include "device.h"
19 #include "net_io.h"
20 #include "dev_mpc860.h"
21
22 /* Debugging flags */
23 #define DEBUG_ACCESS 0
24 #define DEBUG_UNKNOWN 1
25 #define DEBUG_IDMA 0
26 #define DEBUG_SPI 0
27 #define DEBUG_SCC 0
28 #define DEBUG_FEC 1
29
30 #define MPC860_TXRING_PASS_COUNT 16
31
32 /* Dual-Port RAM */
33 #define MPC860_DPRAM_OFFSET 0x2000
34 #define MPC860_DPRAM_SIZE 0x2000
35 #define MPC860_DPRAM_END (MPC860_DPRAM_OFFSET + MPC860_DPRAM_SIZE)
36
37 /* MPC860 registers */
38 #define MPC860_REG_SWSR 0x000e /* Software Service Register */
39 #define MPC860_REG_SIPEND 0x0010 /* SIU Interrupt Pending Register */
40 #define MPC860_REG_SIMASK 0x0014 /* SIU Interrupt Mask Register */
41 #define MPC860_REG_PIPR 0x00f0 /* PCMCIA Interface Input Pins Reg. */
42 #define MPC860_REG_TBSCR 0x0200 /* Timebase Status and Control Reg. */
43 #define MPC860_REG_PISCR 0x0240 /* Periodic Int. Status and Ctrl Reg. */
44 #define MPC860_REG_IDSR1 0x0910 /* IDMA1 Status Register */
45 #define MPC860_REG_IDMR1 0x0914 /* IDMA1 Mask Register */
46 #define MPC860_REG_IDSR2 0x0918 /* IDMA2 Status Register */
47 #define MPC860_REG_IDMR2 0x091c /* IDMA2 Mask Register */
48 #define MPC860_REG_CICR 0x0940 /* CPM Int Config Register */
49 #define MPC860_REG_CIPR 0x0944 /* CPM Int Pending Register */
50 #define MPC860_REG_CIMR 0x0948 /* CPM Int Mask Register */
51 #define MPC860_REG_PCSO 0x0964 /* Port C Special Options Register */
52 #define MPC860_REG_PCDAT 0x0966 /* Port C Data Register */
53 #define MPC860_REG_CPCR 0x09c0 /* CP Command Register */
54 #define MPC860_REG_SCC_BASE 0x0a00 /* SCC register base */
55 #define MPC860_REG_SPMODE 0x0aa0 /* SPI Mode Register */
56 #define MPC860_REG_SPIE 0x0aa6 /* SPI Event Register */
57 #define MPC860_REG_SPIM 0x0aaa /* SPI Mask Register */
58 #define MPC860_REG_SPCOM 0x0aad /* SPI Command Register */
59 #define MPC860_REG_PBDAT 0x0ac4 /* Port B Data Register */
60 #define MPC860_REG_FEC_BASE 0x0e00 /* FEC register base */
61 #define MPC860_REG_FEC_END 0x0f84 /* FEC register end */
62
63 /* ======================================================================== */
64
65 /* CICR (CPM Interrupt Config Register) */
66 #define MPC860_CICR_IRL_MASK 0x0000E000 /* Interrupt Level */
67 #define MPC860_CICR_IRL_SHIFT 13
68 #define MPC860_CICR_IEN 0x00000080 /* Interrupt Enable */
69
70 /* CIPR (CPM Interrupt Pending Register) */
71 #define MPC860_CIPR_PC15 0x80000000
72 #define MPC860_CIPR_SCC1 0x40000000
73 #define MPC860_CIPR_SCC2 0x20000000
74 #define MPC860_CIPR_SCC3 0x10000000
75 #define MPC860_CIPR_SCC4 0x08000000
76 #define MPC860_CIPR_PC14 0x04000000
77 #define MPC860_CIPR_TIMER1 0x02000000
78 #define MPC860_CIPR_PC13 0x01000000
79 #define MPC860_CIPR_PC12 0x00800000
80 #define MPC860_CIPR_SDMA 0x00400000
81 #define MPC860_CIPR_IDMA1 0x00200000
82 #define MPC860_CIPR_IDMA2 0x00100000
83 #define MPC860_CIPR_TIMER2 0x00040000
84 #define MPC860_CIPR_RTT 0x00020000
85 #define MPC860_CIPR_I2C 0x00010000
86 #define MPC860_CIPR_PC11 0x00008000
87 #define MPC860_CIPR_PC10 0x00004000
88 #define MPC860_CIPR_TIMER3 0x00001000
89 #define MPC860_CIPR_PC9 0x00000800
90 #define MPC860_CIPR_PC8 0x00000400
91 #define MPC860_CIPR_PC7 0x00000200
92 #define MPC860_CIPR_TIMER4 0x00000080
93 #define MPC860_CIPR_PC6 0x00000040
94 #define MPC860_CIPR_SPI 0x00000020
95 #define MPC860_CIPR_SMC1 0x00000010
96 #define MPC860_CIPR_SMC2 0x00000008
97 #define MPC860_CIPR_PC5 0x00000004
98 #define MPC860_CIPR_PC4 0x00000002
99
100 /* CPCR (CP Command Register) */
101 #define MPC860_CPCR_RST 0x8000 /* CP reset command */
102 #define MPC860_CPCR_FLG 0x0001 /* Command Semaphore Flag */
103
104 #define MPC860_CPCR_CHNUM_MASK 0x00F0 /* Channel Number */
105 #define MPC860_CPCR_CHNUM_SHIFT 4
106
107 #define MPC860_CPCR_OPCODE_MASK 0x0F00 /* Opcode */
108 #define MPC860_CPCR_OPCODE_SHIFT 8
109
110 /* CP channels */
111 #define MPC860_CHAN_SCC1 0x00
112 #define MPC860_CHAN_I2C_IDMA1 0x01
113 #define MPC860_CHAN_SCC2 0x04
114 #define MPC860_CHAN_SPI_IDMA2_RT 0x05
115 #define MPC860_CHAN_SCC3 0x08
116 #define MPC860_CHAN_SMC1 0x09
117 #define MPC860_CHAN_SCC4 0x0c
118 #define MPC860_CHAN_SMC2_PIP 0x0d
119
120 /* ======================================================================== */
121
122 /* IDMA Status Register */
123 #define MPC860_IDSR_OB 0x0001 /* Out of Buffers */
124 #define MPC860_IDSR_DONE 0x0002 /* Buffer chain done */
125 #define MPC860_IDSR_AD 0x0004 /* Auxiliary done */
126
127 /* Offsets of IDMA channels (from DPRAM base) */
128 #define MPC860_IDMA1_BASE 0x1cc0
129 #define MPC860_IDMA2_BASE 0x1dc0
130
131 /* Size of an IDMA buffer descriptor */
132 #define MPC860_IDMA_BD_SIZE 16
133
134 /* IDMA Buffer Descriptor Control Word */
135 #define MPC860_IDMA_CTRL_V 0x8000 /* Valid Bit */
136 #define MPC860_IDMA_CTRL_W 0x2000 /* Wrap */
137 #define MPC860_IDMA_CTRL_I 0x1000 /* Interrupt for this BD */
138 #define MPC860_IDMA_CTRL_L 0x0800 /* Last buffer of chain */
139 #define MPC860_IDMA_CTRL_CM 0x0200 /* Continuous mode */
140
141 /* IDMA buffer descriptor */
142 struct mpc860_idma_bd {
143 m_uint16_t offset; /* Offset in DPRAM memory */
144
145 m_uint16_t ctrl; /* Control Word */
146 m_uint8_t dfcr,sfcr; /* Src/Dst Function code registers */
147 m_uint32_t buf_len; /* Buffer Length */
148 m_uint32_t src_bp; /* Source buffer pointer */
149 m_uint32_t dst_bp; /* Destination buffer pointer */
150 };
151
152 /* ======================================================================== */
153
154 /* SPI Mode Register (SPMODE) */
155 #define MPC860_SPMODE_LOOP 0x4000 /* Loop mode */
156 #define MPC860_SPMODE_CI 0x2000 /* Clock Invert */
157 #define MPC860_SPMODE_CP 0x1000 /* Clock Phase */
158 #define MPC860_SPMODE_DIV16 0x0800 /* Divide by 16 (SPI clock generator) */
159 #define MPC860_SPMODE_REV 0x0400 /* Reverse Data */
160 #define MPC860_SPMODE_MS 0x0200 /* Master/Slave mode select */
161 #define MPC860_SPMODE_EN 0x0100 /* Enable SPI */
162
163 #define MPC860_SPMODE_LEN_MASK 0x00F0 /* Data length (4 - 11 bits) */
164 #define MPC860_SPMODE_LEN_SHIFT 4
165
166 #define MPC860_SPMODE_PM_MASK 0x000F /* Prescale Modulus Select */
167
168 /* SPI Event/Mask Registers (SPIE/SPIM) */
169 #define MPC860_SPIE_MME 0x20 /* MultiMaster Error */
170 #define MPC860_SPIE_TXE 0x10 /* TX Error */
171 #define MPC860_SPIE_BSY 0x04 /* Busy (no RX buffer available) */
172 #define MPC860_SPIE_TXB 0x02 /* TX Buffer */
173 #define MPC860_SPIE_RXB 0x01 /* RX Buffer */
174
175 /* SPI Command Register (SPCOM) */
176 #define MPC860_SPCOM_STR 0x80 /* Start Transmit */
177
178 /* Offsets of SPI parameters (from DPRAM base) */
179 #define MPC860_SPI_BASE 0x1d80
180 #define MPC860_SPI_BASE_ADDR 0x1dac
181
182 /* Size of an SPI buffer descriptor */
183 #define MPC860_SPI_BD_SIZE 8
184
185 /* SPI RX Buffer Descriptor Control Word */
186 #define MPC860_SPI_RXBD_CTRL_E 0x8000 /* Empty */
187 #define MPC860_SPI_RXBD_CTRL_W 0x2000 /* Wrap */
188 #define MPC860_SPI_RXBD_CTRL_I 0x1000 /* Interrupt */
189 #define MPC860_SPI_RXBD_CTRL_L 0x0800 /* Last */
190 #define MPC860_SPI_RXBD_CTRL_CM 0x0200 /* Continuous Mode */
191 #define MPC860_SPI_RXBD_CTRL_OV 0x0002 /* Overrun */
192 #define MPC860_SPI_RXBD_CTRL_ME 0x0001 /* MultiMaster Error */
193
194 /* SPI TX Buffer Descriptor Control Word */
195 #define MPC860_SPI_TXBD_CTRL_R 0x8000 /* Ready Bit */
196 #define MPC860_SPI_TXBD_CTRL_W 0x2000 /* Wrap */
197 #define MPC860_SPI_TXBD_CTRL_I 0x1000 /* Interrupt */
198 #define MPC860_SPI_TXBD_CTRL_L 0x0800 /* Last */
199 #define MPC860_SPI_TXBD_CTRL_CM 0x0200 /* Continuous Mode */
200 #define MPC860_SPI_TXBD_CTRL_UN 0x0002 /* Underrun */
201 #define MPC860_SPI_TXBD_CTRL_ME 0x0001 /* MultiMaster Error */
202
203 /* SPI buffer descriptor */
204 struct mpc860_spi_bd {
205 m_uint16_t offset; /* Offset in DPRAM memory */
206
207 m_uint16_t ctrl; /* Control Word */
208 m_uint16_t buf_len; /* Buffer Length */
209 m_uint32_t bp; /* Buffer Pointer */
210 };
211
212 /* ======================================================================== */
213
214 /* Number of SCC channels */
215 #define MPC860_SCC_NR_CHAN 4
216
217 /* Maximum buffer size for SCC */
218 #define MPC860_SCC_MAX_PKT_SIZE 32768
219
220 /* Offsets of SCC channels (from DPRAM base) */
221 #define MPC860_SCC1_BASE 0x1c00
222 #define MPC860_SCC2_BASE 0x1d00
223 #define MPC860_SCC3_BASE 0x1e00
224 #define MPC860_SCC4_BASE 0x1f00
225
226 /* GSMR Low register */
227 #define MPC860_GSMRL_MODE_MASK 0x0000000F
228
229 /* SCC Modes */
230 #define MPC860_SCC_MODE_HDLC 0x00
231 #define MPC860_SCC_MODE_UART 0x04
232 #define MPC860_SCC_MODE_BISYNC 0x08
233 #define MPC860_SCC_MODE_ETH 0x0c
234
235 /* SCC Event (SCCE) register */
236 #define MPC860_SCCE_TXB 0x0002 /* TX buffer sent */
237 #define MPC860_SCCE_RXB 0x0001 /* RX buffer ready */
238
239 /* Size of an SCC buffer descriptor */
240 #define MPC860_SCC_BD_SIZE 8
241
242 /* SCC RX Buffer Descriptor Control Word */
243 #define MPC860_SCC_RXBD_CTRL_E 0x8000 /* Empty */
244 #define MPC860_SCC_RXBD_CTRL_W 0x2000 /* Wrap */
245 #define MPC860_SCC_RXBD_CTRL_I 0x1000 /* Interrupt */
246 #define MPC860_SCC_RXBD_CTRL_L 0x0800 /* Last */
247 #define MPC860_SCC_RXBD_CTRL_F 0x0400 /* First */
248 #define MPC860_SCC_RXBD_CTRL_CM 0x0200 /* Continuous Mode */
249 #define MPC860_SCC_RXBD_CTRL_OV 0x0002 /* Overrun */
250
251 /* SCC TX Buffer Descriptor Control Word */
252 #define MPC860_SCC_TXBD_CTRL_R 0x8000 /* Ready Bit */
253 #define MPC860_SCC_TXBD_CTRL_W 0x2000 /* Wrap */
254 #define MPC860_SCC_TXBD_CTRL_I 0x1000 /* Interrupt */
255 #define MPC860_SCC_TXBD_CTRL_L 0x0800 /* Last */
256 #define MPC860_SCC_TXBD_CTRL_TC 0x0400 /* Send TX CRC */
257 #define MPC860_SCC_TXBD_CTRL_CM 0x0200 /* Continuous Mode */
258 #define MPC860_SCC_TXBD_CTRL_UN 0x0002 /* Underrun */
259
260 /* SCC buffer descriptor */
261 struct mpc860_scc_bd {
262 m_uint16_t offset; /* Offset in DPRAM memory */
263
264 m_uint16_t ctrl; /* Control Word */
265 m_uint16_t buf_len; /* Buffer Length */
266 m_uint32_t bp; /* Buffer Pointer */
267 };
268
269 /* ======================================================================== */
270
271 /* FEC Ethernet Control Register */
272 #define MPC860_ECNTRL_FEC_PIN_MUX 0x00000004 /* FEC enable */
273 #define MPC860_ECNTRL_ETHER_EN 0x00000002 /* Ethernet Enable */
274 #define MPC860_ECNTRL_RESET 0x00000001 /* Reset Ethernet controller */
275
276 /* FEC Interrupt Vector Register */
277 #define MPC860_IVEC_ILEVEL_MASK 0xE0000000 /* Interrupt Level */
278 #define MPC860_IVEC_ILEVEL_SHIFT 29
279
280 /* FEC Interrupt Event Register */
281 #define MPC860_IEVENT_HBERR 0x80000000 /* Hearbeat Error */
282 #define MPC860_IEVENT_BABR 0x40000000 /* Babbling Receive Error */
283 #define MPC860_IEVENT_BABT 0x20000000 /* Babbling Transmit Error */
284 #define MPC860_IEVENT_GRA 0x10000000 /* Graceful Stop Complete */
285 #define MPC860_IEVENT_TFINT 0x08000000 /* Transmit Frame Interrupt */
286 #define MPC860_IEVENT_TXB 0x04000000 /* Transmit Buffer Interrupt */
287 #define MPC860_IEVENT_RFINT 0x02000000 /* Receive Frame Interrupt */
288 #define MPC860_IEVENT_RXB 0x01000000 /* Receive Buffer Interrupt */
289 #define MPC860_IEVENT_MII 0x00800000 /* MII Interrupt */
290 #define MPC860_IEVENT_EBERR 0x00400000 /* Ethernet Bus Error */
291
292 /* MII data register */
293 #define MPC860_MII_OP_MASK 0x30000000 /* Opcode (10:read,11:write) */
294 #define MPC860_MII_OP_SHIFT 28
295 #define MPC860_MII_PHY_MASK 0x0F800000 /* PHY device */
296 #define MPC860_MII_PHY_SHIFT 23
297 #define MPC860_MII_REG_MASK 0x007C0000 /* PHY device */
298 #define MPC860_MII_REG_SHIFT 18
299
300 /* Size of an FEC buffer descriptor */
301 #define MPC860_FEC_BD_SIZE 8
302
303 /* Maximum packet size for FEC */
304 #define MPC860_FEC_MAX_PKT_SIZE 2048
305
306 /* FEC RX Buffer Descriptor Control Word */
307 #define MPC860_FEC_RXBD_CTRL_E 0x8000 /* Empty */
308 #define MPC860_FEC_RXBD_CTRL_RO1 0x4000 /* For software use */
309 #define MPC860_FEC_RXBD_CTRL_W 0x2000 /* Wrap */
310 #define MPC860_FEC_RXBD_CTRL_RO2 0x1000 /* For software use */
311 #define MPC860_FEC_RXBD_CTRL_L 0x0800 /* Last */
312 #define MPC860_FEC_RXBD_CTRL_M 0x0100 /* Miss */
313 #define MPC860_FEC_RXBD_CTRL_BC 0x0080 /* Broadcast DA */
314 #define MPC860_FEC_RXBD_CTRL_MC 0x0040 /* Multicast DA */
315 #define MPC860_FEC_RXBD_CTRL_LG 0x0020 /* RX Frame length violation */
316 #define MPC860_FEC_RXBD_CTRL_NO 0x0010 /* RX non-octet aligned frame */
317 #define MPC860_FEC_RXBD_CTRL_SH 0x0008 /* Short Frame */
318 #define MPC860_FEC_RXBD_CTRL_CR 0x0004 /* RX CRC Error */
319 #define MPC860_FEC_RXBD_CTRL_OV 0x0002 /* Overrun */
320 #define MPC860_FEC_RXBD_CTRL_TR 0x0001 /* Truncated Frame */
321
322 /* FEC TX Buffer Descriptor Control Word */
323 #define MPC860_FEC_TXBD_CTRL_R 0x8000 /* Ready Bit */
324 #define MPC860_FEC_TXBD_CTRL_TO1 0x4000 /* For software use */
325 #define MPC860_FEC_TXBD_CTRL_W 0x2000 /* Wrap */
326 #define MPC860_FEC_TXBD_CTRL_TO2 0x1000 /* For software use */
327 #define MPC860_FEC_TXBD_CTRL_L 0x0800 /* Last */
328 #define MPC860_FEC_TXBD_CTRL_TC 0x0400 /* Send TX CRC */
329 #define MPC860_FEC_TXBD_CTRL_DEF 0x0200 /* Defer Indication */
330 #define MPC860_FEC_TXBD_CTRL_HB 0x0100 /* Heartbeat Error */
331 #define MPC860_FEC_TXBD_CTRL_LC 0x0080 /* Late Collision */
332 #define MPC860_FEC_TXBD_CTRL_RL 0x0040 /* Retranmission Limit */
333 #define MPC860_FEC_TXBD_CTRL_UN 0x0002 /* Underrun */
334 #define MPC860_FEC_TXBD_CTRL_CSL 0x0001 /* Carrier Sense Lost */
335
336 /* FEC buffer descriptor */
337 struct mpc860_fec_bd {
338 m_uint32_t bd_addr; /* Address in external memory */
339
340 m_uint16_t ctrl; /* Control Word */
341 m_uint16_t buf_len; /* Buffer Length */
342 m_uint32_t bp; /* Buffer Pointer */
343 };
344
345 /* ======================================================================== */
346
347 struct mpc860_scc_chan {
348 netio_desc_t *nio;
349
350 /* General SCC mode register (high and low parts) */
351 m_uint32_t gsmr_hi,gsmr_lo;
352
353 /* Protocol-Specific mode register */
354 m_uint32_t psmr;
355
356 /* SCC Event and Mask registers */
357 m_uint16_t scce,sccm;
358
359 /* TX packet */
360 u_char tx_pkt[MPC860_SCC_MAX_PKT_SIZE];
361 };
362
363 /* MPC860 private data */
364 struct mpc860_data {
365 char *name;
366 vm_obj_t vm_obj;
367 struct vdevice dev;
368 struct pci_device *pci_dev;
369 vm_instance_t *vm;
370
371 /* SIU Interrupt Pending Register and Interrupt Mask Register */
372 m_uint32_t sipend,simask;
373
374 /* CPM Interrupt Configuration Register */
375 m_uint32_t cicr;
376
377 /* CPM Interrupt Pending Register and Interrupt Mask Register */
378 m_uint32_t cipr,cimr;
379
380 /* IDMA status and mask registers */
381 m_uint8_t idsr[2],idmr[2];
382
383 /* Port B Data Register */
384 m_uint32_t pbdat,pcdat;
385
386 /* SPI callback for TX data */
387 mpc860_spi_tx_callback_t spi_tx_callback;
388 void *spi_user_arg;
389
390 /* SCC channels */
391 struct mpc860_scc_chan scc_chan[MPC860_SCC_NR_CHAN];
392
393 /* FEC (Fast Ethernet Controller) */
394 m_uint32_t fec_rdes_start,fec_xdes_start;
395 m_uint32_t fec_rdes_current,fec_xdes_current;
396 m_uint32_t fec_rbuf_size;
397
398 /* FEC Interrupt Event/Mask registers */
399 m_uint32_t fec_ievent,fec_imask,fec_ivec;
400 m_uint32_t fec_ecntrl;
401
402 /* FEC NetIO */
403 netio_desc_t *fec_nio;
404
405 /* FEC MII registers */
406 m_uint32_t fec_mii_data;
407 m_uint16_t fec_mii_regs[32];
408
409 /* Dual-Port RAM */
410 m_uint8_t dpram[MPC860_DPRAM_SIZE];
411 };
412
413 /* Log a MPC message */
414 #define MPC_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
415
416 /* ======================================================================== */
417
418 /* DPRAM access routines */
419 static inline m_uint8_t dpram_r8(struct mpc860_data *d,m_uint16_t offset)
420 {
421 return(d->dpram[offset]);
422 }
423
424 static inline void dpram_w8(struct mpc860_data *d,m_uint16_t offset,
425 m_uint8_t val)
426 {
427 d->dpram[offset] = val;
428 }
429
430 static inline m_uint16_t dpram_r16(struct mpc860_data *d,m_uint16_t offset)
431 {
432 m_uint16_t val;
433
434 val = (m_uint16_t)d->dpram[offset] << 8;
435 val |= d->dpram[offset+1];
436 return(val);
437 }
438
439 static inline void dpram_w16(struct mpc860_data *d,m_uint16_t offset,
440 m_uint16_t val)
441 {
442 d->dpram[offset] = val >> 8;
443 d->dpram[offset+1] = val & 0xFF;
444 }
445
446 static inline m_uint32_t dpram_r32(struct mpc860_data *d,m_uint16_t offset)
447 {
448 m_uint32_t val;
449
450 val = d->dpram[offset] << 24;
451 val |= d->dpram[offset+1] << 16;
452 val |= d->dpram[offset+2] << 8;
453 val |= d->dpram[offset+3];
454 return(val);
455 }
456
457 static inline void dpram_w32(struct mpc860_data *d,m_uint16_t offset,
458 m_uint32_t val)
459 {
460 d->dpram[offset] = val >> 24;
461 d->dpram[offset+1] = val >> 16;
462 d->dpram[offset+2] = val >> 8;
463 d->dpram[offset+3] = val;
464 }
465
466 /* ======================================================================== */
467
468 /* Update interrupt status */
469 static void mpc860_update_irq_status(struct mpc860_data *d)
470 {
471 cpu_ppc_t *cpu = CPU_PPC32(d->vm->boot_cpu);
472
473 cpu->irq_pending = d->sipend & d->simask;
474 cpu->irq_check = cpu->irq_pending;
475 }
476
477 /* Map level to SIU Interrupt Pending Register bit */
478 static inline u_int mpc860_get_siu_lvl(u_int level)
479 {
480 return(16 + ((7 - level) << 1));
481 }
482
483 /* Update CPM interrupt status */
484 static void mpc860_update_cpm_int_status(struct mpc860_data *d)
485 {
486 u_int level,siu_bit;
487
488 level = (d->cicr & MPC860_CICR_IRL_MASK) >> MPC860_CICR_IRL_SHIFT;
489 siu_bit = mpc860_get_siu_lvl(level);
490
491 if ((d->cipr & d->cimr) && (d->cicr & MPC860_CICR_IEN))
492 mpc860_set_pending_irq(d,siu_bit);
493 else
494 mpc860_clear_pending_irq(d,siu_bit);
495 }
496
497 /* ======================================================================== */
498 /* IDMA */
499 /* ======================================================================== */
500
501 /* Update an IDMA status register */
502 static int mpc860_idma_update_idsr(struct mpc860_data *d,u_int id)
503 {
504 u_int cpm_int;
505
506 switch(id) {
507 case 0:
508 cpm_int = MPC860_CIPR_IDMA1;
509 break;
510 case 1:
511 cpm_int = MPC860_CIPR_IDMA2;
512 break;
513 default:
514 return(-1);
515 }
516
517 if (d->idsr[id] & d->idmr[id])
518 d->cipr |= cpm_int;
519 else
520 d->cipr &= ~cpm_int;
521
522 mpc860_update_cpm_int_status(d);
523 return(0);
524 }
525
526 /* Process to an IDMA transfer for the specified buffer descriptor */
527 static void mpc860_idma_transfer(struct mpc860_data *d,
528 struct mpc860_idma_bd *bd)
529 {
530 physmem_dma_transfer(d->vm,bd->src_bp,bd->dst_bp,bd->buf_len);
531 }
532
533 /* Fetch an IDMA descriptor from Dual-Port RAM */
534 static int mpc860_idma_fetch_bd(struct mpc860_data *d,m_uint16_t bd_addr,
535 struct mpc860_idma_bd *bd)
536 {
537 if ((bd_addr < MPC860_DPRAM_OFFSET) || (bd_addr > MPC860_DPRAM_END))
538 return(-1);
539
540 bd->offset = bd_addr - MPC860_DPRAM_OFFSET;
541
542 /* Fetch control word */
543 bd->ctrl = dpram_r16(d,bd->offset+0x00);
544
545 /* Fetch function code registers */
546 bd->dfcr = dpram_r8(d,bd->offset+0x02);
547 bd->sfcr = dpram_r8(d,bd->offset+0x03);
548
549 /* Fetch buffer length, source and destination addresses */
550 bd->buf_len = dpram_r32(d,bd->offset+0x04);
551 bd->src_bp = dpram_r32(d,bd->offset+0x08);
552 bd->dst_bp = dpram_r32(d,bd->offset+0x0c);
553
554 #if DEBUG_IDMA
555 MPC_LOG(d,"fetched IDMA BD at 0x%4.4x, src_bp=0x%8.8x, dst_bp=0x%8.8x "
556 "len=%d\n",bd->offset,bd->src_bp,bd->dst_bp,bd->buf_len);
557 #endif
558
559 return(0);
560 }
561
562 /* Start an IDMA channel */
563 static int mpc860_idma_start_channel(struct mpc860_data *d,u_int id)
564 {
565 struct mpc860_idma_bd bd;
566 m_uint16_t dma_base,ibase,bd_offset;
567
568 switch(id) {
569 case 0:
570 dma_base = MPC860_IDMA1_BASE;
571 break;
572 case 1:
573 dma_base = MPC860_IDMA2_BASE;
574 break;
575 default:
576 return(-1);
577 }
578
579 /* Get the IBASE register (offset 0) */
580 ibase = bd_offset = dpram_r16(d,dma_base+0x00);
581
582 while(1) {
583 /* Fetch a descriptor */
584 if (mpc860_idma_fetch_bd(d,bd_offset,&bd) == -1)
585 return(-1);
586
587 if (!(bd.ctrl & MPC860_IDMA_CTRL_V)) {
588 d->idsr[id] |= MPC860_IDSR_OB;
589 break;
590 }
591
592 /* Run the DMA transfer */
593 mpc860_idma_transfer(d,&bd);
594
595 /* Clear the Valid bit */
596 bd.ctrl &= ~MPC860_IDMA_CTRL_V;
597 dpram_w16(d,bd_offset-MPC860_DPRAM_OFFSET+0x00,bd.ctrl);
598
599 /* Generate an interrupt for this buffer ? */
600 if (bd.ctrl & MPC860_IDMA_CTRL_I)
601 d->idsr[id] |= MPC860_IDSR_AD;
602
603 /* Stop if this is the last buffer of chain */
604 if (bd.ctrl & MPC860_IDMA_CTRL_L) {
605 d->idsr[id] |= MPC860_IDSR_DONE;
606 break;
607 }
608
609 bd_offset += sizeof(MPC860_IDMA_BD_SIZE);
610 }
611
612 mpc860_idma_update_idsr(d,id);
613 return(0);
614 }
615
616 /* ======================================================================== */
617 /* SPI (Serial Peripheral Interface) */
618 /* ======================================================================== */
619
620 /* Initialize SPI RX parameters */
621 static void mpc860_spi_init_rx_params(struct mpc860_data *d)
622 {
623 m_uint16_t spi_base,rbase;
624
625 spi_base = dpram_r16(d,MPC860_SPI_BASE_ADDR);
626
627 /* Get the RBASE (offset 0) and store it in RBPTR */
628 rbase = dpram_r16(d,spi_base+0x00);
629 dpram_w16(d,spi_base+0x10,rbase);
630 }
631
632 /* Initialize SPI TX parameters */
633 static void mpc860_spi_init_tx_params(struct mpc860_data *d)
634 {
635 m_uint16_t spi_base,tbase;
636
637 spi_base = dpram_r16(d,MPC860_SPI_BASE_ADDR);
638
639 /* Get the TBASE (offset 2) and store it in TBPTR */
640 tbase = dpram_r16(d,spi_base+0x02);
641 dpram_w16(d,spi_base+0x20,tbase);
642 }
643
644 /* Initialize SPI RX/TX parameters */
645 static void mpc860_spi_init_rx_tx_params(struct mpc860_data *d)
646 {
647 mpc860_spi_init_rx_params(d);
648 mpc860_spi_init_tx_params(d);
649 }
650
651 /* Fetch a SPI buffer descriptor */
652 static int mpc860_spi_fetch_bd(struct mpc860_data *d,m_uint16_t bd_addr,
653 struct mpc860_spi_bd *bd)
654 {
655 void *ptr;
656
657 if ((bd_addr < MPC860_DPRAM_OFFSET) || (bd_addr > MPC860_DPRAM_END))
658 return(-1);
659
660 bd->offset = bd_addr - MPC860_DPRAM_OFFSET;
661 ptr = &d->dpram[bd->offset];
662
663 /* Fetch control word */
664 bd->ctrl = dpram_r16(d,bd->offset+0x00);
665
666 /* Fetch buffer length and buffer pointer */
667 bd->buf_len = dpram_r16(d,bd->offset+0x02);
668 bd->bp = dpram_r32(d,bd->offset+0x04);
669
670 #if DEBUG_SPI
671 MPC_LOG(d,"fetched SPI BD at 0x%4.4x, bp=0x%8.8x, len=%d\n",
672 bd->offset,bd->bp,bd->buf_len);
673 #endif
674
675 return(0);
676 }
677
678 /* Start SPI transmit */
679 static int mpc860_spi_start_tx(struct mpc860_data *d)
680 {
681 struct mpc860_spi_bd bd;
682 m_uint16_t bd_offset;
683 m_uint16_t spi_base;
684 u_char buffer[512];
685 u_int buf_len;
686
687 spi_base = dpram_r16(d,MPC860_SPI_BASE_ADDR);
688
689 /* Get the TBPTR (offset 0x20) register */
690 bd_offset = dpram_r16(d,spi_base+0x20);
691
692 while(1) {
693 /* Fetch a TX descriptor */
694 if (mpc860_spi_fetch_bd(d,bd_offset,&bd) == -1)
695 return(FALSE);
696
697 /* If the descriptor is not ready, stop now */
698 if (!(bd.ctrl & MPC860_SPI_TXBD_CTRL_R))
699 return(FALSE);
700
701 /* Extract the data */
702 buf_len = bd.buf_len;
703
704 if (bd.buf_len > sizeof(buffer)) {
705 MPC_LOG(d,"SPI: buffer too small for transmit.\n");
706 buf_len = sizeof(buffer);
707 }
708
709 physmem_copy_from_vm(d->vm,buffer,bd.bp,buf_len);
710
711 /* Send the data to the user callback (if specified) */
712 if (d->spi_tx_callback != NULL)
713 d->spi_tx_callback(d,buffer,buf_len,d->spi_user_arg);
714
715 /* Clear the Ready bit of the TX descriptor */
716 bd.ctrl &= ~MPC860_SPI_TXBD_CTRL_R;
717 dpram_w16(d,bd.offset+0x00,bd.ctrl);
718
719 /* Set pointer on next TX descriptor (wrap ring if necessary) */
720 if (bd.ctrl & MPC860_SPI_TXBD_CTRL_W) {
721 bd_offset = dpram_r16(d,spi_base+0x02);
722 } else {
723 bd_offset += MPC860_SPI_BD_SIZE;
724 }
725 dpram_w16(d,spi_base+0x20,bd_offset);
726
727 /* Stop if this is the last buffer in chain */
728 if (bd.ctrl & MPC860_SPI_TXBD_CTRL_L)
729 break;
730 }
731
732 return(TRUE);
733 }
734
735 /* Put a buffer into SPI receive buffers */
736 int mpc860_spi_receive(struct mpc860_data *d,u_char *buffer,u_int len)
737 {
738 struct mpc860_spi_bd bd;
739 m_uint16_t bd_offset;
740 m_uint16_t spi_base;
741 u_int clen,mrblr;
742
743 spi_base = dpram_r16(d,MPC860_SPI_BASE_ADDR);
744
745 /* Get the RBPTR (offset 0x10) */
746 bd_offset = dpram_r16(d,spi_base+0x10);
747
748 /* Get the maximum buffer size */
749 mrblr = dpram_r16(d,spi_base+0x06);
750
751 while(len > 0) {
752 /* Fetch a RX descriptor */
753 if (mpc860_spi_fetch_bd(d,bd_offset,&bd) == -1)
754 return(FALSE);
755
756 /* If the buffer is not empty, do not use it */
757 if (!(bd.ctrl & MPC860_SPI_RXBD_CTRL_E))
758 return(FALSE);
759
760 /* Write data into the RX buffer */
761 clen = m_min(mrblr,len);
762 physmem_copy_to_vm(d->vm,buffer,bd.bp,clen);
763 buffer += clen;
764 len -= clen;
765
766 /* Update the length field */
767 dpram_w16(d,bd.offset+0x02,clen);
768
769 /* If no more data, set the "Last" bit */
770 if (!len)
771 bd.ctrl |= MPC860_SPI_RXBD_CTRL_L;
772
773 /* Clear the Empty bit of the RX descriptor */
774 bd.ctrl &= ~MPC860_SPI_RXBD_CTRL_E;
775 dpram_w16(d,bd.offset+0x00,bd.ctrl);
776
777 /* Set pointer on next RX descriptor */
778 if (bd.ctrl & MPC860_SPI_RXBD_CTRL_W) {
779 bd_offset = dpram_r16(d,spi_base+0x00);
780 } else {
781 bd_offset += MPC860_SPI_BD_SIZE;
782 }
783 dpram_w16(d,spi_base+0x10,bd_offset);
784 }
785
786 if (len > 0)
787 MPC_LOG(d,"SPI: no buffers available for receive.\n");
788
789 return(0);
790 }
791
792 /* Set SPI TX callback */
793 void mpc860_spi_set_tx_callback(struct mpc860_data *d,
794 mpc860_spi_tx_callback_t cbk,
795 void *user_arg)
796 {
797 d->spi_tx_callback = cbk;
798 d->spi_user_arg = user_arg;
799 }
800
801 /* ======================================================================== */
802 /* SCC (Serial Communication Controller) */
803 /* ======================================================================== */
804
805 typedef struct {
806 u_int cipr_irq;
807 m_uint32_t dpram_base;
808 }scc_chan_info_t;
809
810 static scc_chan_info_t scc_chan_info[MPC860_SCC_NR_CHAN] = {
811 { MPC860_CIPR_SCC1, MPC860_SCC1_BASE },
812 { MPC860_CIPR_SCC2, MPC860_SCC2_BASE },
813 { MPC860_CIPR_SCC3, MPC860_SCC3_BASE },
814 { MPC860_CIPR_SCC4, MPC860_SCC4_BASE },
815 };
816
817 /* Initialize SCC RX parameters */
818 static void mpc860_scc_init_rx_params(struct mpc860_data *d,u_int scc_chan)
819 {
820 m_uint16_t scc_base,rbase;
821
822 scc_base = scc_chan_info[scc_chan].dpram_base;
823
824 /* Get the RBASE (offset 0) and store it in RBPTR */
825 rbase = dpram_r16(d,scc_base+0x00);
826 dpram_w16(d,scc_base+0x10,rbase);
827 }
828
829 /* Initialize SCC TX parameters */
830 static void mpc860_scc_init_tx_params(struct mpc860_data *d,u_int scc_chan)
831 {
832 m_uint16_t scc_base,tbase;
833
834 scc_base = scc_chan_info[scc_chan].dpram_base;
835
836 /* Get the TBASE (offset 2) and store it in TBPTR */
837 tbase = dpram_r16(d,scc_base+0x02);
838 dpram_w16(d,scc_base+0x20,tbase);
839 }
840
841 /* Initialize SCC RX/TX parameters */
842 static void mpc860_scc_init_rx_tx_params(struct mpc860_data *d,u_int scc_chan)
843 {
844 mpc860_scc_init_rx_params(d,scc_chan);
845 mpc860_scc_init_tx_params(d,scc_chan);
846 }
847
848 /* Set an SCC interrupt */
849 static int mpc860_scc_update_irq(struct mpc860_data *d,u_int scc_chan)
850 {
851 struct mpc860_scc_chan *chan = &d->scc_chan[scc_chan];
852
853 if (chan->scce & chan->sccm)
854 d->cipr |= scc_chan_info[scc_chan].cipr_irq;
855 else
856 d->cipr &= ~scc_chan_info[scc_chan].cipr_irq;
857
858 mpc860_update_cpm_int_status(d);
859 return(0);
860 }
861
862 /* Fetch a SCC buffer descriptor */
863 static int mpc860_scc_fetch_bd(struct mpc860_data *d,m_uint16_t bd_addr,
864 struct mpc860_scc_bd *bd)
865 {
866 void *ptr;
867
868 if ((bd_addr < MPC860_DPRAM_OFFSET) || (bd_addr > MPC860_DPRAM_END))
869 return(-1);
870
871 bd->offset = bd_addr - MPC860_DPRAM_OFFSET;
872 ptr = &d->dpram[bd->offset];
873
874 /* Fetch control word */
875 bd->ctrl = dpram_r16(d,bd->offset+0x00);
876
877 /* Fetch buffer length and buffer pointer */
878 bd->buf_len = dpram_r16(d,bd->offset+0x02);
879 bd->bp = dpram_r32(d,bd->offset+0x04);
880
881 #if DEBUG_SCC
882 MPC_LOG(d,"fetched SCC BD at 0x%4.4x, bp=0x%8.8x, len=%d\n",
883 bd->offset,bd->bp,bd->buf_len);
884 #endif
885
886 return(0);
887 }
888
889 /* Handle the TX ring of an SCC channel (transmit a single packet) */
890 static int mpc860_scc_handle_tx_ring_single(struct mpc860_data *d,
891 u_int scc_chan)
892 {
893 struct mpc860_scc_bd txd0,ctxd,*ptxd;
894 struct mpc860_scc_chan *chan;
895 scc_chan_info_t *scc_info;
896 m_uint16_t bd_offset;
897 m_uint32_t clen,tot_len;
898 u_char *pkt_ptr;
899 int done = FALSE;
900 int irq = FALSE;
901
902 scc_info = &scc_chan_info[scc_chan];
903 chan = &d->scc_chan[scc_chan];
904
905 /* Get the TBPTR (offset 0x20) register */
906 bd_offset = dpram_r16(d,scc_info->dpram_base+0x20);
907
908 /* Try to acquire the first descriptor */
909 ptxd = &txd0;
910 mpc860_scc_fetch_bd(d,bd_offset,ptxd);
911
912 /* If we don't own the first descriptor, we cannot transmit */
913 if (!(txd0.ctrl & MPC860_SCC_TXBD_CTRL_R))
914 return(FALSE);
915
916 /* Empty packet for now */
917 pkt_ptr = chan->tx_pkt;
918 tot_len = 0;
919
920 do {
921 /* Copy data into the buffer */
922 clen = ptxd->buf_len;
923 physmem_copy_from_vm(d->vm,pkt_ptr,ptxd->bp,clen);
924 pkt_ptr += clen;
925 tot_len += clen;
926
927 /* Signal IRQ ? */
928 if (ptxd->ctrl & MPC860_SCC_TXBD_CTRL_I)
929 irq = TRUE;
930
931 /*
932 * Clear the ready bit (except for the first descriptor,
933 * which is cleared when the full packet has been sent).
934 */
935 if (ptxd != &txd0) {
936 ptxd->ctrl &= ~MPC860_SCC_TXBD_CTRL_R;
937 dpram_w16(d,ptxd->offset+0x00,ptxd->ctrl);
938 }
939
940 /* Set pointer on next TX descriptor (wrap ring if necessary) */
941 if (ptxd->ctrl & MPC860_SCC_TXBD_CTRL_W) {
942 bd_offset = dpram_r16(d,scc_info->dpram_base+0x02);
943 } else {
944 bd_offset += MPC860_SCC_BD_SIZE;
945 }
946 dpram_w16(d,scc_info->dpram_base+0x20,bd_offset);
947
948 /* If this is the last descriptor, we have finished */
949 if (!(ptxd->ctrl & MPC860_SCC_TXBD_CTRL_L)) {
950 mpc860_scc_fetch_bd(d,bd_offset,&ctxd);
951 ptxd = &ctxd;
952 } else {
953 done = TRUE;
954 }
955 }while(!done);
956
957 if (tot_len != 0) {
958 #if DEBUG_SCC
959 MPC_LOG(d,"SCC%u: sending packet of %u bytes\n",scc_chan+1,tot_len);
960 mem_dump(log_file,chan->tx_pkt,tot_len);
961 #endif
962 /* send packet on wire */
963 netio_send(chan->nio,chan->tx_pkt,tot_len);
964 }
965
966 /* Clear the Ready bit of the first TX descriptor */
967 txd0.ctrl &= ~MPC860_SCC_TXBD_CTRL_R;
968 dpram_w16(d,txd0.offset+0x00,txd0.ctrl);
969
970 /* Trigger SCC IRQ */
971 if (irq) {
972 chan->scce |= MPC860_SCCE_TXB;
973 mpc860_scc_update_irq(d,scc_chan);
974 }
975
976 return(TRUE);
977 }
978
979 /* Handle the TX ring of the specified SCC channel (multiple pkts possible) */
980 static int mpc860_scc_handle_tx_ring(struct mpc860_data *d,u_int scc_chan)
981 {
982 int i;
983
984 for(i=0;i<MPC860_TXRING_PASS_COUNT;i++)
985 if (!mpc860_scc_handle_tx_ring_single(d,scc_chan))
986 break;
987
988 return(TRUE);
989 }
990
991 /* Handle RX packet for an SCC channel */
992 static int mpc860_scc_handle_rx_pkt(netio_desc_t *nio,
993 u_char *pkt,ssize_t pkt_len,
994 struct mpc860_data *d,void *arg)
995 {
996 struct mpc860_scc_bd rxd0,crxd,*prxd;
997 struct mpc860_scc_chan *chan;
998 u_int scc_chan = (int)arg;
999 scc_chan_info_t *scc_info;
1000 m_uint16_t bd_offset;
1001 ssize_t clen,tot_len;
1002 u_char *pkt_ptr;
1003 u_int mrblr;
1004 int irq = FALSE;
1005
1006 scc_info = &scc_chan_info[scc_chan];
1007 chan = &d->scc_chan[scc_chan];
1008
1009 /* Get the RBPTR (offset 0x10) register */
1010 bd_offset = dpram_r16(d,scc_info->dpram_base+0x10);
1011
1012 /* Get the maximum buffer size */
1013 mrblr = dpram_r16(d,scc_info->dpram_base+0x06);
1014
1015 /* Try to acquire the first descriptor */
1016 prxd = &rxd0;
1017 mpc860_scc_fetch_bd(d,bd_offset,prxd);
1018
1019 /* If we don't own the first descriptor, we cannot transmit */
1020 if (!(rxd0.ctrl & MPC860_SCC_RXBD_CTRL_E))
1021 return(FALSE);
1022
1023 pkt_ptr = pkt;
1024 tot_len = pkt_len;
1025
1026 while(tot_len > 0) {
1027 /* Write data into the RX buffer */
1028 clen = m_min(mrblr,tot_len);
1029 physmem_copy_to_vm(d->vm,pkt_ptr,prxd->bp,clen);
1030 pkt_ptr += clen;
1031 tot_len -= clen;
1032
1033 /* Signal IRQ ? */
1034 if (prxd->ctrl & MPC860_SCC_RXBD_CTRL_I)
1035 irq = TRUE;
1036
1037 /* Set the Last flag if we have finished */
1038 if (!tot_len) {
1039 /* Set the full length */
1040 switch(chan->gsmr_lo & MPC860_GSMRL_MODE_MASK) {
1041 case MPC860_SCC_MODE_ETH:
1042 pkt_len += 4;
1043 break;
1044 case MPC860_SCC_MODE_HDLC:
1045 pkt_len += 2;
1046 break;
1047 }
1048
1049 dpram_w16(d,prxd->offset+0x02,pkt_len);
1050 prxd->ctrl |= MPC860_SCC_RXBD_CTRL_L;
1051 } else {
1052 /* Update the length field */
1053 dpram_w16(d,prxd->offset+0x02,clen);
1054 }
1055
1056 /*
1057 * Clear the empty bit (except for the first descriptor,
1058 * which is cleared when the full packet has been stored).
1059 */
1060 if (prxd != &rxd0) {
1061 prxd->ctrl &= ~MPC860_SCC_RXBD_CTRL_E;
1062 dpram_w16(d,prxd->offset+0x00,prxd->ctrl);
1063 }
1064
1065 /* Set pointer on next RX descriptor (wrap ring if necessary) */
1066 if (prxd->ctrl & MPC860_SCC_RXBD_CTRL_W) {
1067 bd_offset = dpram_r16(d,scc_info->dpram_base+0x00);
1068 } else {
1069 bd_offset += MPC860_SCC_BD_SIZE;
1070 }
1071 dpram_w16(d,scc_info->dpram_base+0x10,bd_offset);
1072
1073 /* If this is the last descriptor, we have finished */
1074 if (!tot_len) {
1075 mpc860_scc_fetch_bd(d,bd_offset,&crxd);
1076 prxd = &crxd;
1077 }
1078 }
1079
1080 /* Clear the Empty bit of the first RX descriptor and set First bit */
1081 rxd0.ctrl &= ~MPC860_SCC_RXBD_CTRL_E;
1082 rxd0.ctrl |= MPC860_SCC_RXBD_CTRL_F;
1083 dpram_w16(d,rxd0.offset+0x00,rxd0.ctrl);
1084
1085 /* Trigger SCC IRQ */
1086 if (irq) {
1087 d->scc_chan[scc_chan].scce |= MPC860_SCCE_RXB;
1088 mpc860_scc_update_irq(d,scc_chan);
1089 }
1090
1091 return(TRUE);
1092 }
1093
1094 /* Set NIO for the specified SCC channel */
1095 int mpc860_scc_set_nio(struct mpc860_data *d,u_int scc_chan,netio_desc_t *nio)
1096 {
1097 struct mpc860_scc_chan *chan;
1098
1099 if (!d || (scc_chan >= MPC860_SCC_NR_CHAN))
1100 return(-1);
1101
1102 chan = &d->scc_chan[scc_chan];
1103
1104 /* check that a NIO is not already bound */
1105 if (chan->nio != NULL)
1106 return(-1);
1107
1108 chan->nio = nio;
1109 netio_rxl_add(nio,(netio_rx_handler_t)mpc860_scc_handle_rx_pkt,
1110 d,(void *)scc_chan);
1111 return(0);
1112 }
1113
1114 /* Unset NIO of the specified SCC channel */
1115 int mpc860_scc_unset_nio(struct mpc860_data *d,u_int scc_chan)
1116 {
1117 struct mpc860_scc_chan *chan;
1118
1119 if (!d || (scc_chan >= MPC860_SCC_NR_CHAN))
1120 return(-1);
1121
1122 chan = &d->scc_chan[scc_chan];
1123
1124 if (chan->nio != NULL) {
1125 netio_rxl_remove(chan->nio);
1126 chan->nio = NULL;
1127 }
1128
1129 return(0);
1130 }
1131
1132 /*
1133 * SCC register access.
1134 *
1135 * SCC1: 0x0a00 to 0x0a1f
1136 * SCC2: 0x0a20 to 0x0a3f
1137 * SCC3: 0x0a40 to 0x0a5f
1138 * SCC4: 0x0a60 to 0x0a7f
1139 */
1140 static int dev_mpc860_scc_access(struct mpc860_data *d,m_uint32_t offset,
1141 u_int op_size,u_int op_type,m_uint64_t *data)
1142 {
1143 struct mpc860_scc_chan *chan;
1144 u_int scc_chan,reg;
1145
1146 /* Extract channel ID and register */
1147 scc_chan = (offset >> 5) & 0x03;
1148 reg = offset & 0x1F;
1149
1150 chan = &d->scc_chan[scc_chan];
1151
1152 switch(reg) {
1153 /* GSMRL - General SCC mode register (Low part) */
1154 case 0x00:
1155 if (op_type == MTS_READ)
1156 *data = chan->gsmr_lo;
1157 else
1158 chan->gsmr_lo = *data;
1159 break;
1160
1161 /* GSMRH - General SCC mode register (High part) */
1162 case 0x04:
1163 if (op_type == MTS_READ)
1164 *data = chan->gsmr_hi;
1165 else
1166 chan->gsmr_hi = *data;
1167 break;
1168
1169 /* PSMR - Protocol-Specific Mode Register */
1170 case 0x08:
1171 if (op_type == MTS_READ)
1172 *data = chan->psmr;
1173 else
1174 chan->psmr = *data;
1175 break;
1176
1177 /* TOD - Transmit On Demand */
1178 case 0x0c:
1179 if ((op_type == MTS_WRITE) && (*data & 0x8000))
1180 mpc860_scc_handle_tx_ring(d,scc_chan);
1181 break;
1182
1183 /* SCCE - SCC Event Register */
1184 case 0x10:
1185 if (op_type == MTS_READ)
1186 *data = chan->scce;
1187 else {
1188 chan->scce &= ~(*data);
1189 mpc860_scc_update_irq(d,scc_chan);
1190 }
1191 break;
1192
1193 /* SCCM - SCC Mask Register */
1194 case 0x14:
1195 if (op_type == MTS_READ)
1196 *data = chan->sccm;
1197 else {
1198 chan->sccm = *data;
1199 mpc860_scc_update_irq(d,scc_chan);
1200 }
1201 break;
1202 }
1203
1204 return(0);
1205 }
1206
1207 /* ======================================================================== */
1208 /* FEC (Fast Ethernet Controller) */
1209 /* ======================================================================== */
1210
1211 /* Trigger interrupt for FEC */
1212 static void mpc860_fec_update_irq_status(struct mpc860_data *d)
1213 {
1214 u_int level,siu_bit;
1215
1216 level = (d->fec_ivec & MPC860_IVEC_ILEVEL_MASK) >> MPC860_IVEC_ILEVEL_SHIFT;
1217 siu_bit = mpc860_get_siu_lvl(level);
1218
1219 if (d->fec_ievent & d->fec_imask)
1220 mpc860_set_pending_irq(d,siu_bit);
1221 else
1222 mpc860_clear_pending_irq(d,siu_bit);
1223 }
1224
1225 /* Fetch a FEC buffer descriptor, located in external memory */
1226 static int mpc860_fec_fetch_bd(struct mpc860_data *d,m_uint32_t bd_addr,
1227 struct mpc860_fec_bd *bd)
1228 {
1229 m_uint32_t w0,w1;
1230
1231 /* Set BD address */
1232 bd->bd_addr = bd_addr;
1233
1234 w0 = physmem_copy_u32_from_vm(d->vm,bd_addr);
1235 w1 = physmem_copy_u32_from_vm(d->vm,bd_addr+4);
1236
1237 bd->ctrl = w0 >> 16;
1238 bd->buf_len = w0 & 0xFFFF;
1239 bd->bp = w1;
1240
1241 #if DEBUG_FEC
1242 MPC_LOG(d,"fetched FEC BD at 0x%8.8x, bp=0x%8.8x, len=%d\n",
1243 bd->bd_addr,bd->bp,bd->buf_len);
1244 #endif
1245
1246 return(0);
1247 }
1248
1249 /* Handle the TX ring of the FEC (transmit a single packet) */
1250 static int mpc860_fec_handle_tx_ring_single(struct mpc860_data *d)
1251 {
1252 u_char tx_pkt[MPC860_FEC_MAX_PKT_SIZE];
1253 struct mpc860_fec_bd txd0,ctxd,*ptxd;
1254 m_uint32_t clen,tot_len;
1255 u_char *pkt_ptr;
1256 int done = FALSE;
1257
1258 if (!d->fec_xdes_current)
1259 return(FALSE);
1260
1261 /* Try to acquire the first descriptor */
1262 ptxd = &txd0;
1263 mpc860_fec_fetch_bd(d,d->fec_xdes_current,ptxd);
1264
1265 /* If we don't own the first descriptor, we cannot transmit */
1266 if (!(txd0.ctrl & MPC860_FEC_TXBD_CTRL_R))
1267 return(FALSE);
1268
1269 /* Empty packet for now */
1270 pkt_ptr = tx_pkt;
1271 tot_len = 0;
1272
1273 do {
1274 /* Copy data into the buffer */
1275 clen = ptxd->buf_len;
1276 physmem_copy_from_vm(d->vm,pkt_ptr,ptxd->bp,clen);
1277 pkt_ptr += clen;
1278 tot_len += clen;
1279
1280 /*
1281 * Clear the ready bit (except for the first descriptor,
1282 * which is cleared when the full packet has been sent).
1283 */
1284 if (ptxd != &txd0) {
1285 ptxd->ctrl &= ~MPC860_FEC_TXBD_CTRL_R;
1286 physmem_copy_u16_to_vm(d->vm,ptxd->bd_addr+0x00,ptxd->ctrl);
1287 }
1288
1289 /* Set pointer on next TX descriptor (wrap ring if necessary) */
1290 if (ptxd->ctrl & MPC860_FEC_TXBD_CTRL_W) {
1291 d->fec_xdes_current = d->fec_xdes_start;
1292 } else {
1293 d->fec_xdes_current += MPC860_FEC_BD_SIZE;
1294 }
1295
1296 /* If this is the last descriptor, we have finished */
1297 if (!(ptxd->ctrl & MPC860_FEC_TXBD_CTRL_L)) {
1298 mpc860_fec_fetch_bd(d,d->fec_xdes_current,&ctxd);
1299 ptxd = &ctxd;
1300 } else {
1301 done = TRUE;
1302 }
1303 }while(!done);
1304
1305 if (tot_len != 0) {
1306 #if DEBUG_FEC
1307 MPC_LOG(d,"FEC: sending packet of %u bytes\n",tot_len);
1308 mem_dump(log_file,tx_pkt,tot_len);
1309 #endif
1310 /* send packet on wire */
1311 netio_send(d->fec_nio,tx_pkt,tot_len);
1312 }
1313
1314 /* Clear the Ready bit of the first TX descriptor */
1315 txd0.ctrl &= ~MPC860_FEC_TXBD_CTRL_R;
1316 physmem_copy_u16_to_vm(d->vm,txd0.bd_addr+0x00,txd0.ctrl);
1317
1318 /* Trigger FEC IRQ */
1319 d->fec_ievent |= MPC860_IEVENT_TFINT | MPC860_IEVENT_TXB;
1320 mpc860_fec_update_irq_status(d);
1321 return(TRUE);
1322 }
1323
1324 /* Handle the TX ring of the FEC (multiple pkts possible) */
1325 static int mpc860_fec_handle_tx_ring(struct mpc860_data *d)
1326 {
1327 int i;
1328
1329 for(i=0;i<MPC860_TXRING_PASS_COUNT;i++)
1330 if (!mpc860_fec_handle_tx_ring_single(d))
1331 break;
1332
1333 return(TRUE);
1334 }
1335
1336 /* Handle RX packet for the Fast Ethernet Controller */
1337 static int mpc860_fec_handle_rx_pkt(netio_desc_t *nio,
1338 u_char *pkt,ssize_t pkt_len,
1339 struct mpc860_data *d,void *arg)
1340 {
1341 n_eth_hdr_t *hdr = (n_eth_hdr_t *)pkt;
1342 struct mpc860_fec_bd rxd0,crxd,*prxd;
1343 ssize_t clen,tot_len;
1344 u_char *pkt_ptr;
1345
1346 if (!d->fec_rdes_current)
1347 return(FALSE);
1348
1349 /* Try to acquire the first descriptor */
1350 prxd = &rxd0;
1351 mpc860_fec_fetch_bd(d,d->fec_rdes_current,prxd);
1352
1353 /* If we don't own the first descriptor, we cannot transmit */
1354 if (!(rxd0.ctrl & MPC860_FEC_RXBD_CTRL_E))
1355 return(FALSE);
1356
1357 pkt_ptr = pkt;
1358 tot_len = pkt_len;
1359
1360 while(tot_len > 0) {
1361 /* Write data into the RX buffer */
1362 clen = m_min(d->fec_rbuf_size,tot_len);
1363 physmem_copy_to_vm(d->vm,pkt_ptr,prxd->bp,clen);
1364 pkt_ptr += clen;
1365 tot_len -= clen;
1366
1367 /* Set the Last flag if we have finished */
1368 if (!tot_len) {
1369 /* Set the full length */
1370 physmem_copy_u16_to_vm(d->vm,prxd->bd_addr+0x02,pkt_len+4);
1371 prxd->ctrl |= MPC860_FEC_RXBD_CTRL_L;
1372
1373 if (eth_addr_is_bcast(&hdr->daddr))
1374 prxd->ctrl |= MPC860_FEC_RXBD_CTRL_BC;
1375 else if (eth_addr_is_mcast(&hdr->daddr))
1376 prxd->ctrl |= MPC860_FEC_RXBD_CTRL_MC;
1377 } else {
1378 /* Update the length field */
1379 physmem_copy_u16_to_vm(d->vm,prxd->bd_addr+0x02,clen);
1380 }
1381
1382 /*
1383 * Clear the empty bit (except for the first descriptor,
1384 * which is cleared when the full packet has been stored).
1385 */
1386 if (prxd != &rxd0) {
1387 prxd->ctrl &= ~MPC860_FEC_RXBD_CTRL_E;
1388 physmem_copy_u16_to_vm(d->vm,prxd->bd_addr+0x00,prxd->ctrl);
1389 }
1390
1391 /* Set pointer on next RX descriptor (wrap ring if necessary) */
1392 if (prxd->ctrl & MPC860_FEC_RXBD_CTRL_W) {
1393 d->fec_rdes_current = d->fec_rdes_start;
1394 } else {
1395 d->fec_rdes_current += MPC860_FEC_BD_SIZE;
1396 }
1397
1398 /* If this is the last descriptor, we have finished */
1399 if (!tot_len) {
1400 mpc860_fec_fetch_bd(d,d->fec_rdes_current,&crxd);
1401 prxd = &crxd;
1402 }
1403 }
1404
1405 /* Clear the Empty bit of the first RX descriptor */
1406 rxd0.ctrl &= ~MPC860_FEC_RXBD_CTRL_E;
1407 physmem_copy_u16_to_vm(d->vm,rxd0.bd_addr+0x00,rxd0.ctrl);
1408
1409 /* Trigger FEC IRQ */
1410 d->fec_ievent |= MPC860_IEVENT_RFINT | MPC860_IEVENT_RXB;
1411 mpc860_fec_update_irq_status(d);
1412 return(TRUE);
1413 }
1414
1415 /* MII register read access */
1416 static void mpc860_fec_mii_read_access(struct mpc860_data *d,
1417 u_int phy,u_int reg)
1418 {
1419 m_uint16_t res;
1420
1421 res = d->fec_mii_regs[reg];
1422
1423 switch(reg) {
1424 case 0x00:
1425 res = 0x1100;
1426 break;
1427 case 0x01:
1428 if (d->fec_nio)
1429 res = 0x7829;
1430 else
1431 res = 0;
1432 break;
1433 case 0x02:
1434 res = 0x7810;
1435 break;
1436 case 0x03:
1437 res = 0x0003;
1438 break;
1439 case 0x04:
1440 res = 0x1E1;
1441 break;
1442 case 0x05:
1443 res = 0x41E1;
1444 break;
1445 case 0x06:
1446 res = 0x0004;
1447 break;
1448 case 0x10:
1449 res = 0x0084;
1450 break;
1451 case 0x11:
1452 res = 0x4780;
1453 break;
1454 case 0x12:
1455 res = 0x4000;
1456 break;
1457 case 0x13:
1458 res = 0x0094;
1459 break;
1460 case 0x14:
1461 res = 0x28c8;
1462 break;
1463 default:
1464 res = 0;
1465 }
1466
1467 d->fec_mii_data &= 0xFFFF0000;
1468 d->fec_mii_data |= res;
1469 }
1470
1471 /* MII register read access */
1472 static void mpc860_fec_mii_write_access(struct mpc860_data *d,
1473 u_int phy,u_int reg)
1474 {
1475 #if DEBUG_FEC
1476 MPC_LOG(d,"FEC: Writing 0x%8.8x to MII reg %d\n",
1477 d->fec_mii_data & 0xFFFF,reg);
1478 #endif
1479 d->fec_mii_regs[reg] = d->fec_mii_data & 0xFFFF;
1480 }
1481
1482 /* MII register access */
1483 static void mpc860_fec_mii_access(struct mpc860_data *d)
1484 {
1485 u_int op,phy,reg;
1486
1487 op = (d->fec_mii_data & MPC860_MII_OP_MASK) >> MPC860_MII_OP_SHIFT;
1488 phy = (d->fec_mii_data & MPC860_MII_PHY_MASK) >> MPC860_MII_PHY_SHIFT;
1489 reg = (d->fec_mii_data & MPC860_MII_REG_MASK) >> MPC860_MII_REG_SHIFT;
1490
1491 switch(op) {
1492 /* MII write */
1493 case 0x01:
1494 mpc860_fec_mii_write_access(d,phy,reg);
1495 break;
1496
1497 /* MII read */
1498 case 0x02:
1499 mpc860_fec_mii_read_access(d,phy,reg);
1500 break;
1501
1502 default:
1503 MPC_LOG(d,"FEC: unknown MII opcode %u\n",op);
1504 }
1505
1506 /* MII access completed */
1507 d->fec_ievent |= MPC860_IEVENT_MII;
1508 mpc860_fec_update_irq_status(d);
1509 }
1510
1511 /*
1512 * FEC register access (0xE00 to 0xF84).
1513 */
1514 static int dev_mpc860_fec_access(struct mpc860_data *d,m_uint32_t offset,
1515 u_int op_size,u_int op_type,m_uint64_t *data)
1516 {
1517 switch(offset) {
1518 /* R_DES_START: Beginning of RxBD ring */
1519 case 0xE10:
1520 if (op_type == MTS_READ)
1521 *data = d->fec_rdes_start;
1522 else
1523 d->fec_rdes_start = *data & 0xFFFFFFFC;
1524 break;
1525
1526 /* X_DES_START: Beginning of TxBD ring */
1527 case 0xE14:
1528 if (op_type == MTS_READ)
1529 *data = d->fec_xdes_start;
1530 else
1531 d->fec_xdes_start = *data & 0xFFFFFFFC;
1532 break;
1533
1534 /* R_BUFF_SIZE: Receive Buffer Size */
1535 case 0xE18:
1536 if (op_type == MTS_READ)
1537 *data = d->fec_rbuf_size;
1538 else
1539 d->fec_rbuf_size = *data & 0x7F0;
1540 break;
1541
1542 /* ECNTRL */
1543 case 0xE40:
1544 if (op_type == MTS_READ) {
1545 *data = d->fec_ecntrl;
1546 } else {
1547 if (*data & MPC860_ECNTRL_RESET)
1548 d->fec_ecntrl = 0;
1549 else {
1550 if (!(*data & MPC860_ECNTRL_ETHER_EN)) {
1551 d->fec_xdes_current = d->fec_xdes_start;
1552 d->fec_rdes_current = d->fec_rdes_start;
1553 }
1554
1555 d->fec_ecntrl = *data;
1556 }
1557 }
1558 break;
1559
1560 /* IEVENT: Interrupt Event Register */
1561 case 0xE44:
1562 if (op_type == MTS_READ) {
1563 *data = d->fec_ievent;
1564 } else {
1565 d->fec_ievent &= ~(*data);
1566 mpc860_fec_update_irq_status(d);
1567 }
1568 break;
1569
1570 /* IMASK: Interrupt Mask Register */
1571 case 0xE48:
1572 if (op_type == MTS_READ) {
1573 *data = d->fec_imask;
1574 } else {
1575 d->fec_imask = *data;
1576 mpc860_fec_update_irq_status(d);
1577 }
1578 break;
1579
1580 /* IVEC: Interrupt Vector Register */
1581 case 0xE4C:
1582 if (op_type == MTS_READ)
1583 *data = d->fec_ivec;
1584 else
1585 d->fec_ivec = *data;
1586 break;
1587
1588 /* X_DES_ACTIVE: TxBD Active Register */
1589 case 0xE54:
1590 mpc860_fec_handle_tx_ring(d);
1591 //printf("x_des_active set\n");
1592 break;
1593
1594 /* MII_DATA */
1595 case 0xE80:
1596 if (op_type == MTS_READ) {
1597 *data = d->fec_mii_data;
1598 } else {
1599 d->fec_mii_data = *data;
1600 mpc860_fec_mii_access(d);
1601 }
1602 break;
1603 }
1604
1605 return(0);
1606 }
1607
1608 /* Set NIO for the Fast Ethernet Controller */
1609 int mpc860_fec_set_nio(struct mpc860_data *d,netio_desc_t *nio)
1610 {
1611 /* check that a NIO is not already bound */
1612 if (!d || (d->fec_nio != NULL))
1613 return(-1);
1614
1615 d->fec_nio = nio;
1616 netio_rxl_add(nio,(netio_rx_handler_t)mpc860_fec_handle_rx_pkt,d,NULL);
1617 return(0);
1618 }
1619
1620 /* Unset NIO of the Fast Ethernet Controller */
1621 int mpc860_fec_unset_nio(struct mpc860_data *d)
1622 {
1623 if (!d)
1624 return(-1);
1625
1626 if (d->fec_nio != NULL) {
1627 netio_rxl_remove(d->fec_nio);
1628 d->fec_nio = NULL;
1629 }
1630
1631 return(0);
1632 }
1633
1634 /* ======================================================================== */
1635
1636 #define MPC860_CP_FOP(chan,op) (((chan) << 4) + (op))
1637
1638 /* Execute a command sent through CP Command Register (CPCR) */
1639 static void mpc860_exec_cpcr(struct mpc860_data *d,m_uint32_t cpcr)
1640 {
1641 u_int channel,opcode,fop;
1642
1643 channel = (cpcr >> 4) & 0x0F;
1644 opcode = (cpcr >> 8) & 0x0F;
1645
1646 fop = MPC860_CP_FOP(channel,opcode);
1647
1648 switch(fop) {
1649 /* SPI - Init RX and TX params */
1650 case MPC860_CP_FOP(MPC860_CHAN_SPI_IDMA2_RT,0):
1651 mpc860_spi_init_rx_tx_params(d);
1652 break;
1653
1654 /* SPI - Init RX params */
1655 case MPC860_CP_FOP(MPC860_CHAN_SPI_IDMA2_RT,1):
1656 mpc860_spi_init_rx_params(d);
1657 break;
1658
1659 /* SPI - Init TX params */
1660 case MPC860_CP_FOP(MPC860_CHAN_SPI_IDMA2_RT,2):
1661 mpc860_spi_init_tx_params(d);
1662 break;
1663
1664 /* SCC1 - Init RX and TX params */
1665 case MPC860_CP_FOP(MPC860_CHAN_SCC1,0):
1666 mpc860_scc_init_rx_tx_params(d,0);
1667 break;
1668
1669 /* SCC1 - Init RX params */
1670 case MPC860_CP_FOP(MPC860_CHAN_SCC1,1):
1671 mpc860_scc_init_rx_params(d,0);
1672 break;
1673
1674 /* SCC1 - Init TX params */
1675 case MPC860_CP_FOP(MPC860_CHAN_SCC1,2):
1676 mpc860_scc_init_tx_params(d,0);
1677 break;
1678
1679 /* SCC2 - Init RX and TX params */
1680 case MPC860_CP_FOP(MPC860_CHAN_SCC2,0):
1681 mpc860_scc_init_rx_tx_params(d,1);
1682 break;
1683
1684 /* SCC2 - Init RX params */
1685 case MPC860_CP_FOP(MPC860_CHAN_SCC2,1):
1686 mpc860_scc_init_rx_params(d,1);
1687 break;
1688
1689 /* SCC2 - Init TX params */
1690 case MPC860_CP_FOP(MPC860_CHAN_SCC2,2):
1691 mpc860_scc_init_tx_params(d,1);
1692 break;
1693
1694 /* SCC3 - Init RX and TX params */
1695 case MPC860_CP_FOP(MPC860_CHAN_SCC3,0):
1696 mpc860_scc_init_rx_tx_params(d,2);
1697 break;
1698
1699 /* SCC3 - Init RX params */
1700 case MPC860_CP_FOP(MPC860_CHAN_SCC3,1):
1701 mpc860_scc_init_rx_params(d,2);
1702 break;
1703
1704 /* SCC3 - Init TX params */
1705 case MPC860_CP_FOP(MPC860_CHAN_SCC3,2):
1706 mpc860_scc_init_tx_params(d,2);
1707 break;
1708
1709 /* SCC4 - Init RX and TX params */
1710 case MPC860_CP_FOP(MPC860_CHAN_SCC4,0):
1711 mpc860_scc_init_rx_tx_params(d,3);
1712 break;
1713
1714 /* SCC4 - Init RX params */
1715 case MPC860_CP_FOP(MPC860_CHAN_SCC4,1):
1716 mpc860_scc_init_rx_params(d,3);
1717 break;
1718
1719 /* SCC4 - Init TX params */
1720 case MPC860_CP_FOP(MPC860_CHAN_SCC4,2):
1721 mpc860_scc_init_tx_params(d,3);
1722 break;
1723
1724 default:
1725 MPC_LOG(d,"CPCR: unknown cmd: channel=0x%4.4x, opcode=0x%4.4x\n",
1726 channel,opcode);
1727 }
1728 }
1729
1730 /*
1731 * dev_mpc860_access()
1732 */
1733 void *dev_mpc860_access(cpu_gen_t *cpu,struct vdevice *dev,m_uint32_t offset,
1734 u_int op_size,u_int op_type,m_uint64_t *data)
1735 {
1736 struct mpc860_data *d = dev->priv_data;
1737
1738 if (op_type == MTS_READ)
1739 *data = 0x0;
1740
1741 #if DEBUG_ACCESS
1742 if (op_type == MTS_READ) {
1743 cpu_log(cpu,d->name,
1744 "read from offset 0x%x, pc=0x%llx (size=%u)\n",
1745 offset,cpu_get_pc(cpu),op_size);
1746 } else {
1747 cpu_log(cpu,d->name,
1748 "write to offset 0x%x, value=0x%llx, pc=0x%llx (size=%u)\n",
1749 offset,*data,cpu_get_pc(cpu),op_size);
1750 }
1751 #endif
1752
1753 /* Handle dual-port RAM access */
1754 if ((offset >= MPC860_DPRAM_OFFSET) && (offset < MPC860_DPRAM_END))
1755 return(d->dpram + (offset - MPC860_DPRAM_OFFSET));
1756
1757 /* Handle SCC channels */
1758 if ((offset >= MPC860_REG_SCC_BASE) &&
1759 (offset < (MPC860_REG_SCC_BASE + (4 * 0x20))))
1760 {
1761 dev_mpc860_scc_access(d,offset,op_size,op_type,data);
1762 return NULL;
1763 }
1764
1765 /* Handle Fast Ethernet Controller (FEC) registers */
1766 if ((offset >= MPC860_REG_FEC_BASE) && (offset <= MPC860_REG_FEC_END))
1767 {
1768 dev_mpc860_fec_access(d,offset,op_size,op_type,data);
1769 return NULL;
1770 }
1771
1772 switch(offset) {
1773 /* SWSR - Software Service Register (Watchdog) */
1774 case MPC860_REG_SWSR:
1775 break;
1776
1777 /* SIU Interrupt Pending Register */
1778 case MPC860_REG_SIPEND:
1779 if (op_type == MTS_READ)
1780 *data = d->sipend;
1781 break;
1782
1783 /* SIU Interrupt Mask Register */
1784 case MPC860_REG_SIMASK:
1785 if (op_type == MTS_READ) {
1786 *data = d->simask;
1787 } else {
1788 d->simask = *data;
1789 mpc860_update_irq_status(d);
1790 }
1791 break;
1792
1793 /*
1794 * Cisco 2600:
1795 * Bit 30: 0=NM in slot 1
1796 */
1797 case MPC860_REG_PIPR:
1798 if (op_type == MTS_READ)
1799 *data = 0x3F00F600;
1800 break;
1801
1802 /* PISCR - Periodic Interrupt Status and Control Register */
1803 case MPC860_REG_PISCR:
1804 if (op_type == MTS_WRITE) {
1805 if (*data & 0x80) {
1806 d->sipend &= ~0x40000000;
1807 mpc860_update_irq_status(d);
1808 }
1809 }
1810 break;
1811
1812 case MPC860_REG_TBSCR:
1813 if (op_type == MTS_READ)
1814 *data = 0x45;
1815 break;
1816
1817 /* IDMA1 Status and Mask Registers */
1818 case MPC860_REG_IDSR1:
1819 if (op_type == MTS_READ) {
1820 *data = d->idsr[0];
1821 } else {
1822 d->idsr[0] &= ~(*data);
1823 }
1824 break;
1825
1826 case MPC860_REG_IDMR1:
1827 if (op_type == MTS_READ)
1828 *data = d->idmr[0];
1829 else
1830 d->idmr[0] = *data;
1831 break;
1832
1833 /* IDMA2 Status and Mask Registers */
1834 case MPC860_REG_IDSR2:
1835 if (op_type == MTS_READ)
1836 *data = d->idsr[1];
1837 else
1838 d->idsr[1] &= ~(*data);
1839 break;
1840
1841 case MPC860_REG_IDMR2:
1842 if (op_type == MTS_READ)
1843 *data = d->idmr[1];
1844 else
1845 d->idmr[1] = *data;
1846 break;
1847
1848 /* CICR - CPM Interrupt Configuration Register */
1849 case MPC860_REG_CICR:
1850 if (op_type == MTS_READ)
1851 *data = d->cicr;
1852 else
1853 d->cicr = *data;
1854 break;
1855
1856 /* CIPR - CPM Interrupt Pending Register */
1857 case MPC860_REG_CIPR:
1858 if (op_type == MTS_READ)
1859 *data = d->cipr;
1860 else {
1861 d->cipr &= ~(*data);
1862 mpc860_update_cpm_int_status(d);
1863 }
1864 break;
1865
1866 /* CIMR - CPM Interrupt Mask Register */
1867 case MPC860_REG_CIMR:
1868 if (op_type == MTS_READ)
1869 *data = d->cimr;
1870 else {
1871 d->cimr = *data;
1872 mpc860_update_cpm_int_status(d);
1873 }
1874 break;
1875
1876 /* PCSO - Port C Special Options Register */
1877 case MPC860_REG_PCSO:
1878 if (op_type == MTS_WRITE) {
1879 if (*data & 0x01) {
1880 #if DEBUG_IDMA
1881 MPC_LOG(d,"activating IDMA0\n");
1882 #endif
1883 mpc860_idma_start_channel(d,0);
1884 }
1885 }
1886 break;
1887
1888 /* PCDAT - Port C Data Register */
1889 case MPC860_REG_PCDAT:
1890 if (op_type == MTS_WRITE)
1891 d->pcdat = *data;
1892 else
1893 *data = d->pcdat;
1894 break;
1895
1896 /* PBDAT - Port B Data Register */
1897 case MPC860_REG_PBDAT:
1898 if (op_type == MTS_WRITE)
1899 d->pbdat = *data;
1900 else
1901 *data = d->pbdat;
1902 break;
1903
1904 /* CPCR - CP Command Register */
1905 case MPC860_REG_CPCR:
1906 if (op_type == MTS_WRITE)
1907 mpc860_exec_cpcr(d,(m_uint32_t)(*data));
1908 break;
1909
1910 /* SPCOM - SPI Command Register */
1911 case MPC860_REG_SPCOM:
1912 if ((op_type == MTS_WRITE) && (*data & MPC860_SPCOM_STR))
1913 mpc860_spi_start_tx(d);
1914 break;
1915
1916 #if DEBUG_UNKNOWN
1917 default:
1918 if (op_type == MTS_READ) {
1919 cpu_log(cpu,d->name,
1920 "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
1921 offset,cpu_get_pc(cpu),op_size);
1922 } else {
1923 cpu_log(cpu,d->name,
1924 "write to addr 0x%x, value=0x%llx, pc=0x%llx (size=%u)\n",
1925 offset,*data,cpu_get_pc(cpu),op_size);
1926 }
1927 #endif
1928 }
1929
1930 return NULL;
1931 }
1932
1933 /* Set IRQ pending status */
1934 void mpc860_set_pending_irq(struct mpc860_data *d,m_uint32_t val)
1935 {
1936 d->sipend |= 1 << val;
1937 mpc860_update_irq_status(d);
1938 }
1939
1940 /* Clear a pending IRQ */
1941 void mpc860_clear_pending_irq(struct mpc860_data *d,m_uint32_t val)
1942 {
1943 d->sipend &= ~(1 << val);
1944 mpc860_update_irq_status(d);
1945 }
1946
1947 /* Shutdown the MPC860 device */
1948 void dev_mpc860_shutdown(vm_instance_t *vm,struct mpc860_data *d)
1949 {
1950 if (d != NULL) {
1951 /* Remove the device */
1952 dev_remove(vm,&d->dev);
1953
1954 /* Free the structure itself */
1955 free(d);
1956 }
1957 }
1958
1959 /* Create the MPC860 device */
1960 int dev_mpc860_init(vm_instance_t *vm,char *name,
1961 m_uint64_t paddr,m_uint32_t len)
1962 {
1963 struct mpc860_data *d;
1964
1965 if (!(d = malloc(sizeof(*d)))) {
1966 fprintf(stderr,"mpc860: unable to create device data.\n");
1967 return(-1);
1968 }
1969
1970 memset(d,0,sizeof(*d));
1971 d->name = name;
1972 d->vm = vm;
1973
1974 vm_object_init(&d->vm_obj);
1975 d->vm_obj.name = name;
1976 d->vm_obj.data = d;
1977 d->vm_obj.shutdown = (vm_shutdown_t)dev_mpc860_shutdown;
1978
1979 dev_init(&d->dev);
1980 d->dev.name = name;
1981 d->dev.priv_data = d;
1982 d->dev.phys_addr = paddr;
1983 d->dev.phys_len = len;
1984 d->dev.handler = dev_mpc860_access;
1985
1986 /* Set the default SPI base address */
1987 dpram_w16(d,MPC860_SPI_BASE_ADDR,MPC860_SPI_BASE);
1988
1989 /* Map this device to the VM */
1990 vm_bind_device(vm,&d->dev);
1991 vm_object_add(vm,&d->vm_obj);
1992 return(0);
1993 }
1994

  ViewVC Help
Powered by ViewVC 1.1.26