(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/omap.c

    1: /*
    2:  * TI OMAP processors emulation.
    3:  *
    4:  * Copyright (C) 2006-2007 Andrzej Zaborowski  <balrog@zabor.org>
    5:  *
    6:  * This program is free software; you can redistribute it and/or
    7:  * modify it under the terms of the GNU General Public License as
    8:  * published by the Free Software Foundation; either version 2 of
    9:  * the License, or (at your option) any later version.
   10:  *
   11:  * This program is distributed in the hope that it will be useful,
   12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14:  * GNU General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU General Public License
   17:  * along with this program; if not, write to the Free Software
   18:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
   19:  * MA 02111-1307 USA
   20:  */
   21: #include "hw.h"
   22: #include "arm-misc.h"
   23: #include "omap.h"
   24: #include "sysemu.h"
   25: #include "qemu-timer.h"
   26: /* We use pc-style serial ports.  */
   27: #include "pc.h"
   28: 
   29: /* Should signal the TCMI */
   30: uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
   31: {
   32:     uint8_t ret;
   33: 
   34:     OMAP_8B_REG(addr);
   35:     cpu_physical_memory_read(addr, (void *) &ret, 1);
   36:     return ret;
   37: }
   38: 
   39: void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
   40:                 uint32_t value)
   41: {
   42:     uint8_t val8 = value;
   43: 
   44:     OMAP_8B_REG(addr);
   45:     cpu_physical_memory_write(addr, (void *) &val8, 1);
   46: }
   47: 
   48: uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
   49: {
   50:     uint16_t ret;
   51: 
   52:     OMAP_16B_REG(addr);
   53:     cpu_physical_memory_read(addr, (void *) &ret, 2);
   54:     return ret;
   55: }
   56: 
   57: void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
   58:                 uint32_t value)
   59: {
   60:     uint16_t val16 = value;
   61: 
   62:     OMAP_16B_REG(addr);
   63:     cpu_physical_memory_write(addr, (void *) &val16, 2);
   64: }
   65: 
   66: uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
   67: {
   68:     uint32_t ret;
   69: 
   70:     OMAP_32B_REG(addr);
   71:     cpu_physical_memory_read(addr, (void *) &ret, 4);
   72:     return ret;
   73: }
   74: 
   75: void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
   76:                 uint32_t value)
   77: {
   78:     OMAP_32B_REG(addr);
   79:     cpu_physical_memory_write(addr, (void *) &value, 4);
   80: }
   81: 
   82: /* Interrupt Handlers */
   83: struct omap_intr_handler_bank_s {
   84:     uint32_t irqs;
   85:     uint32_t inputs;
   86:     uint32_t mask;
   87:     uint32_t fiq;
   88:     uint32_t sens_edge;
   89:     unsigned char priority[32];
   90: };
   91: 
   92: struct omap_intr_handler_s {
   93:     qemu_irq *pins;
   94:     qemu_irq parent_intr[2];
   95:     target_phys_addr_t base;
   96:     unsigned char nbanks;
   97: 
   98:     /* state */
   99:     uint32_t new_agr[2];
  100:     int sir_intr[2];
  101:     struct omap_intr_handler_bank_s banks[];
  102: };
  103: 
  104: static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
  105: {
  106:     int i, j, sir_intr, p_intr, p, f;
  107:     uint32_t level;
  108:     sir_intr = 0;
  109:     p_intr = 255;
  110: 
  111:     /* Find the interrupt line with the highest dynamic priority.
  112:      * Note: 0 denotes the hightest priority.
  113:      * If all interrupts have the same priority, the default order is IRQ_N,
  114:      * IRQ_N-1,...,IRQ_0. */
  115:     for (j = 0; j < s->nbanks; ++j) {
  116:         level = s->banks[j].irqs & ~s->banks[j].mask &
  117:                 (is_fiq ? s->banks[j].fiq : ~s->banks[j].fiq);
  118:         for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,
  119:                         level >>= f) {
  120:             p = s->banks[j].priority[i];
  121:             if (p <= p_intr) {
  122:                 p_intr = p;
  123:                 sir_intr = 32 * j + i;
  124:             }
  125:             f = ffs(level >> 1);
  126:         }
  127:     }
  128:     s->sir_intr[is_fiq] = sir_intr;
  129: }
  130: 
  131: static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
  132: {
  133:     int i;
  134:     uint32_t has_intr = 0;
  135: 
  136:     for (i = 0; i < s->nbanks; ++i)
  137:         has_intr |= s->banks[i].irqs & ~s->banks[i].mask &
  138:                 (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq);
  139: 
  140:     if (s->new_agr[is_fiq] && has_intr) {
  141:         s->new_agr[is_fiq] = 0;
  142:         omap_inth_sir_update(s, is_fiq);
  143:         qemu_set_irq(s->parent_intr[is_fiq], 1);
  144:     }
  145: }
  146: 
  147: #define INT_FALLING_EDGE        0
  148: #define INT_LOW_LEVEL           1
  149: 
  150: static void omap_set_intr(void *opaque, int irq, int req)
  151: {
  152:     struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
  153:     uint32_t rise;
  154: 
  155:     struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5];
  156:     int n = irq & 31;
  157: 
  158:     if (req) {
  159:         rise = ~bank->irqs & (1 << n);
  160:         if (~bank->sens_edge & (1 << n))
  161:             rise &= ~bank->inputs & (1 << n);
  162: 
  163:         bank->inputs |= (1 << n);
  164:         if (rise) {
  165:             bank->irqs |= rise;
  166:             omap_inth_update(ih, 0);
  167:             omap_inth_update(ih, 1);
  168:         }
  169:     } else {
  170:         rise = bank->sens_edge & bank->irqs & (1 << n);
  171:         bank->irqs &= ~rise;
  172:         bank->inputs &= ~(1 << n);
  173:     }
  174: }
  175: 
  176: static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
  177: {
  178:     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
  179:     int i, offset = addr - s->base;
  180:     int bank_no = offset >> 8;
  181:     int line_no;
  182:     struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
  183:     offset &= 0xff;
  184: 
  185:     switch (offset) {
  186:     case 0x00:  /* ITR */
  187:         return bank->irqs;
  188: 
  189:     case 0x04:  /* MIR */
  190:         return bank->mask;
  191: 
  192:     case 0x10:  /* SIR_IRQ_CODE */
  193:     case 0x14:  /* SIR_FIQ_CODE */
  194:         if (bank_no != 0)
  195:             break;
  196:         line_no = s->sir_intr[(offset - 0x10) >> 2];
  197:         bank = &s->banks[line_no >> 5];
  198:         i = line_no & 31;
  199:         if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
  200:             bank->irqs &= ~(1 << i);
  201:         return line_no;
  202: 
  203:     case 0x18:  /* CONTROL_REG */
  204:         if (bank_no != 0)
  205:             break;
  206:         return 0;
  207: 
  208:     case 0x1c:  /* ILR0 */
  209:     case 0x20:  /* ILR1 */
  210:     case 0x24:  /* ILR2 */
  211:     case 0x28:  /* ILR3 */
  212:     case 0x2c:  /* ILR4 */
  213:     case 0x30:  /* ILR5 */
  214:     case 0x34:  /* ILR6 */
  215:     case 0x38:  /* ILR7 */
  216:     case 0x3c:  /* ILR8 */
  217:     case 0x40:  /* ILR9 */
  218:     case 0x44:  /* ILR10 */
  219:     case 0x48:  /* ILR11 */
  220:     case 0x4c:  /* ILR12 */
  221:     case 0x50:  /* ILR13 */
  222:     case 0x54:  /* ILR14 */
  223:     case 0x58:  /* ILR15 */
  224:     case 0x5c:  /* ILR16 */
  225:     case 0x60:  /* ILR17 */
  226:     case 0x64:  /* ILR18 */
  227:     case 0x68:  /* ILR19 */
  228:     case 0x6c:  /* ILR20 */
  229:     case 0x70:  /* ILR21 */
  230:     case 0x74:  /* ILR22 */
  231:     case 0x78:  /* ILR23 */
  232:     case 0x7c:  /* ILR24 */
  233:     case 0x80:  /* ILR25 */
  234:     case 0x84:  /* ILR26 */
  235:     case 0x88:  /* ILR27 */
  236:     case 0x8c:  /* ILR28 */
  237:     case 0x90:  /* ILR29 */
  238:     case 0x94:  /* ILR30 */
  239:     case 0x98:  /* ILR31 */
  240:         i = (offset - 0x1c) >> 2;
  241:         return (bank->priority[i] << 2) |
  242:                 (((bank->sens_edge >> i) & 1) << 1) |
  243:                 ((bank->fiq >> i) & 1);
  244: 
  245:     case 0x9c:  /* ISR */
  246:         return 0x00000000;
  247: 
  248:     }
  249:     OMAP_BAD_REG(addr);
  250:     return 0;
  251: }
  252: 
  253: static void omap_inth_write(void *opaque, target_phys_addr_t addr,
  254:                 uint32_t value)
  255: {
  256:     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
  257:     int i, offset = addr - s->base;
  258:     int bank_no = offset >> 8;
  259:     struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
  260:     offset &= 0xff;
  261: 
  262:     switch (offset) {
  263:     case 0x00:  /* ITR */
  264:         /* Important: ignore the clearing if the IRQ is level-triggered and
  265:            the input bit is 1 */
  266:         bank->irqs &= value | (bank->inputs & bank->sens_edge);
  267:         return;
  268: 
  269:     case 0x04:  /* MIR */
  270:         bank->mask = value;
  271:         omap_inth_update(s, 0);
  272:         omap_inth_update(s, 1);
  273:         return;
  274: 
  275:     case 0x10:  /* SIR_IRQ_CODE */
  276:     case 0x14:  /* SIR_FIQ_CODE */
  277:         OMAP_RO_REG(addr);
  278:         break;
  279: 
  280:     case 0x18:  /* CONTROL_REG */
  281:         if (bank_no != 0)
  282:             break;
  283:         if (value & 2) {
  284:             qemu_set_irq(s->parent_intr[1], 0);
  285:             s->new_agr[1] = ~0;
  286:             omap_inth_update(s, 1);
  287:         }
  288:         if (value & 1) {
  289:             qemu_set_irq(s->parent_intr[0], 0);
  290:             s->new_agr[0] = ~0;
  291:             omap_inth_update(s, 0);
  292:         }
  293:         return;
  294: 
  295:     case 0x1c:  /* ILR0 */
  296:     case 0x20:  /* ILR1 */
  297:     case 0x24:  /* ILR2 */
  298:     case 0x28:  /* ILR3 */
  299:     case 0x2c:  /* ILR4 */
  300:     case 0x30:  /* ILR5 */
  301:     case 0x34:  /* ILR6 */
  302:     case 0x38:  /* ILR7 */
  303:     case 0x3c:  /* ILR8 */
  304:     case 0x40:  /* ILR9 */
  305:     case 0x44:  /* ILR10 */
  306:     case 0x48:  /* ILR11 */
  307:     case 0x4c:  /* ILR12 */
  308:     case 0x50:  /* ILR13 */
  309:     case 0x54:  /* ILR14 */
  310:     case 0x58:  /* ILR15 */
  311:     case 0x5c:  /* ILR16 */
  312:     case 0x60:  /* ILR17 */
  313:     case 0x64:  /* ILR18 */
  314:     case 0x68:  /* ILR19 */
  315:     case 0x6c:  /* ILR20 */
  316:     case 0x70:  /* ILR21 */
  317:     case 0x74:  /* ILR22 */
  318:     case 0x78:  /* ILR23 */
  319:     case 0x7c:  /* ILR24 */
  320:     case 0x80:  /* ILR25 */
  321:     case 0x84:  /* ILR26 */
  322:     case 0x88:  /* ILR27 */
  323:     case 0x8c:  /* ILR28 */
  324:     case 0x90:  /* ILR29 */
  325:     case 0x94:  /* ILR30 */
  326:     case 0x98:  /* ILR31 */
  327:         i = (offset - 0x1c) >> 2;
  328:         bank->priority[i] = (value >> 2) & 0x1f;
  329:         bank->sens_edge &= ~(1 << i);
  330:         bank->sens_edge |= ((value >> 1) & 1) << i;
  331:         bank->fiq &= ~(1 << i);
  332:         bank->fiq |= (value & 1) << i;
  333:         return;
  334: 
  335:     case 0x9c:  /* ISR */
  336:         for (i = 0; i < 32; i ++)
  337:             if (value & (1 << i)) {
  338:                 omap_set_intr(s, 32 * bank_no + i, 1);
  339:                 return;
  340:             }
  341:         return;
  342:     }
  343:     OMAP_BAD_REG(addr);
  344: }
  345: 
  346: static CPUReadMemoryFunc *omap_inth_readfn[] = {
  347:     omap_badwidth_read32,
  348:     omap_badwidth_read32,
  349:     omap_inth_read,
  350: };
  351: 
  352: static CPUWriteMemoryFunc *omap_inth_writefn[] = {
  353:     omap_inth_write,
  354:     omap_inth_write,
  355:     omap_inth_write,
  356: };
  357: 
  358: void omap_inth_reset(struct omap_intr_handler_s *s)
  359: {
  360:     int i;
  361: 
  362:     for (i = 0; i < s->nbanks; ++i){
  363:         s->banks[i].irqs = 0x00000000;
  364:         s->banks[i].mask = 0xffffffff;
  365:         s->banks[i].sens_edge = 0x00000000;
  366:         s->banks[i].fiq = 0x00000000;
  367:         s->banks[i].inputs = 0x00000000;
  368:         memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority));
  369:     }
  370: 
  371:     s->new_agr[0] = ~0;
  372:     s->new_agr[1] = ~0;
  373:     s->sir_intr[0] = 0;
  374:     s->sir_intr[1] = 0;
  375: 
  376:     qemu_set_irq(s->parent_intr[0], 0);
  377:     qemu_set_irq(s->parent_intr[1], 0);
  378: }
  379: 
  380: struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
  381:                 unsigned long size, unsigned char nbanks,
  382:                 qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk)
  383: {
  384:     int iomemtype;
  385:     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
  386:             qemu_mallocz(sizeof(struct omap_intr_handler_s) +
  387:                             sizeof(struct omap_intr_handler_bank_s) * nbanks);
  388: 
  389:     s->parent_intr[0] = parent_irq;
  390:     s->parent_intr[1] = parent_fiq;
  391:     s->base = base;
  392:     s->nbanks = nbanks;
  393:     s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
  394: 
  395:     omap_inth_reset(s);
  396: 
  397:     iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
  398:                     omap_inth_writefn, s);
  399:     cpu_register_physical_memory(s->base, size, iomemtype);
  400: 
  401:     return s;
  402: }
  403: 
  404: /* OMAP1 DMA module */
  405: struct omap_dma_channel_s {
  406:     /* transfer data */
  407:     int burst[2];
  408:     int pack[2];
  409:     enum omap_dma_port port[2];
  410:     target_phys_addr_t addr[2];
  411:     omap_dma_addressing_t mode[2];
  412:     uint16_t elements;
  413:     uint16_t frames;
  414:     int16_t frame_index[2];
  415:     int16_t element_index[2];
  416:     int data_type;
  417: 
  418:     /* transfer type */
  419:     int transparent_copy;
  420:     int constant_fill;
  421:     uint32_t color;
  422: 
  423:     /* auto init and linked channel data */
  424:     int end_prog;
  425:     int repeat;
  426:     int auto_init;
  427:     int link_enabled;
  428:     int link_next_ch;
  429: 
  430:     /* interruption data */
  431:     int interrupts;
  432:     int status;
  433: 
  434:     /* state data */
  435:     int active;
  436:     int enable;
  437:     int sync;
  438:     int pending_request;
  439:     int waiting_end_prog;
  440:     uint16_t cpc;
  441: 
  442:     /* sync type */
  443:     int fs;
  444:     int bs;
  445: 
  446:     /* compatibility */
  447:     int omap_3_1_compatible_disable;
  448: 
  449:     qemu_irq irq;
  450:     struct omap_dma_channel_s *sibling;
  451: 
  452:     struct omap_dma_reg_set_s {
  453:         target_phys_addr_t src, dest;
  454:         int frame;
  455:         int element;
  456:         int frame_delta[2];
  457:         int elem_delta[2];
  458:         int frames;
  459:         int elements;
  460:     } active_set;
  461: 
  462:     /* unused parameters */
  463:     int priority;
  464:     int interleave_disabled;
  465:     int type;
  466: };
  467: 
  468: struct omap_dma_s {
  469:     QEMUTimer *tm;
  470:     struct omap_mpu_state_s *mpu;
  471:     target_phys_addr_t base;
  472:     omap_clk clk;
  473:     int64_t delay;
  474:     uint32_t drq;
  475:     enum omap_dma_model model;
  476:     int omap_3_1_mapping_disabled;
  477: 
  478:     uint16_t gcr;
  479:     int run_count;
  480: 
  481:     int chans;
  482:     struct omap_dma_channel_s ch[16];
  483:     struct omap_dma_lcd_channel_s lcd_ch;
  484: };
  485: 
  486: /* Interrupts */
  487: #define TIMEOUT_INTR    (1 << 0)
  488: #define EVENT_DROP_INTR (1 << 1)
  489: #define HALF_FRAME_INTR (1 << 2)
  490: #define END_FRAME_INTR  (1 << 3)
  491: #define LAST_FRAME_INTR (1 << 4)
  492: #define END_BLOCK_INTR  (1 << 5)
  493: #define SYNC            (1 << 6)
  494: 
  495: static void omap_dma_interrupts_update(struct omap_dma_s *s)
  496: {
  497:     struct omap_dma_channel_s *ch = s->ch;
  498:     int i;
  499: 
  500:     if (s->omap_3_1_mapping_disabled) {
  501:         for (i = 0; i < s->chans; i ++, ch ++)
  502:             if (ch->status)
  503:                 qemu_irq_raise(ch->irq);
  504:     } else {
  505:         /* First three interrupts are shared between two channels each. */
  506:         for (i = 0; i < 6; i ++, ch ++) {
  507:             if (ch->status || (ch->sibling && ch->sibling->status))
  508:                 qemu_irq_raise(ch->irq);
  509:         }
  510:     }
  511: }
  512: 
  513: static void omap_dma_channel_load(struct omap_dma_s *s,
  514:                 struct omap_dma_channel_s *ch)
  515: {
  516:     struct omap_dma_reg_set_s *a = &ch->active_set;
  517:     int i;
  518:     int omap_3_1 = !ch->omap_3_1_compatible_disable;
  519: 
  520:     /*
  521:      * TODO: verify address ranges and alignment
  522:      * TODO: port endianness
  523:      */
  524: 
  525:     a->src = ch->addr[0];
  526:     a->dest = ch->addr[1];
  527:     a->frames = ch->frames;
  528:     a->elements = ch->elements;
  529:     a->frame = 0;
  530:     a->element = 0;
  531: 
  532:     if (unlikely(!ch->elements || !ch->frames)) {
  533:         printf("%s: bad DMA request\n", __FUNCTION__);
  534:         return;
  535:     }
  536: 
  537:     for (i = 0; i < 2; i ++)
  538:         switch (ch->mode[i]) {
  539:         case constant:
  540:             a->elem_delta[i] = 0;
  541:             a->frame_delta[i] = 0;
  542:             break;
  543:         case post_incremented:
  544:             a->elem_delta[i] = ch->data_type;
  545:             a->frame_delta[i] = 0;
  546:             break;
  547:         case single_index:
  548:             a->elem_delta[i] = ch->data_type +
  549:                     ch->element_index[omap_3_1 ? 0 : i] - 1;
  550:             a->frame_delta[i] = 0;
  551:             break;
  552:         case double_index:
  553:             a->elem_delta[i] = ch->data_type +
  554:                     ch->element_index[omap_3_1 ? 0 : i] - 1;
  555:             a->frame_delta[i] = ch->frame_index[omap_3_1 ? 0 : i] -
  556:                     ch->element_index[omap_3_1 ? 0 : i];
  557:             break;
  558:         default:
  559:             break;
  560:         }
  561: }
  562: 
  563: static void omap_dma_activate_channel(struct omap_dma_s *s,
  564:                 struct omap_dma_channel_s *ch)
  565: {
  566:     if (!ch->active) {
  567:         ch->active = 1;
  568:         if (ch->sync)
  569:             ch->status |= SYNC;
  570:         s->run_count ++;
  571:     }
  572: 
  573:     if (s->delay && !qemu_timer_pending(s->tm))
  574:         qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
  575: }
  576: 
  577: static void omap_dma_deactivate_channel(struct omap_dma_s *s,
  578:                 struct omap_dma_channel_s *ch)