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 #include <bsp.h>
0032 #include <rtems/libio.h>
0033 #include <stdlib.h>
0034 #include <stdio.h>
0035 #include <string.h>
0036 #include <assert.h>
0037 #include <ctype.h>
0038 #include <rtems/bspIo.h>
0039
0040 #include <drvmgr/drvmgr.h>
0041 #include <grlib/b1553rt.h>
0042 #include <grlib/ambapp.h>
0043 #include <grlib/ambapp_bus.h>
0044
0045 #include <grlib/grlib_impl.h>
0046
0047
0048
0049
0050
0051
0052
0053 #undef FUNCDEBUG
0054
0055
0056
0057 #define EVENT_QUEUE_SIZE 1024
0058
0059
0060 #define INDEX(x) ( x&(EVENT_QUEUE_SIZE-1) )
0061
0062 #if 0
0063 #define DBG(x...) printk(x)
0064 #else
0065 #define DBG(x...)
0066 #endif
0067
0068 #ifdef FUNCDEBUG
0069 #define FUNCDBG(x...) printk(x)
0070 #else
0071 #define FUNCDBG(x...)
0072 #endif
0073
0074 #define READ_DMA(address) grlib_read_uncached16((unsigned int)address)
0075
0076 static rtems_device_driver rt_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0077 static rtems_device_driver rt_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0078 static rtems_device_driver rt_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0079 static rtems_device_driver rt_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0080 static rtems_device_driver rt_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0081 static rtems_device_driver rt_control(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0082
0083 #define RT_DRIVER_TABLE_ENTRY { rt_initialize, rt_open, rt_close, rt_read, rt_write, rt_control }
0084
0085 static rtems_driver_address_table b1553rt_driver = RT_DRIVER_TABLE_ENTRY;
0086
0087 typedef struct {
0088
0089 struct drvmgr_dev *dev;
0090 char devName[52];
0091
0092 struct rt_reg *regs;
0093 unsigned int ctrl_copy;
0094
0095 unsigned int cfg_freq;
0096
0097 unsigned int memarea_base;
0098 unsigned int memarea_base_remote;
0099
0100 volatile unsigned short *mem;
0101
0102
0103 struct rt_msg *rt_event;
0104 unsigned int head, tail;
0105
0106 int rx_blocking;
0107
0108 rtems_id rx_sem, tx_sem, dev_sem;
0109 int minor;
0110 int irqno;
0111
0112 #ifdef DEBUG
0113 unsigned int log[EVENT_QUEUE_SIZE*4];
0114 unsigned int log_i;
0115 #endif
0116
0117 unsigned int status;
0118 rtems_id event_id;
0119
0120 } rt_priv;
0121
0122 static void b1553rt_interrupt(void *arg);
0123 static rtems_device_driver rt_init(rt_priv *rt);
0124
0125 #define OFS(ofs) (((unsigned int)&ofs & 0x1ffff)>>1)
0126
0127 static int b1553rt_driver_io_registered = 0;
0128 static rtems_device_major_number b1553rt_driver_io_major = 0;
0129
0130
0131
0132
0133 int b1553rt_register_io(rtems_device_major_number *m);
0134 int b1553rt_device_init(rt_priv *pDev);
0135
0136 int b1553rt_init2(struct drvmgr_dev *dev);
0137 int b1553rt_init3(struct drvmgr_dev *dev);
0138 int b1553rt_remove(struct drvmgr_dev *dev);
0139
0140 struct drvmgr_drv_ops b1553rt_ops =
0141 {
0142 .init = {NULL, b1553rt_init2, b1553rt_init3, NULL},
0143 .remove = b1553rt_remove,
0144 .info = NULL
0145 };
0146
0147 struct amba_dev_id b1553rt_ids[] =
0148 {
0149 {VENDOR_GAISLER, GAISLER_B1553RT},
0150 {0, 0}
0151 };
0152
0153 struct amba_drv_info b1553rt_drv_info =
0154 {
0155 {
0156 DRVMGR_OBJ_DRV,
0157 NULL,
0158 NULL,
0159 DRIVER_AMBAPP_GAISLER_B1553RT_ID,
0160 "B1553RT_DRV",
0161 DRVMGR_BUS_TYPE_AMBAPP,
0162 &b1553rt_ops,
0163 NULL,
0164 0,
0165 0,
0166
0167 },
0168 &b1553rt_ids[0]
0169 };
0170
0171 void b1553rt_register_drv (void)
0172 {
0173 DBG("Registering B1553RT driver\n");
0174 drvmgr_drv_register(&b1553rt_drv_info.general);
0175 }
0176
0177 int b1553rt_init2(struct drvmgr_dev *dev)
0178 {
0179 rt_priv *priv;
0180
0181 DBG("B1553RT[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0182 priv = dev->priv = grlib_calloc(1, sizeof(*priv));
0183 if ( !priv )
0184 return DRVMGR_NOMEM;
0185 priv->dev = dev;
0186
0187
0188
0189 return DRVMGR_OK;
0190 }
0191
0192 int b1553rt_init3(struct drvmgr_dev *dev)
0193 {
0194 rt_priv *priv;
0195 char prefix[32];
0196 rtems_status_code status;
0197
0198 priv = dev->priv;
0199
0200
0201
0202 if ( b1553rt_driver_io_registered == 0) {
0203
0204 if ( b1553rt_register_io(&b1553rt_driver_io_major) ) {
0205
0206 dev->priv = NULL;
0207 return DRVMGR_FAIL;
0208 }
0209
0210 b1553rt_driver_io_registered = 1;
0211 }
0212
0213
0214
0215
0216
0217 if ( b1553rt_device_init(priv) ) {
0218 return DRVMGR_FAIL;
0219 }
0220
0221
0222 prefix[0] = '\0';
0223 if ( drvmgr_get_dev_prefix(dev, prefix) ) {
0224
0225
0226
0227 sprintf(priv->devName, "/dev/b1553rt%d", dev->minor_drv);
0228 } else {
0229
0230
0231
0232 sprintf(priv->devName, "/dev/%sb1553rt%d", prefix, dev->minor_bus);
0233 }
0234
0235
0236 status = rtems_io_register_name(priv->devName, b1553rt_driver_io_major, dev->minor_drv);
0237 if (status != RTEMS_SUCCESSFUL) {
0238 return DRVMGR_FAIL;
0239 }
0240
0241 return DRVMGR_OK;
0242 }
0243
0244 int b1553rt_remove(struct drvmgr_dev *dev)
0245 {
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 return DRVMGR_FAIL;
0259 }
0260
0261
0262
0263 int b1553rt_register_io(rtems_device_major_number *m)
0264 {
0265 rtems_status_code r;
0266
0267 if ((r = rtems_io_register_driver(0, &b1553rt_driver, m)) == RTEMS_SUCCESSFUL) {
0268 DBG("B1553RT driver successfully registered, major: %d\n", *m);
0269 } else {
0270 switch(r) {
0271 case RTEMS_TOO_MANY:
0272 printk("B1553RT rtems_io_register_driver failed: RTEMS_TOO_MANY\n");
0273 return -1;
0274 case RTEMS_INVALID_NUMBER:
0275 printk("B1553RT rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n");
0276 return -1;
0277 case RTEMS_RESOURCE_IN_USE:
0278 printk("B1553RT rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n");
0279 return -1;
0280 default:
0281 printk("B1553RT rtems_io_register_driver failed\n");
0282 return -1;
0283 }
0284 }
0285 return 0;
0286 }
0287
0288 int b1553rt_device_init(rt_priv *pDev)
0289 {
0290 struct amba_dev_info *ambadev;
0291 struct ambapp_core *pnpinfo;
0292 union drvmgr_key_value *value;
0293 unsigned int mem;
0294 unsigned int sys_freq_hz;
0295
0296
0297 ambadev = (struct amba_dev_info *)pDev->dev->businfo;
0298 if ( ambadev == NULL ) {
0299 return -1;
0300 }
0301 pnpinfo = &ambadev->info;
0302 pDev->irqno = pnpinfo->irq;
0303 pDev->regs = (struct rt_reg *)pnpinfo->apb_slv->start;
0304 pDev->minor = pDev->dev->minor_drv;
0305
0306 #ifdef DEBUG
0307 pDev->log_i = 0;
0308 memset(pDev->log,0,sizeof(pDev->log));
0309 printf("LOG: 0x%x\n", &pDev->log[0]);
0310 printf("LOG_I: 0x%x\n", &pDev->log_i);
0311 #endif
0312
0313
0314 value = drvmgr_dev_key_get(pDev->dev, "dmaBaseAdr", DRVMGR_KT_POINTER);
0315 if (value)
0316 mem = (unsigned int)value->ptr;
0317
0318 if (value && (mem & 1)) {
0319
0320
0321
0322 pDev->memarea_base = mem & ~1;
0323 drvmgr_translate_check(pDev->dev, DMAMEM_TO_CPU,
0324 (void *)pDev->memarea_base_remote,
0325 (void **)&pDev->memarea_base,
0326 4 * 1024);
0327 } else {
0328 if (!value) {
0329
0330
0331
0332 mem = (unsigned int)grlib_malloc(4 * 1024 * 2);
0333 if ( !mem ){
0334 printk("RT: Failed to allocate HW memory\n\r");
0335 return -1;
0336 }
0337
0338 pDev->memarea_base = (mem + 0xfff) & ~0xfff;
0339 } else {
0340 pDev->memarea_base = mem;
0341 }
0342
0343
0344 drvmgr_translate_check(pDev->dev, CPUMEM_TO_DMA,
0345 (void *)pDev->memarea_base,
0346 (void **)&pDev->memarea_base_remote,
0347 4 * 1024);
0348 }
0349
0350
0351 memset((char *)pDev->memarea_base, 0, 4 * 1024);
0352
0353
0354 pDev->memarea_base = (unsigned int)mem;
0355 pDev->mem = (volatile unsigned short *)pDev->memarea_base;
0356
0357 pDev->rt_event = NULL;
0358
0359
0360
0361
0362
0363 pDev->cfg_freq = RT_FREQ_24MHZ;
0364
0365
0366 if ( drvmgr_freq_get(pDev->dev, DEV_APB_SLV, &sys_freq_hz) == 0 ) {
0367 if ( sys_freq_hz == 20000000 ) {
0368 pDev->cfg_freq = RT_FREQ_20MHZ;
0369 } else if ( sys_freq_hz == 16000000 ) {
0370 pDev->cfg_freq = RT_FREQ_16MHZ;
0371 } else if ( sys_freq_hz == 12000000 ) {
0372 pDev->cfg_freq = RT_FREQ_12MHZ;
0373 }
0374 }
0375
0376 value = drvmgr_dev_key_get(pDev->dev, "coreFreq", DRVMGR_KT_INT);
0377 if ( value ) {
0378 pDev->cfg_freq = value->i & RT_FREQ_MASK;
0379 }
0380
0381
0382 if ( rtems_semaphore_create(rtems_build_name('R', 'T', '0', '0' + pDev->minor),
0383 0,
0384 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0385 0,
0386 &pDev->rx_sem) != RTEMS_SUCCESSFUL ) {
0387 printk("RT: Failed to create rx semaphore\n");
0388 return RTEMS_INTERNAL_ERROR;
0389 }
0390
0391
0392 if ( rtems_semaphore_create(rtems_build_name('R', 'T', '0', '0' + pDev->minor),
0393 1,
0394 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0395 0,
0396 &pDev->dev_sem) != RTEMS_SUCCESSFUL ){
0397 printk("RT: Failed to create device semaphore\n");
0398 return RTEMS_INTERNAL_ERROR;
0399 }
0400
0401
0402 rt_init(pDev);
0403
0404 return 0;
0405 }
0406
0407 static int odd_parity(unsigned int data)
0408 {
0409 unsigned int i=0;
0410
0411 while(data)
0412 {
0413 i++;
0414 data &= (data - 1);
0415 }
0416
0417 return !(i&1);
0418 }
0419
0420 static void start_operation(rt_priv *rt)
0421 {
0422
0423 }
0424
0425 static void stop_operation(rt_priv *rt)
0426 {
0427
0428 }
0429
0430 static void set_extmdata_en(rt_priv *rt, int extmdata)
0431 {
0432 if ( extmdata )
0433 extmdata = 1;
0434 rt->ctrl_copy = (rt->ctrl_copy & ~(1<<16)) | (extmdata<<16);
0435 rt->regs->ctrl = rt->ctrl_copy;
0436 }
0437
0438 static void set_vector_word(rt_priv *rt, unsigned short vword)
0439 {
0440 rt->regs->vword = vword;
0441 }
0442
0443
0444 static void set_clkspd(rt_priv *rt, int spd)
0445 {
0446 rt->ctrl_copy = (rt->ctrl_copy & ~0xC0) | (spd<<6);
0447 rt->regs->ctrl = rt->ctrl_copy;
0448 asm volatile("nop"::);
0449 rt->regs->ctrl = rt->ctrl_copy | (1<<20);
0450 }
0451
0452 static void set_rtaddr(rt_priv *rt, int addr)
0453 {
0454 rt->ctrl_copy = (rt->ctrl_copy & ~0x3F00) | (addr << 8) | (odd_parity(addr)<<13);
0455 rt->regs->ctrl = rt->ctrl_copy;
0456 }
0457
0458 static void set_broadcast_en(rt_priv *rt, int data)
0459 {
0460 rt->ctrl_copy = (rt->ctrl_copy & ~0x40000) | (data<<18);
0461 rt->regs->ctrl = rt->ctrl_copy;
0462 }
0463
0464 static rtems_device_driver rt_init(rt_priv *rt)
0465 {
0466 rt->rx_blocking = 1;
0467
0468 if ( rt->rt_event )
0469 free(rt->rt_event);
0470 rt->rt_event = NULL;
0471
0472 rt->rt_event = grlib_malloc(EVENT_QUEUE_SIZE*sizeof(*rt->rt_event));
0473
0474 if (rt->rt_event == NULL) {
0475 DBG("RT driver failed to allocated memory.");
0476 return RTEMS_NO_MEMORY;
0477 }
0478
0479 rt->ctrl_copy = rt->regs->ctrl & 0x3F00;
0480 rt->ctrl_copy |= 0x3C0D0;
0481 rt->regs->ctrl = rt->ctrl_copy;
0482
0483
0484 set_clkspd(rt, rt->cfg_freq);
0485
0486 rt->regs->addr = rt->memarea_base_remote;
0487 rt->regs->ipm = 0x70000;
0488
0489 DBG("B1553RT DMA_AREA: 0x%x\n", (unsigned int)rt->mem);
0490
0491 return RTEMS_SUCCESSFUL;
0492 }
0493
0494
0495 static rtems_device_driver rt_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0496 {
0497 return RTEMS_SUCCESSFUL;
0498 }
0499
0500 static rtems_device_driver rt_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) {
0501 rt_priv *rt;
0502 struct drvmgr_dev *dev;
0503
0504 FUNCDBG("rt_open\n");
0505
0506 if ( drvmgr_get_dev(&b1553rt_drv_info.general, minor, &dev) ) {
0507 DBG("Wrong minor %d\n", minor);
0508 return RTEMS_UNSATISFIED;
0509 }
0510 rt = (rt_priv *)dev->priv;
0511
0512 if (rtems_semaphore_obtain(rt->dev_sem, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL) {
0513 DBG("rt_open: resource in use\n");
0514 return RTEMS_RESOURCE_IN_USE;
0515 }
0516
0517
0518 rt->event_id = 0;
0519
0520 start_operation(rt);
0521
0522
0523 if (drvmgr_interrupt_register(rt->dev, 0, "b1553rt", b1553rt_interrupt, rt)) {
0524 rtems_semaphore_release(rt->dev_sem);
0525 return -1;
0526 }
0527
0528
0529 return RTEMS_SUCCESSFUL;
0530 }
0531
0532 static rtems_device_driver rt_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0533 {
0534 rt_priv *rt;
0535 struct drvmgr_dev *dev;
0536
0537 FUNCDBG("rt_close");
0538
0539 if ( drvmgr_get_dev(&b1553rt_drv_info.general, minor, &dev) ) {
0540 return RTEMS_UNSATISFIED;
0541 }
0542 rt = (rt_priv *)dev->priv;
0543
0544 drvmgr_interrupt_unregister(rt->dev, 0, b1553rt_interrupt, rt);
0545
0546 stop_operation(rt);
0547 rtems_semaphore_release(rt->dev_sem);
0548
0549 return RTEMS_SUCCESSFUL;
0550 }
0551
0552 static int get_messages(rt_priv *rt, void *buf, unsigned int msg_count)
0553 {
0554
0555 struct rt_msg *dest = (struct rt_msg *) buf;
0556 int count = 0;
0557
0558 if (rt->head == rt->tail) {
0559 return 0;
0560 }
0561
0562 do {
0563
0564 DBG("rt read - head: %d, tail: %d\n", rt->head, rt->tail);
0565 dest[count++] = rt->rt_event[INDEX(rt->tail++)];
0566
0567 } while (rt->head != rt->tail && count < msg_count);
0568
0569 return count;
0570
0571 }
0572 static rtems_device_driver rt_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0573 {
0574 rtems_libio_rw_args_t *rw_args;
0575 int count = 0;
0576 rt_priv *rt;
0577 struct drvmgr_dev *dev;
0578
0579 if ( drvmgr_get_dev(&b1553rt_drv_info.general, minor, &dev) ) {
0580 return RTEMS_UNSATISFIED;
0581 }
0582 rt = (rt_priv *)dev->priv;
0583
0584 rw_args = (rtems_libio_rw_args_t *) arg;
0585
0586 FUNCDBG("rt_read [%i,%i]: buf: 0x%x, len: %i\n",major, minor, (unsigned int)rw_args->buffer, rw_args->count);
0587
0588 while ( (count = get_messages(rt,rw_args->buffer, rw_args->count)) == 0 ) {
0589
0590 if (rt->rx_blocking) {
0591 rtems_semaphore_obtain(rt->rx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0592 } else {
0593
0594 return RTEMS_RESOURCE_IN_USE;
0595 }
0596 }
0597
0598 rw_args->bytes_moved = count;
0599 return RTEMS_SUCCESSFUL;
0600 }
0601
0602 static rtems_device_driver rt_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0603 {
0604 rtems_libio_rw_args_t *rw_args;
0605 struct rt_msg *source;
0606 rt_priv *rt;
0607 struct drvmgr_dev *dev;
0608 unsigned int descriptor, suba, wc;
0609
0610 if ( drvmgr_get_dev(&b1553rt_drv_info.general, minor, &dev) ) {
0611 return RTEMS_UNSATISFIED;
0612 }
0613 rt = (rt_priv *)dev->priv;
0614
0615 rw_args = (rtems_libio_rw_args_t *) arg;
0616
0617 if ( rw_args->count != 1 ) {
0618 return RTEMS_INVALID_NAME;
0619 }
0620
0621 source = (struct rt_msg *) rw_args->buffer;
0622
0623 descriptor = source[0].desc & 0x7F;
0624 suba = descriptor-32;
0625 wc = source[0].miw >> 11;
0626 wc = wc ? wc : 32;
0627
0628 FUNCDBG("rt_write [%i,%i]: buf: 0x%x\n",major, minor, (unsigned int)rw_args->buffer);
0629
0630 memcpy((void *)&rt->mem[0x400 + suba*32], &source[0].data[0], wc*2);
0631
0632 rw_args->bytes_moved = 1;
0633
0634 return RTEMS_SUCCESSFUL;
0635
0636 }
0637
0638 static rtems_device_driver rt_control(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0639 {
0640 rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *) arg;
0641 unsigned int *data;
0642
0643 rt_priv *rt;
0644 struct drvmgr_dev *dev;
0645
0646 FUNCDBG("rt_control[%d]: [%i,%i]\n", minor, major, minor);
0647
0648 if ( drvmgr_get_dev(&b1553rt_drv_info.general, minor, &dev) ) {
0649 return RTEMS_UNSATISFIED;
0650 }
0651 rt = (rt_priv *)dev->priv;
0652
0653 if (!ioarg) {
0654 DBG("rt_control: invalid argument\n");
0655 return RTEMS_INVALID_NAME;
0656 }
0657
0658 data = ioarg->buffer;
0659
0660 ioarg->ioctl_return = 0;
0661 switch (ioarg->command) {
0662
0663 case RT_SET_ADDR:
0664 set_rtaddr(rt, data[0]);
0665 break;
0666
0667 case RT_SET_BCE:
0668 set_broadcast_en(rt, data[0]);
0669 break;
0670
0671 case RT_SET_VECTORW:
0672 set_vector_word(rt, data[0]);
0673 break;
0674
0675 case RT_SET_EXTMDATA:
0676 set_extmdata_en(rt, data[0]);
0677 break;
0678
0679 case RT_RX_BLOCK:
0680 rt->rx_blocking = data[0];
0681 break;
0682
0683 case RT_CLR_STATUS:
0684 rt->status = 0;
0685 break;
0686
0687 case RT_GET_STATUS:
0688 if ( !ioarg->buffer )
0689 return RTEMS_INVALID_NAME;
0690
0691 *(unsigned int *)ioarg->buffer = rt->status;
0692 break;
0693
0694 case RT_SET_EVENTID:
0695 rt->event_id = (rtems_id)ioarg->buffer;
0696 break;
0697
0698 default:
0699 return RTEMS_NOT_IMPLEMENTED;
0700 }
0701
0702 return RTEMS_SUCCESSFUL;
0703 }
0704
0705 static void b1553rt_interrupt(void *arg)
0706 {
0707 rt_priv *rt = arg;
0708 unsigned short descriptor;
0709 int signal_event=0, wake_rx_task=0;
0710 unsigned int event_status=0;
0711 unsigned int wc, irqv, cmd, tsw, suba, tx, miw, i;
0712 unsigned int ipend;
0713
0714 #define SET_ERROR_DESCRIPTOR(descriptor) (event_status = (event_status & 0x0000ffff) | descriptor<<16)
0715 ipend = rt->regs->ipm;
0716
0717 if (ipend == 0) {
0718
0719
0720 rt->regs->ctrl = rt->ctrl_copy;
0721 rt->regs->addr = rt->memarea_base_remote;
0722 rt->regs->ipm = 0x70000;
0723
0724 if (rt->head - rt->tail != EVENT_QUEUE_SIZE) {
0725 miw = (8<<11);
0726 descriptor = 64 + 32 + 8;
0727 rt->rt_event[INDEX(rt->head)].miw = miw;
0728 rt->rt_event[INDEX(rt->head)].time = 0;
0729 rt->rt_event[INDEX(rt->head)].desc = descriptor;
0730 rt->head++;
0731 }
0732 }
0733
0734 if ( ipend & 0x1 ) {
0735
0736 if (rt->head - rt->tail != EVENT_QUEUE_SIZE) {
0737
0738 irqv = rt->regs->irq;
0739 cmd = irqv >> 7;
0740 wc = cmd & 0x1F;
0741 suba = irqv & 0x1F;
0742 tx = (irqv >> 5) & 1;
0743
0744
0745 tsw = READ_DMA(&rt->mem[tx*0x3E0+suba]);
0746
0747
0748 miw = (wc<<11) | (tsw&RT_TSW_BUS)>>4 | !(tsw&RT_TSW_OK)<<7 | (tsw&RT_TSW_ILL)>>5 |
0749 (tsw&RT_TSW_PAR)>>5 | (tsw&RT_TSW_MAN)>>7;
0750
0751 descriptor = (tx << 5) | suba;
0752
0753
0754 if (suba == 0 || suba == 31) {
0755 descriptor = 64 + (tx*32) + wc;
0756 }
0757
0758
0759 if (descriptor < 64) {
0760 wc = wc ? wc : 32;
0761 }
0762
0763 else if (descriptor < 96) {
0764 wc = (wc>>4);
0765 }
0766
0767 else if (descriptor < 128) {
0768 wc = (wc>>4);
0769 }
0770
0771
0772 rt->rt_event[INDEX(rt->head)].miw = miw;
0773 rt->rt_event[INDEX(rt->head)].time = 0;
0774
0775 for (i = 0; i < wc; i++) {
0776 rt->rt_event[INDEX(rt->head)].data[i] = READ_DMA(&rt->mem[tx*0x400 + suba*32 + i]);
0777 }
0778 rt->rt_event[INDEX(rt->head)].desc = descriptor;
0779 rt->head++;
0780
0781
0782
0783 if ( tsw & RT_TSW_ILL){
0784 FUNCDBG("RT: RT_ILLCMD\n\r");
0785 rt->status |= RT_ILLCMD_IRQ;
0786 event_status |= RT_ILLCMD_IRQ;
0787 SET_ERROR_DESCRIPTOR(descriptor);
0788 signal_event=1;
0789 }
0790
0791 if ( !(tsw & RT_TSW_OK) ) {
0792 FUNCDBG("RT: RT_MERR_IRQ\n\r");
0793 rt->status |= RT_MERR_IRQ;
0794 event_status |= RT_MERR_IRQ;
0795 SET_ERROR_DESCRIPTOR(descriptor);
0796 signal_event=1;
0797 }
0798
0799 }
0800 else {
0801
0802 rt->rt_event[INDEX(rt->head)].desc |= 0x8000;
0803 }
0804 }
0805
0806 if ( ipend & 0x2 ) {
0807
0808 FUNCDBG("B1553RT: Memory failure\n");
0809 event_status |= RT_DMAF_IRQ;
0810 signal_event=1;
0811 }
0812
0813 if ( ipend & 0x4 ) {
0814
0815 FUNCDBG("B1553RT: AHB ERROR\n");
0816 event_status |= RT_DMAF_IRQ;
0817 signal_event=1;
0818 }
0819
0820 #ifdef DEBUG
0821 rt->log[rt->log_i++ % EVENT_QUEUE_SIZE] = descriptor;
0822 rt->log[rt->log_i++ % EVENT_QUEUE_SIZE] = cmd;
0823 rt->log[rt->log_i++ % EVENT_QUEUE_SIZE] = miw;
0824 rt->log[rt->log_i++ % EVENT_QUEUE_SIZE] = tsw;
0825 #endif
0826
0827 wake_rx_task = 1;
0828
0829
0830 if ( wake_rx_task ) {
0831 rtems_semaphore_release(rt->rx_sem);
0832 }
0833
0834
0835 if ( event_status ) {
0836 if ( event_status & 0xffff0000 )
0837 rt->status &= 0x0000ffff;
0838 rt->status |= event_status;
0839 }
0840
0841
0842 if ( signal_event && (rt->event_id != 0) ) {
0843 rtems_event_send(rt->event_id, event_status);
0844 }
0845
0846 }
0847
0848 void b1553rt_print_dev(struct drvmgr_dev *dev, int options)
0849 {
0850 rt_priv *pDev = dev->priv;
0851
0852
0853 printf("--- B1553RT[%d] %s ---\n", pDev->minor, pDev->devName);
0854 printf(" REGS: 0x%x\n", (unsigned int)pDev->regs);
0855 printf(" IRQ: %d\n", pDev->irqno);
0856
0857 }
0858
0859 void b1553rt_print(int options)
0860 {
0861 struct amba_drv_info *drv = &b1553rt_drv_info;
0862 struct drvmgr_dev *dev;
0863
0864 dev = drv->general.dev;
0865 while(dev) {
0866 b1553rt_print_dev(dev, options);
0867 dev = dev->next_in_drv;
0868 }
0869 }