/[dynamips]/upstream/dynamips-0.2.5/dev_c7200_bri.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 /upstream/dynamips-0.2.5/dev_c7200_bri.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Sat Oct 6 16:01:44 2007 UTC (12 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 26717 byte(s)
import 0.2.5 from upstream

1 /*
2 * Cisco C7200 (Predator) Simulation Platform.
3 * Copyright (C) 2005-2006 Christophe Fillot. All rights reserved.
4 *
5 * EEPROM types:
6 * - 0x3d: PA-4B
7 * - 0x3e: PA-8B
8 *
9 * Vernon Missouri offered a PA-4B.
10 *
11 * It is based on the Munich32 chip:
12 * http://www.infineon.com//upload/Document/cmc_upload/migrated_files/document_files/Datasheet/m32_34m.pdf
13 *
14 * There is also one TP3420A per BRI port.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <errno.h>
22 #include <pthread.h>
23 #include <assert.h>
24
25 #include "mips64.h"
26 #include "dynamips.h"
27 #include "memory.h"
28 #include "device.h"
29 #include "net.h"
30 #include "net_io.h"
31 #include "ptask.h"
32 #include "dev_c7200.h"
33
34 /* Debugging flags */
35 #define DEBUG_ACCESS 1
36 #define DEBUG_TRANSMIT 0
37 #define DEBUG_RECEIVE 0
38
39 /* PCI vendor/product codes */
40 #define BRI_PCI_VENDOR_ID 0x10ee
41 #define BRI_PCI_PRODUCT_ID 0x4013
42
43 /* Memory used by the munich32 chip */
44 #define MUNICH32_MEM_SIZE 0x40000
45
46 /* Maximum packet size */
47 #define M32_MAX_PKT_SIZE 8192
48
49 /* 32 timeslots and 32 channels for a Munich32 chip */
50 #define M32_NR_TIMESLOTS 32
51 #define M32_NR_CHANNELS 32
52
53 /* Offsets */
54 #define M32_OFFSET_TS 0x0c /* Timeslots */
55 #define M32_OFFSET_CHAN 0x8c /* Channel specification */
56 #define M32_OFFSET_CRDA 0x28c /* Current RX descriptor address */
57 #define M32_OFFSET_CTDA 0x30c /* Current TX descriptor address */
58
59 /* Action Specification */
60 #define M32_AS_PCM_MASK 0xE0000000 /* PCM Highway Format */
61 #define M32_AS_PCM_SHIFT 29
62 #define M32_AS_MFL_MASK 0x1FFF0000 /* Maximum Frame Length */
63 #define M32_AS_MFL_SHIFT 16
64 #define M32_AS_IN 0x00008000 /* Initialization Procedure */
65 #define M32_AS_ICO 0x00004000 /* Initialize Channel Only */
66 #define M32_AS_CHAN_MASK 0x00001F00 /* Channel Number */
67 #define M32_AS_CHAN_SHIFT 8
68 #define M32_AS_IM 0x00000080 /* Interrupt Mask */
69 #define M32_AS_RES 0x00000040 /* Reset */
70 #define M32_AS_LOOPS_MASK 0x00000038 /* Loops (LOC,LOOP,LOOPI) */
71 #define M32_AS_LOOPS_SHIFT 3
72 #define M32_AS_IA 0x00000004 /* Interrupt Attention */
73
74 /* Interrupt Information */
75 #define M32_II_INT 0x80000000 /* Interrupt */
76 #define M32_II_VN3 0x20000000 /* Silicon version number */
77 #define M32_II_VN2 0x10000000
78 #define M32_II_VN1 0x08000000
79 #define M32_II_FRC 0x04000000 /* Framing bits changed */
80 #define M32_II_ARACK 0x00008000 /* Action Request Acknowledge */
81 #define M32_II_ARF 0x00004000 /* Action Request Failed */
82 #define M32_II_HI 0x00002000 /* Host Initiated Interrupt */
83 #define M32_II_FI 0x00001000 /* Frame Indication */
84 #define M32_II_IFC 0x00000800 /* Idle Flag Change */
85 #define M32_II_SF 0x00000400 /* Short Frame */
86 #define M32_II_ERR 0x00000200 /* Error condition */
87 #define M32_II_FO 0x00000100 /* Overflow/Underflow */
88 #define M32_II_RT 0x00000020 /* Direction (Transmit/Receive Int) */
89
90 /* Timeslot Assignment */
91 #define M32_TS_TTI 0x20000000 /* Transmit Timeslot Inhibit */
92 #define M32_TS_TCN_MASK 0x1F000000 /* Transmit Channel Number Mask */
93 #define M32_TS_TCN_SHIFT 24
94 #define M32_TS_TFM_MASK 0x00FF0000 /* Transmit Fill Mask */
95 #define M32_TS_TFM_SHIFT 16
96 #define M32_TS_RTI 0x00002000 /* Receive Timeslot Inhibit */
97 #define M32_TS_RCN_MASK 0x00001F00 /* Receive Channel Number Mask */
98 #define M32_TS_RCN_SHIFT 8
99 #define M32_TS_RFM_MASK 0x000000FF /* Receive Fill Mask */
100 #define M32_TS_RFM_SHIFT 0
101
102 /* Transmit Descriptor */
103 #define M32_TXDESC_FE 0x80000000 /* Frame End */
104 #define M32_TXDESC_HOLD 0x40000000 /* Hold=0: usable by Munich */
105 #define M32_TXDESC_HI 0x20000000 /* Host Initiated Interrupt */
106 #define M32_TXDESC_NO_MASK 0x1FFF0000 /* Number of bytes */
107 #define M32_TXDESC_NO_SHIFT 16
108 #define M32_TXDESC_V110 0x00008000 /* V.110/X.30 frame */
109 #define M32_TXDESC_CSM 0x00000800 /* CRC Select per Message */
110 #define M32_TXDESC_FNUM 0x000001FF /* Inter-Frame Time-Fill chars */
111
112 /* Munich32 TX descriptor */
113 struct m32_tx_desc {
114 m_uint32_t params; /* Size + Flags */
115 m_uint32_t tdp; /* Transmit Data Pointer */
116 m_uint32_t ntdp; /* Next Transmit Descriptor Pointer */
117 };
118
119 /* Receive Descriptor (parameters) */
120 #define M32_RXDESC_HOLD 0x40000000 /* Hold */
121 #define M32_RXDESC_HI 0x20000000 /* Host Initiated Interrupt */
122 #define M32_RXDESC_NO_MASK 0x1FFF0000 /* Size of receive data section */
123 #define M32_RXDESC_NO_SHIFT 16
124
125 /* Receive Descriptor (status) */
126 #define M32_RXDESC_FE 0x80000000 /* Frame End */
127 #define M32_RXDESC_C 0x40000000
128 #define M32_RXDESC_BNO_MASK 0x1FFF0000 /* Bytes stored in data section */
129 #define M32_RXDESC_BNO_SHIFT 16
130 #define M32_RXDESC_SF 0x00004000
131 #define M32_RXDESC_LOSS 0x00002000 /* Error in sync pattern */
132 #define M32_RXDESC_CRCO 0x00001000 /* CRC error */
133 #define M32_RXDESC_NOB 0x00000800 /* Bit content not divisible by 8 */
134 #define M32_RXDESC_LFD 0x00000400 /* Long Frame Detected */
135 #define M32_RXDESC_RA 0x00000200 /* Receive Abort */
136 #define M32_RXDESC_ROF 0x00000100 /* Overflow of internal buffer */
137
138 /* Munich32 RX descriptor */
139 struct m32_rx_desc {
140 m_uint32_t params; /* RX parameters (hold, hi, ...) */
141 m_uint32_t status; /* Status */
142 m_uint32_t rdp; /* Receive Data Pointer */
143 m_uint32_t nrdp; /* Next Receive Descriptor Pointer */
144 };
145
146 /* Munich32 channel */
147 struct m32_channel {
148 m_uint32_t status;
149 m_uint32_t frda;
150 m_uint32_t ftda;
151 m_uint32_t itbs;
152
153 /* Physical addresses of current RX and TX descriptors */
154 m_uint32_t rx_current,tx_current;
155
156 /* Poll mode */
157 u_int poll_mode;
158 };
159
160 /* Munich32 chip data */
161 struct m32_data {
162 /* Virtual machine */
163 vm_instance_t *vm;
164
165 /* TX ring scanner task id */
166 ptask_id_t tx_tid;
167
168 /* Interrupt Queue */
169 m_uint32_t iq_base_addr;
170 m_uint32_t iq_cur_addr;
171 u_int iq_size;
172
173 /* Timeslots */
174 m_uint32_t timeslots[M32_NR_TIMESLOTS];
175
176 /* Channels */
177 struct m32_channel channels[M32_NR_CHANNELS];
178
179 /* Embedded config memory */
180 m_uint32_t cfg_mem[MUNICH32_MEM_SIZE/4];
181 };
182
183 /* === TP3420 SID === */
184
185 /* Activation / Desactivation */
186 #define TP3420_SID_NOP 0xFF /* No Operation */
187 #define TP3420_SID_PDN 0x00 /* Power Down */
188 #define TP3420_SID_PUP 0x20 /* Power Up */
189 #define TP3420_SID_DR 0x01 /* Deactivation Request */
190 #define TP3420_SID_FI2 0x02 /* Force Info 2 (NT Only) */
191 #define TP3420_SID_MMA 0x1F /* Monitor Mode Activation */
192
193 /* Device Modes */
194 #define TP3420_SID_NTA 0x04 /* NT Mode, Adaptive Sampling */
195 #define TP3420_SID_NTF 0x05 /* NT Mode, Fixed Sampling */
196 #define TP3420_SID_TES 0x06 /* TE Mode, Digital System Interface Slave */
197 #define TP3420_SID_TEM 0x07 /* TE Mode, Digital System Interface Master */
198
199 /* Digital Interface Formats */
200 #define TP3420_SID_DIF1 0x08 /* Digital System Interface Format 1 */
201 #define TP3420_SID_DIF2 0x09 /* Digital System Interface Format 2 */
202 #define TP3420_SID_DIF3 0x0A /* Digital System Interface Format 3 */
203 #define TP3420_SID_DIF4 0x0B /* Digital System Interface Format 4 */
204
205 /* BCLK Frequency Settings */
206 #define TP3420_SID_BCLK1 0x98 /* Set BCLK to 2.048 Mhz */
207 #define TP3420_SID_BCLK2 0x99 /* Set BCLK to 256 Khz */
208 #define TP3420_SID_BCLK3 0x9A /* Set BCLK to 512 Khz */
209 #define TP3420_SID_BCLK4 0x9B /* Set BCLK to 2.56 Mhz */
210
211 /* B Channel Exchange */
212 #define TP3420_SID_BDIR 0x0C /* B Channels Mapped Direct (B1->B1,B2->B2) */
213 #define TP3420_SID_BEX 0x0D /* B Channels Exchanged (B1->B2,B2->B1) */
214
215 /* D Channel Access */
216 #define TP3420_SID_DREQ1 0x0E /* D Channel Request, Class 1 Message */
217 #define TP3420_SID_DREQ2 0x0F /* D Channel Request, Class 2 Message */
218
219 /* D Channel Access Control */
220 #define TP3420_SID_DACCE 0x90 /* Enable D-Channel Access Mechanism */
221 #define TP3420_SID_DACCD 0x91 /* Disable D-Channel Access Mechanism */
222 #define TP3420_SID_EBIT0 0x96 /* Force Echo Bit to 0 */
223 #define TP3420_SID_EBITI 0x97 /* Force Echo Bit to Inverted Received D bit */
224 #define TP3420_SID_EBITN 0x9C /* Reset EBITI and EBIT0 to Normal Condition */
225 #define TP3420_SID_DCKE 0xF1 /* D Channel Clock Enable */
226
227 /* End Of Message (EOM) Interrupt */
228 #define TP3420_SID_EIE 0x10 /* EOM Interrupt Enabled */
229 #define TP3420_SID_EID 0x11 /* EOM Interrupt Disabled */
230
231 /* B1 Channel Enable/Disable */
232 #define TP3420_SID_B1E 0x14 /* B1 Channel Enabled */
233 #define TP3420_SID_B1D 0x15 /* B1 Channel Disabled */
234
235 /* B2 Channel Enable/Disable */
236 #define TP3420_SID_B2E 0x16 /* B2 Channel Enabled */
237 #define TP3420_SID_B2D 0x17 /* B2 Channel Disabled */
238
239 /* Loopback Tests Modes */
240 #define TP3420_SID_CAL 0x1B /* Clear All Loopbacks */
241
242 /* Control Device State Reading */
243 #define TP3420_SID_ENST 0x92 /* Enable the Device State Output on NOCST */
244 #define TP3420_SID_DISST 0x93 /* Disable the Device State Output on NOCST */
245
246 /* PIN Signal Selection */
247 #define TP3420_SID_PINDEF 0xE0 /* Redefine PIN signals */
248
249 /* TP3420 Status Register */
250 #define TP3420_SR_LSD 0x02 /* Line Signal Detected Far-End */
251 #define TP3420_SR_AP 0x03 /* Activation Pending */
252 #define TP3420_SR_AI 0x0C /* Activation Indication */
253 #define TP3420_SR_EI 0x0E /* Error Indication */
254 #define TP3420_SR_DI 0x0F /* Deactivation Indication */
255 #define TP3420_SR_EOM 0x06 /* End of D-channel TX message */
256 #define TP3420_SR_CON 0x07 /* Lost Contention for D channel */
257
258 /* NO Change Return status */
259 #define TP3420_SR_NOC 0x00 /* NOC Status after DISST command */
260 #define TP3420_SR_NOCST 0x80 /* NOC Status after ENST command */
261
262 /* BRI Channel Index */
263 #define BRI_CHAN_INDEX_B1 0
264 #define BRI_CHAN_INDEX_B2 1
265 #define BRI_CHAN_INDEX_D 2
266
267 /* PA-4B Data */
268 struct pa_4b_data {
269 char *name;
270
271 /* Virtual machine */
272 vm_instance_t *vm;
273
274 /* Virtual device */
275 struct vdevice *dev;
276
277 /* PCI device information */
278 struct pci_device *pci_dev;
279
280 /* NetIO descriptor */
281 netio_desc_t *nio;
282
283 /* Munich32 data and base offset */
284 struct m32_data m32_data;
285 u_int m32_offset;
286 };
287
288 /* EEPROM definition (3D = PA-4B, 3E = PA-8B) */
289 static const m_uint16_t eeprom_pa_4b_data[64] = {
290 0x013D, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
291 0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
292 };
293
294 static const struct c7200_eeprom eeprom_pa_4b = {
295 "PA-4B", (m_uint16_t *)eeprom_pa_4b_data,
296 sizeof(eeprom_pa_4b_data)/2,
297 };
298
299 /* Log a PA-4B/PA-8B message */
300 #define BRI_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
301
302 /* Read a configuration word */
303 static inline m_uint32_t m32_get_cfgw(struct m32_data *d,m_uint32_t offset)
304 {
305 return(d->cfg_mem[offset >> 2]);
306 }
307
308 /* Write a configuration word */
309 static inline void m32_set_cfgw(struct m32_data *d,m_uint32_t offset,
310 m_uint32_t val)
311 {
312 d->cfg_mem[offset >> 2] = val;
313 }
314
315 /* Post an interrupt into the interrupt queue */
316 static int m32_post_interrupt(struct m32_data *d,m_uint32_t iq_value)
317 {
318 if (!d->iq_base_addr)
319 return(-1);
320
321 /* The INT bit is mandatory */
322 iq_value |= M32_II_INT;
323
324 #if 0
325 printf("M32: Posting interrupt iq_val=0x%8.8x at 0x%8.8x\n",
326 iq_value,d->iq_cur_addr);
327 #endif
328
329 physmem_copy_u32_to_vm(d->vm,d->iq_cur_addr,iq_value);
330 d->iq_cur_addr += sizeof(m_uint32_t);
331
332 if (d->iq_cur_addr >= (d->iq_base_addr + d->iq_size))
333 d->iq_cur_addr = d->iq_base_addr;
334
335 return(0);
336 }
337
338 /* Fetch a timeslot assignment */
339 static int m32_fetch_ts_assign(struct m32_data *d,u_int ts_id)
340 {
341 m_uint32_t offset;
342
343 offset = M32_OFFSET_TS + (ts_id * sizeof(m_uint32_t));
344 d->timeslots[ts_id] = m32_get_cfgw(d,offset);
345 return(0);
346 }
347
348 /* Fetch all timeslot assignments */
349 static int m32_fetch_all_ts(struct m32_data *d)
350 {
351 m_uint32_t offset = M32_OFFSET_TS;
352 u_int i;
353
354 for(i=0;i<M32_NR_TIMESLOTS;i++,offset+=sizeof(m_uint32_t))
355 d->timeslots[i] = m32_get_cfgw(d,offset);
356
357 return(0);
358 }
359
360 /* Show timeslots assignments (debugging) */
361 static void m32_show_ts_assign(struct m32_data *d)
362 {
363 m_uint32_t ts;
364 u_int i;
365
366 printf("MUNICH32 timeslots:\n");
367
368 for(i=0;i<M32_NR_TIMESLOTS;i++) {
369 ts = d->timeslots[i];
370
371 if ((ts & (M32_TS_TTI|M32_TS_RTI)) != (M32_TS_TTI|M32_TS_RTI)) {
372 printf(" Timeslot %2u: ",i);
373
374 if (!(ts & M32_TS_TTI)) {
375 printf("TCN=%2u TFM=0x%2.2x ",
376 (ts & M32_TS_TCN_MASK) >> M32_TS_TCN_SHIFT,
377 (ts & M32_TS_TFM_MASK) >> M32_TS_TFM_SHIFT);
378 }
379
380 if (!(ts & M32_TS_RTI)) {
381 printf("RCN=%2u RFM=0x%2.2x",
382 (ts & M32_TS_RCN_MASK) >> M32_TS_RCN_SHIFT,
383 (ts & M32_TS_RFM_MASK) >> M32_TS_RFM_SHIFT);
384 }
385
386 printf("\n");
387 }
388 }
389
390 printf("\n");
391 }
392
393 /* Show info about a channels (debugging) */
394 static void m32_show_channel(struct m32_data *d,u_int chan_id)
395 {
396 struct m32_channel *chan;
397
398 chan = &d->channels[chan_id];
399 printf("M32 Channel %u:\n",chan_id);
400 printf(" Status : 0x%8.8x\n",chan->status);
401 printf(" FRDA : 0x%8.8x\n",chan->frda);
402 printf(" FTDA : 0x%8.8x\n",chan->ftda);
403 printf(" ITBS : 0x%8.8x\n",chan->itbs);
404 }
405
406 /* Fetch a channel specification */
407 static int m32_fetch_chan_spec(struct m32_data *d,u_int chan_id)
408 {
409 struct m32_channel *chan;
410 m_uint32_t offset;
411
412 offset = M32_OFFSET_CHAN + (chan_id * 4 * sizeof(m_uint32_t));
413 chan = &d->channels[chan_id];
414
415 chan->status = m32_get_cfgw(d,offset);
416 chan->frda = m32_get_cfgw(d,offset+4);
417 chan->ftda = m32_get_cfgw(d,offset+8);
418 chan->itbs = m32_get_cfgw(d,offset+12);
419
420 chan->poll_mode = 0;
421 chan->rx_current = chan->frda;
422 chan->tx_current = chan->ftda;
423
424 m32_set_cfgw(d,M32_OFFSET_CTDA+(chan_id*4),chan->tx_current);
425
426 #if 1
427 if (chan_id == 2) {
428 printf("M32: Fetched channel %u\n",chan_id);
429 //m32_show_ts_assign(d);
430 m32_show_channel(d,chan_id);
431 }
432 #endif
433 return(0);
434 }
435
436 /* Fetch all channel specifications */
437 static void m32_fetch_all_chan_spec(struct m32_data *d)
438 {
439 u_int i;
440
441 for(i=0;i<M32_NR_CHANNELS;i++)
442 m32_fetch_chan_spec(d,i);
443 }
444
445 /* Try to acquire the specified TX descriptor */
446 static int m32_tx_acquire(struct m32_data *d,m_uint32_t txd_addr,
447 struct m32_tx_desc *txd)
448 {
449 m_uint32_t params;
450
451 if (!(params = physmem_copy_u32_from_vm(d->vm,txd_addr)) & M32_TXDESC_HOLD)
452 return(FALSE);
453
454 txd->params = params;
455 txd->tdp = physmem_copy_u32_from_vm(d->vm,txd_addr+4);
456 txd->ntdp = physmem_copy_u32_from_vm(d->vm,txd_addr+8);
457 return(TRUE);
458 }
459
460 /* Try to acquire the next TX descriptor */
461 static int m32_tx_acquire_next(struct m32_data *d,m_uint32_t *txd_addr)
462 {
463 m_uint32_t params;
464
465 /* HOLD bit must be reset */
466 if ((params = physmem_copy_u32_from_vm(d->vm,*txd_addr)) & M32_TXDESC_HOLD)
467 return(FALSE);
468
469 *txd_addr = physmem_copy_u32_from_vm(d->vm,(*txd_addr)+8);
470 return(TRUE);
471 }
472
473 /* Scan a channel TX ring */
474 static inline int m32_tx_scan(struct m32_data *d,u_int chan_id)
475 {
476 struct m32_channel *chan = &d->channels[chan_id];
477 m_uint8_t pkt[M32_MAX_PKT_SIZE];
478 struct m32_tx_desc txd;
479 m_uint32_t pkt_len;
480
481 if (!chan->tx_current)
482 return(FALSE);
483
484 switch(chan->poll_mode) {
485 case 0:
486 m32_set_cfgw(d,M32_OFFSET_CTDA+(chan_id*4),chan->tx_current);
487
488 /* Try to transmit data */
489 if (!m32_tx_acquire(d,chan->tx_current,&txd))
490 return(FALSE);
491
492 printf("M32: TX scanner for channel %u (tx_current=0x%8.8x)\n",
493 chan_id,chan->tx_current);
494
495 printf("M32: params=0x%8.8x, next=0x%8.8x.\n",txd.params,txd.ntdp);
496
497 /* The descriptor has been acquired */
498 pkt_len = (txd.params & M32_TXDESC_NO_MASK) >> M32_TXDESC_NO_SHIFT;
499 physmem_copy_from_vm(d->vm,pkt,txd.tdp,pkt_len);
500
501 printf("M32: data_ptr=0x%x, len=%u\n",txd.tdp,pkt_len);
502 mem_dump(stdout,pkt,pkt_len);
503
504 /* Poll the next descriptor (wait for HOLD bit to be reset */
505 chan->poll_mode = 1;
506
507 if (txd.params & M32_TXDESC_FE) {
508 m32_post_interrupt(d,M32_II_FI | chan_id);
509 vm_set_irq(d->vm,2);
510 }
511
512 break;
513
514 case 1:
515 if (!m32_tx_acquire_next(d,&chan->tx_current))
516 return(FALSE);
517
518 printf("M32: branching on next descriptor 0x%x\n",chan->tx_current);
519 chan->poll_mode = 0;
520 break;
521 }
522
523 return(TRUE);
524 }
525
526 /* Scan the all channel TX rings */
527 static void m32_tx_scan_all_channels(struct m32_data *d)
528 {
529 u_int i;
530
531 for(i=0;i<M32_NR_CHANNELS;i++)
532 m32_tx_scan(d,i);
533 }
534
535 /*
536 * Handle an action request.
537 *
538 * IN, ICO and RES bits are mutually exclusive.
539 */
540 static int m32_action_req(struct m32_data *d,m_uint32_t action)
541 {
542 u_int chan_id;
543
544 /* Define a new Interrupt Queue */
545 if (action & M32_AS_IA) {
546 d->iq_base_addr = d->iq_cur_addr = m32_get_cfgw(d,4);
547 d->iq_size = ((m32_get_cfgw(d,8) & 0xFF) + 1) * 16 * sizeof(m_uint32_t);
548 }
549
550 /* Initialization Procedure */
551 if (action & M32_AS_IN) {
552 /* Fetch all timeslots assignments */
553 m32_fetch_all_ts(d);
554
555 /* Fetch specification of the specified channel */
556 chan_id = (action & M32_AS_CHAN_MASK) >> M32_AS_CHAN_SHIFT;
557 m32_fetch_chan_spec(d,chan_id);
558
559 /* Generate acknowledge */
560 if (!(action & M32_AS_IM))
561 m32_post_interrupt(d,M32_II_ARACK);
562 }
563
564 /* Initialize Channel Only */
565 if (action & M32_AS_ICO) {
566 /* Fetch specification of the specified channel */
567 chan_id = (action & M32_AS_CHAN_MASK) >> M32_AS_CHAN_SHIFT;
568 m32_fetch_chan_spec(d,chan_id);
569
570 /* Generate acknowledge */
571 if (!(action & M32_AS_IM))
572 m32_post_interrupt(d,M32_II_ARACK);
573 }
574
575 /* Reset */
576 if (action & M32_AS_RES) {
577 /* Fetch all timeslots assignments */
578 m32_fetch_all_ts(d);
579
580 /* Fetch all channel specifications */
581 m32_fetch_all_chan_spec(d);
582
583 /* Generate acknowledge */
584 if (!(action & M32_AS_IM))
585 m32_post_interrupt(d,M32_II_ARACK);
586 }
587
588 return(0);
589 }
590
591 /* Munich32 general access function */
592 static void *m32_gen_access(struct m32_data *d,cpu_mips_t *cpu,
593 m_uint32_t offset,u_int op_size,u_int op_type,
594 m_uint64_t *data)
595 {
596 u_int p;
597
598 switch(offset) {
599 /* Action Specification */
600 case 0x0:
601 if (op_type == MTS_WRITE)
602 m32_action_req(d,*data);
603 return NULL;
604
605 /* Configuration memory */
606 default:
607 switch(op_size) {
608 case 4:
609 if (op_type == MTS_READ)
610 *data = m32_get_cfgw(d,offset);
611 else
612 m32_set_cfgw(d,offset,*data);
613 break;
614
615 case 1:
616 if (op_type == MTS_READ) {
617 *data = m32_get_cfgw(d,offset & ~0x03);
618 *data >>= (24 - ((offset & 0x03) << 3));
619 *data &= 0xFF;
620 } else {
621 printf("UNSUPPORTED(1)!!!!\n");
622 }
623 break;
624
625 case 2:
626 if (op_type == MTS_READ) {
627 *data = m32_get_cfgw(d,offset & ~0x03);
628 *data >>= (16 - ((offset & 0x03) << 3));
629 *data &= 0xFFFF;
630 } else {
631 printf("UNSUPPORTED(2)!!!!\n");
632 }
633 break;
634
635 case 8:
636 if (op_type == MTS_READ) {
637 *data = (m_uint64_t)m32_get_cfgw(d,offset) << 32;
638 *data |= m32_get_cfgw(d,offset+4);
639 } else {
640 printf("UNSUPPORTED(8)!!!!\n");
641 }
642 break;
643
644 default:
645 printf("UNSUPPORTED (size=%u)!!!\n",op_size);
646 }
647 }
648
649 return NULL;
650 }
651
652 /*
653 * pa_4b_access()
654 */
655 void *pa_4b_access(cpu_mips_t *cpu,struct vdevice *dev,m_uint32_t offset,
656 u_int op_size,u_int op_type,m_uint64_t *data)
657 {
658 struct pa_4b_data *d = dev->priv_data;
659 static m_uint32_t test1,test2,test3;
660
661 if (op_type == MTS_READ)
662 *data = 0xFFFFFFFF;
663
664 #if DEBUG_ACCESS
665 if (offset >= MUNICH32_MEM_SIZE) {
666 if (op_type == MTS_READ) {
667 cpu_log(cpu,d->name,"read access to offset = 0x%x, pc = 0x%llx "
668 "(op_size=%u)\n",offset,cpu->pc,op_size);
669 } else {
670 cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
671 "val = 0x%llx (op_size=%u)\n",offset,cpu->pc,*data,op_size);
672 }
673 }
674 #endif
675
676 /* Specific cases */
677 switch(offset) {
678 case 0x40008:
679 if (op_type == MTS_READ)
680 *data = 0xFF;
681 break;
682
683 case 0x40030:
684 if (op_type == MTS_READ)
685 *data = 0xFF;
686 break;
687
688 case 0x40000:
689 if (op_type == MTS_READ)
690 *data = 0xFFFF;
691 break;
692
693 case 0x40020:
694 if (op_type == MTS_READ)
695 *data = 0xFFFFFFFF; //test2;
696 else
697 test2 = *data;
698 break;
699
700 case 0x40021:
701 if (op_type == MTS_READ)
702 *data = 0xFF; //test3;
703 else
704 test3 = *data;
705 break;
706
707 case 0x40023:
708 if (op_type == MTS_READ)
709 *data = 0xFF;
710 break;
711
712 case 0x40040:
713 if (op_type == MTS_READ)
714 *data = 0x04;
715 break;
716
717 /* Channels enabled ? */
718 case 0x40044:
719 if (op_type == MTS_READ)
720 *data = 0xFF; /* 0x02 */
721 break;
722
723 /* SID */
724 case 0x40050:
725 if (op_type == MTS_WRITE) {
726 test1 = *data;
727 } else {
728 switch(test1) {
729 case TP3420_SID_PUP:
730 *data = TP3420_SR_AI;
731 vm_set_irq(d->vm,C7200_PA_MGMT_IRQ);
732 break;
733 case TP3420_SID_ENST:
734 *data = 0xB0;
735 break;
736 default:
737 *data = 0x03;
738 break;
739 }
740 }
741 break;
742
743 default:
744 if (offset < MUNICH32_MEM_SIZE)
745 return(m32_gen_access(&d->m32_data,cpu,offset - d->m32_offset,
746 op_size,op_type,data));
747 }
748
749 return NULL;
750 }
751
752 /*
753 * pci_munich32_read()
754 */
755 static m_uint32_t pci_munich32_read(cpu_mips_t *cpu,struct pci_device *dev,
756 int reg)
757 {
758 struct pa_4b_data *d = dev->priv_data;
759
760 #if DEBUG_ACCESS
761 BRI_LOG(d,"read PCI register 0x%x\n",reg);
762 #endif
763 switch(reg) {
764 case PCI_REG_BAR0:
765 return(d->dev->phys_addr);
766 default:
767 return(0);
768 }
769 }
770
771 /*
772 * pci_munich32_write()
773 */
774 static void pci_munich32_write(cpu_mips_t *cpu,struct pci_device *dev,
775 int reg,m_uint32_t value)
776 {
777 struct pa_4b_data *d = dev->priv_data;
778
779 #if DEBUG_ACCESS
780 BRI_LOG(d,"write 0x%x to PCI register 0x%x\n",value,reg);
781 #endif
782
783 switch(reg) {
784 case PCI_REG_BAR0:
785 vm_map_device(cpu->vm,d->dev,(m_uint64_t)value);
786 BRI_LOG(d,"registers are mapped at 0x%x\n",value);
787 break;
788 }
789 }
790
791 /*
792 * dev_c7200_bri_init()
793 *
794 * Add a PA-4B/PA-8B port adapter into specified slot.
795 */
796 int dev_c7200_pa_bri_init(c7200_t *router,char *name,u_int pa_bay)
797 {
798 struct pci_device *pci_dev;
799 struct pa_4b_data *d;
800 struct vdevice *dev;
801
802 /* Allocate the private data structure for PA-4B chip */
803 if (!(d = malloc(sizeof(*d)))) {
804 fprintf(stderr,"%s (PA-4B): out of memory\n",name);
805 return(-1);
806 }
807
808 memset(d,0,sizeof(*d));
809 d->m32_offset = 0x08;
810 d->m32_data.vm = router->vm;
811
812 /* Set the EEPROM */
813 c7200_pa_set_eeprom(router,pa_bay,&eeprom_pa_4b);
814
815 /* Add as PCI device PA-4B */
816 pci_dev = pci_dev_add(router->pa_bay[pa_bay].pci_map,name,
817 BRI_PCI_VENDOR_ID,BRI_PCI_PRODUCT_ID,
818 0,0,C7200_NETIO_IRQ,d,
819 NULL,pci_munich32_read,pci_munich32_write);
820
821 if (!pci_dev) {
822 fprintf(stderr,"%s (PA-4B): unable to create PCI device.\n",name);
823 return(-1);
824 }
825
826 /* Create the PA-4B structure */
827 d->name = name;
828 d->pci_dev = pci_dev;
829 d->vm = router->vm;
830
831 /* Create the device itself */
832 if (!(dev = dev_create(name))) {
833 fprintf(stderr,"%s (PA-4B): unable to create device.\n",name);
834 return(-1);
835 }
836
837 dev->phys_len = 0x800000;
838 dev->handler = pa_4b_access;
839
840 /* Store device info */
841 dev->priv_data = d;
842 d->dev = dev;
843
844 /* Map this device to the VM */
845 vm_bind_device(router->vm,dev);
846
847 /* Store device info into the router structure */
848 return(c7200_pa_set_drvinfo(router,pa_bay,d));
849 }
850
851 /* Remove a PA-4B from the specified slot */
852 int dev_c7200_pa_bri_shutdown(c7200_t *router,u_int pa_bay)
853 {
854 struct c7200_pa_bay *bay;
855 struct pa_4b_data *d;
856
857 if (!(bay = c7200_pa_get_info(router,pa_bay)))
858 return(-1);
859
860 d = bay->drv_info;
861
862 /* Remove the PA EEPROM */
863 c7200_pa_unset_eeprom(router,pa_bay);
864
865 /* Remove the PCI device */
866 pci_dev_remove(d->pci_dev);
867
868 /* Remove the device from the CPU address space */
869 vm_unbind_device(router->vm,d->dev);
870 cpu_group_rebuild_mts(router->vm->cpu_group);
871
872 /* Free the device structure itself */
873 free(d->dev);
874 free(d);
875 return(0);
876 }
877
878 /* Bind a Network IO descriptor to a specific port */
879 int dev_c7200_pa_bri_set_nio(c7200_t *router,u_int pa_bay,u_int port_id,
880 netio_desc_t *nio)
881 {
882 struct pa_4b_data *d;
883
884 if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))
885 return(-1);
886
887 if (d->nio != NULL)
888 return(-1);
889
890 d->nio = nio;
891
892 /* TEST */
893 d->m32_data.tx_tid = ptask_add((ptask_callback)m32_tx_scan_all_channels,&d->m32_data,NULL);
894
895 //netio_rxl_add(nio,(netio_rx_handler_t)dev_pa_4b_handle_rxring,d,NULL);
896 return(0);
897 }
898
899 /* Bind a Network IO descriptor to a specific port */
900 int dev_c7200_pa_bri_unset_nio(c7200_t *router,u_int pa_bay,u_int port_id)
901 {
902 struct pa_4b_data *d;
903
904 if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))
905 return(-1);
906
907 if (d->nio) {
908 /* TEST */
909 ptask_remove(d->m32_data.tx_tid);
910
911 //netio_rxl_remove(d->nio);
912 d->nio = NULL;
913 }
914 return(0);
915 }
916
917 /* PA-4B driver */
918 struct c7200_pa_driver dev_c7200_pa_4b_driver = {
919 "PA-4B", 0,
920 dev_c7200_pa_bri_init,
921 dev_c7200_pa_bri_shutdown,
922 dev_c7200_pa_bri_set_nio,
923 dev_c7200_pa_bri_unset_nio,
924 };

  ViewVC Help
Powered by ViewVC 1.1.26