File indexing completed on 2025-05-11 08:24:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #define DMA_MEM_128K
0035 #if !defined(DMA_MEM_128K)
0036 #define DMA_MEM_16K
0037 #endif
0038
0039 #include <bsp.h>
0040 #include <rtems/libio.h>
0041 #include <stdlib.h>
0042 #include <stdio.h>
0043 #include <string.h>
0044 #include <assert.h>
0045 #include <ctype.h>
0046 #include <rtems/bspIo.h>
0047
0048 #include <drvmgr/drvmgr.h>
0049 #include <grlib/b1553brm.h>
0050 #include <grlib/ambapp.h>
0051 #include <grlib/ambapp_bus.h>
0052
0053 #include <grlib/grlib_impl.h>
0054
0055
0056
0057
0058 #undef DEBUG
0059 #undef FUNCDEBUG
0060
0061
0062
0063 #define EVENT_QUEUE_SIZE 1024
0064
0065
0066 #define INDEX(x) ( x&(EVENT_QUEUE_SIZE-1) )
0067
0068 #if 0
0069 #define DBG(x...) printk(x)
0070 #else
0071 #define DBG(x...)
0072 #endif
0073
0074 #ifdef FUNCDEBUG
0075 #define FUNCDBG(x...) printk(x)
0076 #else
0077 #define FUNCDBG(x...)
0078 #endif
0079
0080 #define READ_REG(address) (*(volatile unsigned int *)address)
0081 #define READ_DMA(address) grlib_read_uncached16((unsigned int)address)
0082
0083 static rtems_device_driver brm_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0084 static rtems_device_driver brm_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0085 static rtems_device_driver brm_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0086 static rtems_device_driver brm_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0087 static rtems_device_driver brm_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0088 static rtems_device_driver brm_control(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0089
0090 #define BRM_DRIVER_TABLE_ENTRY { brm_initialize, brm_open, brm_close, brm_read, brm_write, brm_control }
0091
0092 static rtems_driver_address_table b1553brm_driver = BRM_DRIVER_TABLE_ENTRY;
0093
0094 struct msg {
0095 unsigned short miw;
0096 unsigned short time;
0097 unsigned short data[32];
0098 };
0099 #if defined(DMA_MEM_128K)
0100 struct circ_buf {
0101 struct msg msgs[9];
0102 };
0103 #elif defined(DMA_MEM_16K)
0104
0105 struct circ_buf_2 {
0106 struct msg msgs[2];
0107 };
0108
0109 struct circ_buf_1 {
0110 struct msg msgs[1];
0111 };
0112 #endif
0113
0114 struct irq_log_list {
0115 volatile unsigned short iiw;
0116 volatile unsigned short iaw;
0117 };
0118
0119 typedef struct {
0120
0121 struct drvmgr_dev *dev;
0122 char devName[52];
0123 struct brm_reg *regs;
0124
0125 unsigned int memarea_base;
0126 unsigned int memarea_base_remote;
0127 unsigned int cfg_clksel;
0128 unsigned int cfg_clkdiv;
0129 unsigned int cfg_freq;
0130
0131
0132 struct desc_table {
0133 volatile unsigned short ctrl;
0134 volatile unsigned short top;
0135 volatile unsigned short cur;
0136 volatile unsigned short bot;
0137 } *desc;
0138
0139 volatile unsigned short *mem;
0140
0141 struct {
0142
0143 struct {
0144 unsigned short ctrl;
0145 unsigned short cw1;
0146 unsigned short cw2;
0147 unsigned short dptr;
0148 unsigned short tsw[2];
0149 unsigned short ba;
0150 unsigned short timer;
0151 } descs[128];
0152
0153
0154 struct {
0155 unsigned short data[32];
0156 } msg_data[128];
0157
0158 #if defined(DMA_MEM_128K)
0159
0160 unsigned short unused[(64*1024-(128*8+128*32))-16*2];
0161 #elif defined(DMA_MEM_16K)
0162 unsigned short unused[(8*1024-(128*8+128*32))-16*2];
0163 #endif
0164
0165 struct irq_log_list irq_logs[16];
0166 } *bcmem;
0167
0168 #if defined(DMA_MEM_128K)
0169
0170
0171
0172
0173
0174 struct {
0175
0176 struct desc_table rxsubs[32];
0177
0178 struct desc_table txsubs[32];
0179
0180 struct desc_table rxmodes[32];
0181
0182 struct desc_table txmodes[32];
0183
0184
0185 struct circ_buf rxsuba_msgs[32];
0186
0187 struct circ_buf txsuba_msgs[32];
0188
0189 struct circ_buf rxmode_msgs[32];
0190
0191 struct circ_buf txmode_msgs[32];
0192
0193
0194 unsigned short unused[(64*1024-(4*32*4+4*32*9*34))-16*2];
0195
0196
0197 struct irq_log_list irq_logs[16];
0198 } *rtmem;
0199 #elif defined(DMA_MEM_16K)
0200
0201
0202
0203
0204
0205
0206 struct {
0207
0208 struct desc_table rxsubs[32];
0209
0210 struct desc_table txsubs[32];
0211
0212 struct desc_table rxmodes[32];
0213
0214 struct desc_table txmodes[32];
0215
0216
0217 struct circ_buf_2 rxsuba_msgs[32];
0218
0219 struct circ_buf_2 txsuba_msgs[32];
0220
0221 struct circ_buf_2 rxmode_msgs[32];
0222
0223 struct circ_buf_1 txmode_msgs[32];
0224
0225
0226 unsigned short unused[8*1024 -(4*32*4 +3*32*2*34 +1*32*1*34) -16*2];
0227
0228
0229 struct irq_log_list irq_logs[16];
0230 } *rtmem;
0231 #else
0232 #error You must define one DMA_MEM_???K
0233 #endif
0234
0235
0236 struct irq_log_list *irq_log;
0237 unsigned int irq;
0238
0239
0240 struct rt_msg *rt_event;
0241 struct bm_msg *bm_event;
0242
0243 unsigned int head, tail;
0244
0245 unsigned int last_read[128];
0246 unsigned int written[32];
0247
0248 struct bc_msg *cur_list;
0249
0250 int tx_blocking, rx_blocking;
0251
0252 rtems_id rx_sem, tx_sem, dev_sem;
0253 int minor;
0254 int irqno;
0255 unsigned int mode;
0256 #ifdef DEBUG
0257 unsigned int log[EVENT_QUEUE_SIZE*4];
0258 unsigned int log_i;
0259 #endif
0260
0261 rtems_id event_id;
0262 unsigned int status;
0263 int bc_list_fail;
0264 } brm_priv;
0265
0266 static void b1553brm_interrupt(void *arg);
0267 static rtems_device_driver rt_init(brm_priv *brm);
0268
0269 #define OFS(ofs) (((unsigned int)&ofs & 0x1ffff)>>1)
0270
0271 static int b1553brm_driver_io_registered = 0;
0272 static rtems_device_major_number b1553brm_driver_io_major = 0;
0273
0274
0275
0276
0277 int b1553brm_register_io(rtems_device_major_number *m);
0278 int b1553brm_device_init(brm_priv *pDev);
0279
0280 int b1553brm_init2(struct drvmgr_dev *dev);
0281 int b1553brm_init3(struct drvmgr_dev *dev);
0282 int b1553brm_remove(struct drvmgr_dev *dev);
0283
0284 struct drvmgr_drv_ops b1553brm_ops =
0285 {
0286 .init = {NULL, b1553brm_init2, b1553brm_init3, NULL},
0287 .remove = b1553brm_remove,
0288 .info = NULL
0289 };
0290
0291 struct amba_dev_id b1553brm_ids[] =
0292 {
0293 {VENDOR_GAISLER, GAISLER_B1553BRM},
0294 {0, 0}
0295 };
0296
0297 struct amba_drv_info b1553brm_drv_info =
0298 {
0299 {
0300 DRVMGR_OBJ_DRV,
0301 NULL,
0302 NULL,
0303 DRIVER_AMBAPP_GAISLER_B1553BRM_ID,
0304 "B1553BRM_DRV",
0305 DRVMGR_BUS_TYPE_AMBAPP,
0306 &b1553brm_ops,
0307 NULL,
0308 0,
0309 0,
0310 },
0311 &b1553brm_ids[0]
0312 };
0313
0314 void b1553brm_register_drv (void)
0315 {
0316 DBG("Registering B1553BRM driver\n");
0317 drvmgr_drv_register(&b1553brm_drv_info.general);
0318 }
0319
0320 int b1553brm_init2(struct drvmgr_dev *dev)
0321 {
0322 brm_priv *priv;
0323
0324 DBG("B1553BRM[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0325 priv = dev->priv = grlib_calloc(1, sizeof(*priv));
0326 if ( !priv )
0327 return DRVMGR_NOMEM;
0328 priv->dev = dev;
0329
0330
0331
0332 return DRVMGR_OK;
0333 }
0334
0335 int b1553brm_init3(struct drvmgr_dev *dev)
0336 {
0337 brm_priv *priv;
0338 char prefix[32];
0339 rtems_status_code status;
0340
0341 priv = dev->priv;
0342
0343
0344
0345 if ( b1553brm_driver_io_registered == 0) {
0346
0347 if ( b1553brm_register_io(&b1553brm_driver_io_major) ) {
0348
0349 dev->priv = NULL;
0350 return DRVMGR_FAIL;
0351 }
0352
0353 b1553brm_driver_io_registered = 1;
0354 }
0355
0356
0357
0358
0359
0360 if ( b1553brm_device_init(priv) ) {
0361 return DRVMGR_FAIL;
0362 }
0363
0364
0365 prefix[0] = '\0';
0366 if ( drvmgr_get_dev_prefix(dev, prefix) ) {
0367
0368
0369
0370 sprintf(priv->devName, "/dev/b1553brm%d", dev->minor_drv);
0371 } else {
0372
0373
0374
0375 sprintf(priv->devName, "/dev/%sb1553brm%d", prefix, dev->minor_bus);
0376 }
0377
0378
0379 status = rtems_io_register_name(priv->devName, b1553brm_driver_io_major, dev->minor_drv);
0380 if (status != RTEMS_SUCCESSFUL) {
0381 return DRVMGR_FAIL;
0382 }
0383
0384 return DRVMGR_OK;
0385 }
0386
0387 int b1553brm_remove(struct drvmgr_dev *dev)
0388 {
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401 return DRVMGR_OK;
0402 }
0403
0404
0405
0406 int b1553brm_register_io(rtems_device_major_number *m)
0407 {
0408 rtems_status_code r;
0409
0410 if ((r = rtems_io_register_driver(0, &b1553brm_driver, m)) == RTEMS_SUCCESSFUL) {
0411 DBG("B1553BRM driver successfully registered, major: %d\n", *m);
0412 } else {
0413 switch(r) {
0414 case RTEMS_TOO_MANY:
0415 printk("B1553BRM rtems_io_register_driver failed: RTEMS_TOO_MANY\n");
0416 return -1;
0417 case RTEMS_INVALID_NUMBER:
0418 printk("B1553BRM rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n");
0419 return -1;
0420 case RTEMS_RESOURCE_IN_USE:
0421 printk("B1553BRM rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n");
0422 return -1;
0423 default:
0424 printk("B1553BRM rtems_io_register_driver failed\n");
0425 return -1;
0426 }
0427 }
0428 return 0;
0429 }
0430
0431 int b1553brm_device_init(brm_priv *pDev)
0432 {
0433 struct amba_dev_info *ambadev;
0434 struct ambapp_core *pnpinfo;
0435 union drvmgr_key_value *value;
0436 unsigned int mem;
0437 int size;
0438
0439
0440 ambadev = (struct amba_dev_info *)pDev->dev->businfo;
0441 if ( ambadev == NULL ) {
0442 return -1;
0443 }
0444 pnpinfo = &ambadev->info;
0445 pDev->irqno = pnpinfo->irq;
0446
0447
0448
0449 if ( pnpinfo->ahb_slv ) {
0450
0451 pDev->regs = (struct brm_reg *)pnpinfo->ahb_slv->start[0];
0452 } else {
0453
0454 pDev->regs = (struct brm_reg *)pnpinfo->apb_slv->start;
0455 }
0456 pDev->minor = pDev->dev->minor_drv;
0457 #ifdef DEBUG
0458 pDev->log_i = 0;
0459 memset(pDev->log,0,sizeof(pDev->log));
0460 #endif
0461
0462 #ifdef DMA_MEM_128K
0463 size = 128 * 1024;
0464 #else
0465 size = 16 * 1024;
0466 #endif
0467
0468
0469 value = drvmgr_dev_key_get(pDev->dev, "dmaBaseAdr", DRVMGR_KT_POINTER);
0470 if (value)
0471 mem = (unsigned int)value->ptr;
0472
0473 if (value && (mem & 1)) {
0474
0475
0476
0477 pDev->memarea_base_remote = mem & ~1;
0478 drvmgr_translate_check(pDev->dev, DMAMEM_TO_CPU,
0479 (void *)pDev->memarea_base_remote,
0480 (void **)&pDev->memarea_base,
0481 size);
0482 } else {
0483 if (!value) {
0484
0485
0486
0487 mem = (unsigned int)grlib_malloc(size + 128 * 1024);
0488 if (!mem){
0489 printk("BRM: Failed to allocate HW memory\n\r");
0490 return -1;
0491 }
0492
0493 pDev->memarea_base = (mem + 0x1ffff) & ~0x1ffff;
0494 } else {
0495 pDev->memarea_base = mem;
0496 }
0497
0498
0499 drvmgr_translate_check(pDev->dev, CPUMEM_TO_DMA,
0500 (void *)pDev->memarea_base,
0501 (void **)&pDev->memarea_base_remote,
0502 size);
0503 }
0504
0505
0506 memset((char *)pDev->memarea_base, 0, size);
0507
0508
0509 pDev->desc = (struct desc_table *) pDev->memarea_base;
0510 pDev->mem = (volatile unsigned short *) pDev->memarea_base;
0511 pDev->irq_log = (struct irq_log_list *)(pDev->memarea_base + (0xFFE0<<1));
0512
0513 pDev->bm_event = NULL;
0514 pDev->rt_event = NULL;
0515
0516 pDev->cfg_clksel = 0;
0517 pDev->cfg_clkdiv = 0;
0518 pDev->cfg_freq = BRM_FREQ_24MHZ;
0519
0520 value = drvmgr_dev_key_get(pDev->dev, "clkSel", DRVMGR_KT_INT);
0521 if ( value ) {
0522 pDev->cfg_clksel = value->i & CLKSEL_MASK;
0523 }
0524
0525 value = drvmgr_dev_key_get(pDev->dev, "clkDiv", DRVMGR_KT_INT);
0526 if ( value ) {
0527 pDev->cfg_clkdiv = value->i & CLKDIV_MASK;
0528 }
0529
0530 value = drvmgr_dev_key_get(pDev->dev, "coreFreq", DRVMGR_KT_INT);
0531 if ( value ) {
0532 pDev->cfg_freq = value->i & BRM_FREQ_MASK;
0533 }
0534
0535
0536 pDev->regs->w_ctrl = (pDev->cfg_clksel<<9) | (pDev->cfg_clkdiv<<5);
0537
0538 pDev->regs->w_ctrl = 1<<10 | READ_REG(&pDev->regs->w_ctrl);
0539
0540
0541 if ( rtems_semaphore_create(rtems_build_name('B', 'M', 'R', '0' + pDev->minor),
0542 0,
0543 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0544 0,
0545 &pDev->rx_sem) != RTEMS_SUCCESSFUL ) {
0546 printk("BRM: Failed to create rx semaphore\n");
0547 return RTEMS_INTERNAL_ERROR;
0548 }
0549
0550
0551 if ( rtems_semaphore_create(rtems_build_name('B', 'M', 'T', '0' + pDev->minor),
0552 1,
0553 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0554 0,
0555 &pDev->tx_sem) != RTEMS_SUCCESSFUL ){
0556 printk("BRM: Failed to create tx semaphore\n");
0557 return RTEMS_INTERNAL_ERROR;
0558 }
0559
0560
0561 if ( rtems_semaphore_create(rtems_build_name('B', 'M', 'D', '0' + pDev->minor),
0562 1,
0563 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0564 0,
0565 &pDev->dev_sem) != RTEMS_SUCCESSFUL ){
0566 printk("BRM: Failed to create device semaphore\n");
0567 return RTEMS_INTERNAL_ERROR;
0568 }
0569
0570
0571 rt_init(pDev);
0572
0573 return 0;
0574 }
0575
0576 static int odd_parity(unsigned int data) {
0577 unsigned int i=0;
0578
0579 while(data)
0580 {
0581 i++;
0582 data &= (data - 1);
0583 }
0584
0585 return !(i&1);
0586 }
0587
0588 static void start_operation(brm_priv *brm) {
0589 unsigned int ctrl = READ_REG(&brm->regs->ctrl);
0590 brm->regs->ctrl = ctrl | 0x8000;
0591 }
0592
0593 static void stop_operation(brm_priv *brm) {
0594 unsigned int ctrl = READ_REG(&brm->regs->ctrl);
0595 brm->regs->ctrl = ctrl & ~0x8000;
0596 }
0597
0598 static int is_executing(brm_priv *brm) {
0599 unsigned int ctrl = READ_REG(&brm->regs->ctrl);
0600 return ((ctrl>>15) & 1);
0601 }
0602
0603 static void clr_int_logs(struct irq_log_list *logs){
0604 int i;
0605 for(i=0; i<16; i++){
0606 logs[i].iiw = 0xffff;
0607 logs[i].iaw = 0x0;
0608 }
0609 }
0610
0611 unsigned short b1553brm_rt_cmd_legalize[16] = {
0612 0,
0613 0,
0614 0,
0615 0,
0616 0,
0617 0,
0618 0xffff,
0619 0xffff,
0620 0xffff,
0621 0xfffd,
0622 0xfe01,
0623 0xfff2,
0624 0xffff,
0625 0xfffd,
0626 0xfe05,
0627 0xffff,
0628 };
0629
0630 static rtems_device_driver rt_init(brm_priv *brm) {
0631 unsigned int i;
0632
0633 brm->head = brm->tail = 0;
0634 brm->rx_blocking = brm->tx_blocking = 1;
0635
0636 if ( brm->bm_event )
0637 free(brm->bm_event);
0638 brm->bm_event = NULL;
0639
0640 if ( brm->rt_event )
0641 free(brm->rt_event);
0642
0643 brm->bcmem = NULL;
0644 brm->rtmem = (void *)brm->mem;
0645
0646 brm->rt_event = grlib_malloc(EVENT_QUEUE_SIZE*sizeof(*brm->rt_event));
0647
0648 if (brm->rt_event == NULL) {
0649 DBG("BRM driver failed to allocated memory.");
0650 return RTEMS_NO_MEMORY;
0651 }
0652
0653 brm->irq_log = (struct irq_log_list *)&brm->rtmem->irq_logs[0];
0654
0655 brm->regs->ctrl = 0x1912;
0656 brm->regs->oper = 0x0900;
0657 brm->regs->imask = BRM_RT_ILLCMD_IRQ|BRM_SUBAD_IRQ|BRM_TAPF_IRQ|BRM_DMAF_IRQ|BRM_WRAPF_IRQ|BRM_MERR_IRQ;
0658 brm->regs->dpoint = 0;
0659 brm->regs->ipoint = OFS(brm->rtmem->irq_logs[0]);
0660 brm->regs->enhanced = 0x0000 | brm->cfg_freq;
0661 brm->regs->w_ctrl = (brm->cfg_clksel<<9) | (brm->cfg_clkdiv<<5) | 1;
0662 brm->regs->w_irqctrl = 6;
0663 brm->regs->w_ahbaddr = brm->memarea_base_remote;
0664
0665 clr_int_logs(brm->irq_log);
0666
0667
0668 for (i = 0; i < 16; i++) {
0669 brm->regs->rt_cmd_leg[i] = b1553brm_rt_cmd_legalize[i];
0670 }
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680 for (i = 0; i < 32; i++) {
0681 brm->rtmem->rxsubs[i].ctrl = 0x00E0;
0682 brm->rtmem->rxsubs[i].top = OFS(brm->rtmem->rxsuba_msgs[i]);
0683 brm->rtmem->rxsubs[i].cur = OFS(brm->rtmem->rxsuba_msgs[i]);
0684 brm->rtmem->rxsubs[i].bot = OFS(brm->rtmem->rxsuba_msgs[i+1]) - sizeof(struct msg)/2;
0685 brm->last_read[i] = OFS(brm->rtmem->rxsuba_msgs[i]);
0686 }
0687
0688 for (i = 0; i < 32; i++) {
0689 brm->rtmem->txsubs[i].ctrl = 0x0060;
0690 brm->rtmem->txsubs[i].top = OFS(brm->rtmem->txsuba_msgs[i]);
0691 brm->rtmem->txsubs[i].cur = OFS(brm->rtmem->txsuba_msgs[i]);
0692 brm->rtmem->txsubs[i].bot = OFS(brm->rtmem->txsuba_msgs[i+1]) - sizeof(struct msg)/2;
0693 brm->last_read[i+32] = OFS(brm->rtmem->txsuba_msgs[i]);
0694 brm->written[i] = OFS(brm->rtmem->txsuba_msgs[i]);
0695 }
0696
0697 for (i = 0; i < 32; i++) {
0698 brm->rtmem->rxmodes[i].ctrl = 0x00E0;
0699 brm->rtmem->rxmodes[i].top = OFS(brm->rtmem->rxmode_msgs[i]);
0700 brm->rtmem->rxmodes[i].cur = OFS(brm->rtmem->rxmode_msgs[i]);
0701 brm->rtmem->rxmodes[i].bot = OFS(brm->rtmem->rxmode_msgs[i+1]) - sizeof(struct msg)/2;
0702 brm->last_read[i+64] = OFS(brm->rtmem->rxmode_msgs[i]);
0703 }
0704
0705 for (i = 0; i < 32; i++) {
0706 brm->rtmem->txmodes[i].ctrl = 0x0060;
0707 brm->rtmem->txmodes[i].top = OFS(brm->rtmem->txmode_msgs[i]);
0708 brm->rtmem->txmodes[i].cur = OFS(brm->rtmem->txmode_msgs[i]);
0709 brm->rtmem->txmodes[i].bot = OFS(brm->rtmem->txmode_msgs[i+1]) - sizeof(struct msg)/2;
0710 brm->last_read[i+96] = OFS(brm->rtmem->txmode_msgs[i]);
0711 }
0712
0713 #ifdef DEBUG
0714 printk("b1553BRM DMA_AREA: 0x%x\n", (unsigned int)brm->rtmem);
0715 printk("LOG: 0x%x\n", &brm->log[0]);
0716 printk("LOG_I: 0x%x\n", &brm->log_i);
0717 #endif
0718
0719 brm->mode = BRM_MODE_RT;
0720
0721 return RTEMS_SUCCESSFUL;
0722 }
0723
0724 static rtems_device_driver bc_init(brm_priv *brm){
0725
0726 if ( brm->bm_event )
0727 free(brm->bm_event);
0728 brm->bm_event = NULL;
0729
0730 if ( brm->rt_event )
0731 free(brm->rt_event);
0732 brm->rt_event = NULL;
0733
0734 brm->bcmem = (void *)brm->mem;
0735 brm->rtmem = NULL;
0736 brm->irq_log = (struct irq_log_list *)&brm->bcmem->irq_logs[0];
0737
0738 brm->head = brm->tail = 0;
0739 brm->rx_blocking = brm->tx_blocking = 1;
0740
0741 brm->regs->ctrl = 0x0006;
0742 brm->regs->oper = 0x0800;
0743 brm->regs->imask = BRM_EOL_IRQ|BRM_BC_ILLCMD_IRQ|BRM_ILLOP_IRQ|BRM_DMAF_IRQ|BRM_WRAPF_IRQ|BRM_MERR_IRQ;
0744 brm->regs->dpoint = 0;
0745 brm->regs->ipoint = OFS(brm->bcmem->irq_logs[0]);
0746 brm->regs->enhanced = 0x0000 | (brm->cfg_freq&BRM_FREQ_MASK);
0747 brm->regs->w_ctrl = (brm->cfg_clksel<<9) | (brm->cfg_clkdiv<<5) | 1;
0748 brm->regs->w_irqctrl = 6;
0749 brm->regs->w_ahbaddr = brm->memarea_base_remote;
0750
0751 clr_int_logs(brm->irq_log);
0752
0753 brm->mode = BRM_MODE_BC;
0754
0755 return RTEMS_SUCCESSFUL;
0756 }
0757
0758 static rtems_device_driver bm_init(brm_priv *brm) {
0759
0760
0761 brm->head = brm->tail = 0;
0762 brm->rx_blocking = brm->tx_blocking = 1;
0763
0764 if ( brm->rt_event )
0765 free(brm->rt_event);
0766 brm->rt_event = NULL;
0767
0768 if ( brm->bm_event )
0769 free(brm->bm_event);
0770
0771 brm->bcmem = NULL;
0772 brm->rtmem = NULL;
0773
0774 brm->bm_event = grlib_malloc(EVENT_QUEUE_SIZE*sizeof(*brm->bm_event));
0775
0776 if (brm->bm_event == NULL) {
0777 DBG("BRM driver failed to allocated memory.");
0778 return RTEMS_NO_MEMORY;
0779 }
0780
0781
0782 brm->irq_log = (struct irq_log_list *)&brm->mem[8*1024-16*2];
0783
0784 brm->regs->ctrl = 0x0006;
0785 brm->regs->oper = 0x0A00;
0786 brm->regs->imask = BRM_MBC_IRQ|BRM_MERR_IRQ|BRM_DMAF_IRQ;
0787 brm->regs->dpoint = 0;
0788 brm->regs->ipoint = OFS(brm->mem[8*1024-16*2]);
0789 brm->regs->mcpoint = 0;
0790 brm->regs->mdpoint = 0x100;
0791 brm->regs->mbc = 1;
0792 brm->regs->enhanced = 0x0000 | (brm->cfg_freq&BRM_FREQ_MASK);
0793 brm->regs->w_ctrl = (brm->cfg_clksel<<9) | (brm->cfg_clkdiv<<5) | 1;
0794 brm->regs->w_irqctrl = 6;
0795 brm->regs->w_ahbaddr = brm->memarea_base_remote;
0796
0797 clr_int_logs(brm->irq_log);
0798
0799 brm->mode = BRM_MODE_BM;
0800
0801 return RTEMS_SUCCESSFUL;
0802 }
0803
0804
0805 static rtems_device_driver brm_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0806 {
0807 return RTEMS_SUCCESSFUL;
0808 }
0809
0810 static rtems_device_driver brm_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) {
0811 brm_priv *brm;
0812 struct drvmgr_dev *dev;
0813
0814 FUNCDBG("brm_open\n");
0815
0816 if ( drvmgr_get_dev(&b1553brm_drv_info.general, minor, &dev) ) {
0817 DBG("Wrong minor %d\n", minor);
0818 return RTEMS_UNSATISFIED;
0819 }
0820 brm = (brm_priv *)dev->priv;
0821
0822 if (rtems_semaphore_obtain(brm->dev_sem, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL) {
0823 DBG("brm_open: resource in use\n");
0824 return RTEMS_RESOURCE_IN_USE;
0825 }
0826
0827
0828 brm->event_id = 0;
0829
0830 start_operation(brm);
0831
0832
0833 if ( drvmgr_interrupt_register(brm->dev, 0, "b1553brm", b1553brm_interrupt, brm) ) {
0834 rtems_semaphore_release(brm->dev_sem);
0835 return RTEMS_UNSATISFIED;
0836 }
0837
0838 return RTEMS_SUCCESSFUL;
0839 }
0840
0841 static rtems_device_driver brm_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0842 {
0843 brm_priv *brm;
0844 struct drvmgr_dev *dev;
0845
0846 FUNCDBG("brm_close");
0847
0848 if ( drvmgr_get_dev(&b1553brm_drv_info.general, minor, &dev) ) {
0849 return RTEMS_UNSATISFIED;
0850 }
0851 brm = (brm_priv *)dev->priv;
0852
0853 drvmgr_interrupt_unregister(brm->dev, 0, b1553brm_interrupt, brm);
0854
0855 stop_operation(brm);
0856 rtems_semaphore_release(brm->dev_sem);
0857
0858 return RTEMS_SUCCESSFUL;
0859 }
0860
0861 static int get_rt_messages(brm_priv *brm, void *buf, unsigned int msg_count)
0862 {
0863 struct rt_msg *dest = (struct rt_msg *) buf;
0864 int count = 0;
0865
0866 if (brm->head == brm->tail) {
0867 return 0;
0868 }
0869
0870 do {
0871
0872 DBG("rt read - head: %d, tail: %d\n", brm->head, brm->tail);
0873 dest[count++] = brm->rt_event[INDEX(brm->tail++)];
0874 } while (brm->head != brm->tail && count < msg_count);
0875
0876 return count;
0877 }
0878
0879 static int get_bm_messages(brm_priv *brm, void *buf, unsigned int msg_count)
0880 {
0881 struct bm_msg *dest = (struct bm_msg *) buf;
0882 int count = 0;
0883
0884 if (brm->head == brm->tail) {
0885 return 0;
0886 }
0887
0888 do {
0889
0890 DBG("bm read - head: %d, tail: %d\n", brm->head, brm->tail);
0891 dest[count++] = brm->bm_event[INDEX(brm->tail++)];
0892
0893 } while (brm->head != brm->tail && count < msg_count);
0894
0895 return count;
0896 }
0897
0898 static rtems_device_driver brm_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0899 {
0900 rtems_libio_rw_args_t *rw_args;
0901 int count = 0;
0902 brm_priv *brm;
0903 struct drvmgr_dev *dev;
0904 int (*get_messages)(brm_priv *brm, void *buf, unsigned int count);
0905
0906 if ( drvmgr_get_dev(&b1553brm_drv_info.general, minor, &dev) ) {
0907 return RTEMS_UNSATISFIED;
0908 }
0909 brm = (brm_priv *)dev->priv;
0910
0911 if ( ! (brm->mode & (BRM_MODE_RT | BRM_MODE_BM)) ){
0912 return RTEMS_INVALID_NAME;
0913 }
0914
0915 rw_args = (rtems_libio_rw_args_t *) arg;
0916
0917 if ( ((READ_REG(&brm->regs->oper)>>8) & 3) == 1 ) {
0918 get_messages = get_rt_messages;
0919 } else {
0920 get_messages = get_bm_messages;
0921 }
0922
0923 FUNCDBG("brm_read [%i,%i]: buf: 0x%x len: %i\n",major, minor, (unsigned int)rw_args->buffer,rw_args->count);
0924
0925 while ( (count=get_messages(brm,rw_args->buffer, rw_args->count)) == 0 ) {
0926 if (brm->rx_blocking) {
0927 rtems_semaphore_obtain(brm->rx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0928 } else {
0929
0930 return RTEMS_RESOURCE_IN_USE;
0931 }
0932 }
0933
0934 rw_args->bytes_moved = count;
0935 return RTEMS_SUCCESSFUL;
0936 }
0937
0938 static rtems_device_driver brm_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0939 {
0940 rtems_libio_rw_args_t *rw_args;
0941 struct rt_msg *source;
0942 unsigned int count=0, current, next, descriptor, wc, suba;
0943 brm_priv *brm;
0944 struct drvmgr_dev *dev;
0945
0946 if ( drvmgr_get_dev(&b1553brm_drv_info.general, minor, &dev) ) {
0947 return RTEMS_UNSATISFIED;
0948 }
0949 brm = (brm_priv *)dev->priv;
0950
0951 if ( ! (brm->mode & BRM_MODE_RT) ){
0952 return RTEMS_INVALID_NAME;
0953 }
0954
0955 rw_args = (rtems_libio_rw_args_t *) arg;
0956 source = (struct rt_msg *) rw_args->buffer;
0957
0958 FUNCDBG("brm_write [%i,%i]: buf: 0x%x len: %i\n",major, minor, (unsigned int)rw_args->buffer,rw_args->count);
0959
0960 do {
0961
0962 descriptor = source[count].desc & 0x7F;
0963 suba = descriptor-32;
0964 wc = source[count].miw >> 11;
0965 wc = wc ? wc : 32;
0966
0967
0968 if (descriptor < 32 || descriptor >= 64)
0969 return RTEMS_INVALID_NAME;
0970
0971 current = brm->desc[descriptor].cur;
0972 next = brm->written[suba] + 2 + wc;
0973
0974 if (brm->written[suba] < current) {
0975
0976 if (next > current) {
0977
0978
0979 if (brm->tx_blocking && count == 0) {
0980 rtems_semaphore_obtain(brm->tx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0981 } else if ( count > 0 ) {
0982
0983 break;
0984 } else {
0985
0986 return RTEMS_RESOURCE_IN_USE;
0987 }
0988 }
0989 }
0990
0991 memcpy((void *)&brm->mem[brm->written[suba]], &source[count], (2+wc)*2);
0992
0993 count++;
0994
0995 if (next >= brm->desc[descriptor].bot) {
0996 next = brm->desc[descriptor].top;
0997 }
0998 brm->written[suba] = next;
0999
1000 } while (count < rw_args->count);
1001
1002 rw_args->bytes_moved = count;
1003
1004 return RTEMS_SUCCESSFUL;
1005 }
1006
1007 static rtems_device_driver brm_control(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1008 {
1009
1010 unsigned int i=0;
1011 unsigned short ctrl, oper, cw1, cw2;
1012 rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *) arg;
1013 unsigned int *data;
1014 struct bc_msg *cmd_list;
1015 brm_priv *brm;
1016 struct drvmgr_dev *dev;
1017 rtems_device_driver ret;
1018 int len, msglen;
1019
1020 FUNCDBG("brm_control[%d]: [%i,%i]\n", minor, major, minor);
1021
1022 if ( drvmgr_get_dev(&b1553brm_drv_info.general, minor, &dev) ) {
1023 return RTEMS_UNSATISFIED;
1024 }
1025 brm = (brm_priv *)dev->priv;
1026
1027 if (!ioarg) {
1028 DBG("brm_control: invalid argument\n");
1029 return RTEMS_INVALID_NAME;
1030 }
1031
1032 data = ioarg->buffer;
1033 cmd_list = (struct bc_msg *) ioarg->buffer;
1034
1035 ioarg->ioctl_return = 0;
1036 switch (ioarg->command) {
1037
1038 case BRM_SET_MODE:
1039 if ( data[0] > 2 )
1040 return RTEMS_INVALID_NAME;
1041 stop_operation(brm);
1042 if (data[0] == 0) {
1043 ret = bc_init(brm);
1044 } else if (data[0] == 1) {
1045 ret = rt_init(brm);
1046 } else if (data[0] == 2) {
1047 ret = bm_init(brm);
1048 } else {
1049 ret = RTEMS_INVALID_NAME;
1050 }
1051 if ( ret != RTEMS_SUCCESSFUL)
1052 return ret;
1053
1054 if ( brm->mode & (BRM_MODE_RT | BRM_MODE_BM ) )
1055 start_operation(brm);
1056 break;
1057
1058 case BRM_SET_BUS:
1059 stop_operation(brm);
1060 ctrl = READ_REG(&brm->regs->ctrl);
1061 ctrl &= 0xE7FF;
1062 ctrl |= (data[0]&0x3)<<11;
1063 brm->regs->ctrl = ctrl;
1064 start_operation(brm);
1065 break;
1066
1067 case BRM_SET_MSGTO:
1068 stop_operation(brm);
1069 ctrl = READ_REG(&brm->regs->ctrl);
1070 ctrl &= 0xFDFF;
1071 ctrl |= (data[0]&1)<<9;
1072 brm->regs->ctrl = ctrl;
1073 start_operation(brm);
1074 break;
1075
1076 case BRM_SET_RT_ADDR:
1077 stop_operation(brm);
1078 oper = READ_REG(&brm->regs->oper);
1079 oper &= 0x03FF;
1080 oper |= (data[0]&0x1f)<<11;
1081 oper |= odd_parity(data[0]&0x1f)<<10;
1082 brm->regs->oper = oper;
1083 start_operation(brm);
1084 break;
1085
1086 case BRM_SET_STD:
1087 stop_operation(brm);
1088 ctrl = READ_REG(&brm->regs->ctrl);
1089 ctrl &= 0xFF7F;
1090 ctrl |= (data[0]&1)<<7;
1091 brm->regs->ctrl = ctrl;
1092 start_operation(brm);
1093 break;
1094
1095 case BRM_SET_BCE:
1096 stop_operation(brm);
1097 ctrl = READ_REG(&brm->regs->ctrl);
1098 ctrl &= 0xFFEF;
1099 ctrl |= (data[0]&1)<<4;
1100 brm->regs->ctrl = ctrl;
1101 start_operation(brm);
1102 break;
1103
1104 case BRM_TX_BLOCK:
1105 brm->tx_blocking = data[0];
1106 break;
1107
1108 case BRM_RX_BLOCK:
1109 brm->rx_blocking = data[0];
1110 break;
1111
1112 case BRM_DO_LIST:
1113 if ( brm->mode != BRM_MODE_BC ){
1114 return RTEMS_INVALID_NAME;
1115 }
1116
1117
1118 if ( ((READ_REG(&brm->regs->oper)>>8) & 3) != 0 ) {
1119 return RTEMS_INVALID_NAME;
1120 }
1121
1122
1123 if (is_executing(brm)) {
1124 return RTEMS_RESOURCE_IN_USE;
1125 }
1126
1127
1128 rtems_semaphore_obtain(brm->tx_sem, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT);
1129
1130 brm->bc_list_fail = 0;
1131 brm->cur_list = cmd_list;
1132 brm->regs->dpoint = 0;
1133
1134 i = 0;
1135 while ( (cmd_list[i].ctrl & BC_EOL) == 0) {
1136
1137 ctrl = (4<<12) | (((cmd_list[i].ctrl&BC_BUSA)==BC_BUSA)<<9) | (((cmd_list[i].ctrl&BC_RTRT)==BC_RTRT)<<8);
1138
1139 if (cmd_list[i].ctrl&BC_RTRT) {
1140 cw1 = (cmd_list[i].rtaddr[0]<<11) | (0<<10) | (cmd_list[i].subaddr[0]<<5) | (cmd_list[i].wc & 0x1f);
1141 cw2 = (cmd_list[i].rtaddr[1]<<11) | (1<<10) | (cmd_list[i].subaddr[1]<<5) | (cmd_list[i].wc & 0x1f);
1142 } else {
1143 cw1 = (cmd_list[i].rtaddr[0]<<11) | (((cmd_list[i].ctrl&BC_TR)==BC_TR)<<10) | (cmd_list[i].subaddr[0]<<5) | (cmd_list[i].wc&0x1f);
1144 cw2 = 0;
1145 }
1146
1147
1148 brm->bcmem->descs[i].ctrl = ctrl;
1149 brm->bcmem->descs[i].cw1 = cw1;
1150 brm->bcmem->descs[i].cw2 = cw2;
1151
1152
1153
1154 brm->bcmem->descs[i].dptr = 1024+i*32;
1155 brm->bcmem->descs[i].tsw[0] = 0;
1156 brm->bcmem->descs[i].tsw[1] = 0;
1157 brm->bcmem->descs[i].ba = 0;
1158 brm->bcmem->descs[i].timer = 0;
1159
1160 msglen = cmd_list[i].wc;
1161 if ( msglen == 0 )
1162 msglen = 32;
1163 memcpy((void *)&brm->bcmem->msg_data[i].data[0], &cmd_list[i].data[0], msglen*2);
1164
1165 i++;
1166 }
1167
1168 brm->bcmem->descs[i].ctrl = 0;
1169
1170 start_operation(brm);
1171 break;
1172
1173 case BRM_LIST_DONE:
1174
1175 if ( brm->mode != BRM_MODE_BC ){
1176 return RTEMS_INVALID_NAME;
1177 }
1178
1179
1180 if ( ((READ_REG(&brm->regs->oper)>>8) & 3) != 0 ) {
1181 return RTEMS_INVALID_NAME;
1182 }
1183
1184 if (is_executing(brm)) {
1185
1186 data[0] = 0;
1187 if (brm->tx_blocking) {
1188 rtems_semaphore_obtain(brm->tx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1189 data[0] = 1;
1190 if ( brm->bc_list_fail ){
1191 return RTEMS_INVALID_NAME;
1192 }
1193 } else {
1194 return RTEMS_RESOURCE_IN_USE;
1195 }
1196 } else {
1197 data[0] = 1;
1198 }
1199
1200
1201 i = 0;
1202 while ( (brm->cur_list[i].ctrl & BC_EOL) == 0) {
1203 if (READ_DMA(&brm->bcmem->descs[i].ctrl) & 1) {
1204 brm->cur_list[i].ctrl |= 0x8000;
1205 }
1206 if (brm->cur_list[i].ctrl & BC_TR) {
1207
1208 len = brm->cur_list[i].wc;
1209 if ( len == 0 )
1210 len = 32;
1211 while ( len-- > 0) {
1212 brm->cur_list[i].data[len] = READ_DMA(&brm->bcmem->msg_data[i].data[len]);
1213 }
1214 }
1215 brm->cur_list[i].tsw[0] = READ_DMA(&brm->bcmem->descs[i].tsw[0]);
1216 brm->cur_list[i].tsw[1] = READ_DMA(&brm->bcmem->descs[i].tsw[1]);
1217
1218 i++;
1219 }
1220 break;
1221
1222 case BRM_CLR_STATUS:
1223 brm->status = 0;
1224 break;
1225
1226 case BRM_GET_STATUS:
1227 if ( !ioarg->buffer )
1228 return RTEMS_INVALID_NAME;
1229
1230 *(unsigned int *)ioarg->buffer = brm->status;
1231 break;
1232
1233 case BRM_SET_EVENTID:
1234 brm->event_id = (rtems_id)ioarg->buffer;
1235 break;
1236
1237 default:
1238 return RTEMS_NOT_DEFINED;
1239 }
1240 return RTEMS_SUCCESSFUL;
1241 }
1242
1243 static void b1553brm_interrupt(void *arg)
1244 {
1245 brm_priv *brm = arg;
1246 unsigned short descriptor, current, pending, miw, wc, tmp, ctrl;
1247 unsigned short msgadr, iaw, iiw;
1248 int len;
1249 int signal_event=0, wake_rx_task=0, wake_tx_task=0;
1250 unsigned int event_status=0;
1251 int accessed;
1252 #define SET_ERROR_DESCRIPTOR(descriptor) (event_status = (event_status & 0x0000ffff) | descriptor<<16)
1253
1254 while( (iiw=READ_DMA(&brm->irq_log[brm->irq].iiw)) != 0xffff ){
1255 iaw=READ_DMA(&brm->irq_log[brm->irq].iaw);
1256
1257
1258 brm->irq_log[brm->irq].iiw = 0xffff;
1259
1260
1261 descriptor = iaw >> 2;
1262 pending = iiw;
1263 brm->irq = (brm->irq + 1) % 16;
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273 if (pending & BRM_SUBAD_IRQ) {
1274
1275
1276 current = READ_DMA(&brm->desc[descriptor].cur);
1277 ctrl = READ_DMA(&brm->desc[descriptor].ctrl);
1278 #ifdef DEBUG
1279 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = (0xff<<16);
1280 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = current;
1281 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = ctrl;
1282 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = 0;
1283 #endif
1284 accessed = ctrl & 0x10;
1285
1286
1287
1288 if ( accessed )
1289 do {
1290 msgadr = brm->last_read[descriptor];
1291
1292
1293 miw = READ_DMA(&brm->mem[msgadr]);
1294 wc = miw >> 11;
1295
1296
1297 if (descriptor < 32) {
1298 wc = wc ? wc : 32;
1299 }
1300
1301 else if (descriptor < 64) {
1302 wc = wc ? wc : 32;
1303 wake_tx_task=1;
1304 }
1305
1306 else if (descriptor < 96) {
1307 wc = (wc>>4);
1308 }
1309
1310 else if (descriptor < 128) {
1311 wc = (wc>>4);
1312 }
1313
1314 #ifdef DEBUG
1315 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = (descriptor << 16) | wc;
1316 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = current;
1317 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = msgadr;
1318 #endif
1319
1320
1321 if (brm->head - brm->tail != EVENT_QUEUE_SIZE) {
1322
1323
1324 brm->rt_event[INDEX(brm->head)].miw = READ_DMA(&brm->mem[msgadr]);
1325 brm->rt_event[INDEX(brm->head)].time = READ_DMA(&brm->mem[msgadr+1]);
1326 len = wc;
1327 while( len-- > 0){
1328 brm->rt_event[INDEX(brm->head)].data[len] = READ_DMA(&brm->mem[msgadr+2+len]);
1329 }
1330 brm->rt_event[INDEX(brm->head)].desc = descriptor;
1331 brm->head++;
1332 }
1333 else {
1334
1335 brm->rt_event[INDEX(brm->head)].desc |= 0x8000;
1336 }
1337
1338 msgadr += (2+wc);
1339
1340 if (msgadr >= READ_DMA(&brm->desc[descriptor].bot)) {
1341 msgadr = READ_DMA(&brm->desc[descriptor].top);
1342 }
1343 brm->last_read[descriptor] = msgadr;
1344
1345 #ifdef DEBUG
1346 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = msgadr;
1347 #endif
1348 wake_rx_task = 1;
1349 } while ( (msgadr=brm->last_read[descriptor]) != current );
1350 }
1351
1352 if (pending & BRM_EOL_IRQ) {
1353 wake_tx_task = 1;
1354 }
1355
1356 if (pending & BRM_BC_ILLCMD_IRQ) {
1357 brm->bc_list_fail = 1;
1358 wake_tx_task = 1;
1359 SET_ERROR_DESCRIPTOR(descriptor);
1360 FUNCDBG("BRM: ILLCMD IRQ\n\r");
1361 }
1362
1363
1364 if (pending & BRM_MBC_IRQ) {
1365
1366 stop_operation(brm);
1367 brm->regs->mbc = 1;
1368 start_operation(brm);
1369
1370
1371 if (brm->head - brm->tail != EVENT_QUEUE_SIZE) {
1372
1373
1374
1375 brm->bm_event[INDEX(brm->head)].miw = READ_DMA(&brm->mem[0]);
1376 brm->bm_event[INDEX(brm->head)].cw1 = READ_DMA(&brm->mem[1]);
1377 brm->bm_event[INDEX(brm->head)].cw2 = READ_DMA(&brm->mem[2]);
1378 brm->bm_event[INDEX(brm->head)].sw1 = READ_DMA(&brm->mem[4]);
1379 brm->bm_event[INDEX(brm->head)].sw2 = READ_DMA(&brm->mem[5]);
1380 brm->bm_event[INDEX(brm->head)].time = READ_DMA(&brm->mem[6]);
1381
1382 len = 32;
1383 while ( len-- ){
1384 brm->bm_event[INDEX(brm->head)].data[len] = READ_DMA(&brm->mem[0x100+len]);
1385 len--;
1386 brm->bm_event[INDEX(brm->head)].data[len] = READ_DMA(&brm->mem[0x100+len]);
1387 len--;
1388 brm->bm_event[INDEX(brm->head)].data[len] = READ_DMA(&brm->mem[0x100+len]);
1389 len--;
1390 brm->bm_event[INDEX(brm->head)].data[len] = READ_DMA(&brm->mem[0x100+len]);
1391 }
1392
1393
1394 #ifdef DEBUG
1395 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = READ_REG(&brm->regs->mbc) & 0xffff;
1396 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = READ_DMA(&brm->mem[0]);
1397 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = READ_DMA(&brm->mem[1]);
1398 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = READ_DMA(&brm->mem[4]);
1399 #endif
1400
1401 brm->head++;
1402
1403 }
1404 else {
1405
1406 brm->bm_event[INDEX(brm->head)].miw |= 0x8000;
1407 }
1408
1409
1410 wake_rx_task = 1;
1411 }
1412
1413
1414
1415
1416
1417 if ( pending & BRM_RT_ILLCMD_IRQ){
1418 FUNCDBG("BRM: BRM_RT_ILLCMD_IRQ\n\r");
1419 brm->status |= BRM_RT_ILLCMD_IRQ;
1420 event_status |= BRM_RT_ILLCMD_IRQ;
1421 SET_ERROR_DESCRIPTOR(descriptor);
1422 signal_event=1;
1423 }
1424
1425 if ( pending & BRM_ILLOP_IRQ){
1426 FUNCDBG("BRM: BRM_ILLOP_IRQ\n\r");
1427 brm->bc_list_fail = 1;
1428 wake_tx_task = 1;
1429 event_status |= BRM_ILLOP_IRQ;
1430 SET_ERROR_DESCRIPTOR(descriptor);
1431 signal_event=1;
1432 }
1433
1434 if ( pending & BRM_MERR_IRQ){
1435 FUNCDBG("BRM: BRM_MERR_IRQ\n\r");
1436 event_status |= BRM_MERR_IRQ;
1437 SET_ERROR_DESCRIPTOR(descriptor);
1438 signal_event=1;
1439 }
1440
1441 tmp = READ_DMA(&brm->desc[descriptor].ctrl);
1442 brm->desc[descriptor].ctrl = tmp & ~0x10;
1443 #ifdef DEBUG
1444 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = (0xfe<<16);
1445 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = 0;
1446 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = tmp & ~0x10;
1447 brm->log[brm->log_i++ % EVENT_QUEUE_SIZE] = tmp;
1448 #endif
1449 }
1450
1451
1452 pending = READ_REG(&brm->regs->ipend);
1453
1454 if ( pending & BRM_DMAF_IRQ){
1455 FUNCDBG("BRM: BRM_DMAF_IRQ\n\r");
1456 event_status |= BRM_DMAF_IRQ;
1457 signal_event=1;
1458 }
1459
1460 if ( pending & BRM_WRAPF_IRQ){
1461 FUNCDBG("BRM: BRM_WRAPF_IRQ\n\r");
1462 event_status |= BRM_WRAPF_IRQ;
1463 signal_event=1;
1464 }
1465
1466 if ( pending & BRM_TAPF_IRQ){
1467 FUNCDBG("BRM: BRM_TAPF_IRQ\n\r");
1468 event_status |= BRM_TAPF_IRQ;
1469 signal_event=1;
1470 }
1471
1472
1473 if ( event_status ){
1474 if ( event_status & 0xffff0000 )
1475 brm->status &= 0x0000ffff;
1476 brm->status |= event_status;
1477 }
1478
1479
1480 if ( wake_rx_task ) {
1481 rtems_semaphore_release(brm->rx_sem);
1482 }
1483
1484
1485 if ( wake_tx_task ) {
1486 rtems_semaphore_release(brm->tx_sem);
1487 }
1488
1489
1490 if ( signal_event && (brm->event_id!=0) ){
1491 rtems_event_send(brm->event_id, event_status);
1492 }
1493
1494 }
1495
1496 void b1553brm_print_dev(struct drvmgr_dev *dev, int options)
1497 {
1498 brm_priv *pDev = dev->priv;
1499 struct brm_reg *regs = pDev->regs;
1500
1501
1502 printf("--- B1553BRM[%d] %s ---\n", pDev->minor, pDev->devName);
1503 printf(" REGS: 0x%x\n", (unsigned int)pDev->regs);
1504 printf(" IRQ: %d\n", pDev->irqno);
1505 switch (pDev->mode) {
1506 case BRM_MODE_BC:
1507 printf(" MODE: BC\n");
1508 printf(" DESCS: 0x%x\n", (unsigned int)&pDev->bcmem->descs[0]);
1509 printf(" DATA: 0x%x\n", (unsigned int)&pDev->bcmem->msg_data[0].data[0]);
1510 printf(" IRQLOG: 0x%x\n", (unsigned int)&pDev->bcmem->irq_logs[0]);
1511 break;
1512 case BRM_MODE_BM:
1513 printf(" MODE: BM\n");
1514 break;
1515 case BRM_MODE_RT:
1516 printf(" MODE: RT\n");
1517 printf(" RXSUBS: 0x%x\n", (unsigned int)&pDev->rtmem->rxsubs[0]);
1518 printf(" TXSUBS: 0x%x\n", (unsigned int)&pDev->rtmem->txsubs[0]);
1519 printf(" RXMODES: 0x%x\n", (unsigned int)&pDev->rtmem->rxmodes[0]);
1520 printf(" TXOMODES: 0x%x\n", (unsigned int)&pDev->rtmem->txmodes[0]);
1521 printf(" RXSUBS MSGS: 0x%x\n", (unsigned int)&pDev->rtmem->rxsuba_msgs[0]);
1522 printf(" TXSUBS MSGS: 0x%x\n", (unsigned int)&pDev->rtmem->txsuba_msgs[0]);
1523 printf(" RXMODES MSGS: 0x%x\n", (unsigned int)&pDev->rtmem->rxmode_msgs[0]);
1524 printf(" TXMODES MSGS: 0x%x\n", (unsigned int)&pDev->rtmem->txmode_msgs[0]);
1525 printf(" IRQLOG: 0x%x\n", (unsigned int)&pDev->rtmem->irq_logs[0]);
1526 break;
1527 }
1528 printf(" CTRL: 0x%x\n", regs->ctrl);
1529 printf(" OPER: 0x%x\n", regs->oper);
1530 printf(" CUR_CMD: 0x%x\n", regs->cur_cmd);
1531 printf(" IMASK: 0x%x\n", regs->imask);
1532 printf(" IPEND: 0x%x\n", regs->ipend);
1533 printf(" IPOINT: 0x%x\n", regs->ipoint);
1534 printf(" BIT_REG: 0x%x\n", regs->bit_reg);
1535 printf(" TTAG: 0x%x\n", regs->ttag);
1536 printf(" DPOINT: 0x%x\n", regs->dpoint);
1537 printf(" SW: 0x%x\n", regs->sw);
1538 printf(" INITCOUNT: 0x%x\n", regs->initcount);
1539 printf(" MCPOINT: 0x%x\n", regs->mcpoint);
1540 printf(" MDPOINT: 0x%x\n", regs->mdpoint);
1541 printf(" MBC: 0x%x\n", regs->mbc);
1542 printf(" MFILTA: 0x%x\n", regs->mfilta);
1543 printf(" MFILTB: 0x%x\n", regs->mfiltb);
1544 printf(" ENHANCED: 0x%x\n", regs->enhanced);
1545 printf(" W_CTRL: 0x%x\n", regs->w_ctrl);
1546 printf(" W_IRQCTRL: 0x%x\n", regs->w_irqctrl);
1547 printf(" W_AHBADDR: 0x%x\n", regs->w_ahbaddr);
1548 }
1549
1550 void b1553brm_print(int options)
1551 {
1552 struct amba_drv_info *drv = &b1553brm_drv_info;
1553 struct drvmgr_dev *dev;
1554
1555 dev = drv->general.dev;
1556 while(dev) {
1557 b1553brm_print_dev(dev, options);
1558 dev = dev->next_in_drv;
1559 }
1560 }