⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 omap.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    QEMUTimer *tm;    struct omap_mpu_state_s *mpu;    target_phys_addr_t base;    omap_clk clk;    int64_t delay;    uint32_t drq;    enum omap_dma_model model;    int omap_3_1_mapping_disabled;    uint16_t gcr;    int run_count;    int chans;    struct omap_dma_channel_s ch[16];    struct omap_dma_lcd_channel_s lcd_ch;};/* Interrupts */#define TIMEOUT_INTR    (1 << 0)#define EVENT_DROP_INTR (1 << 1)#define HALF_FRAME_INTR (1 << 2)#define END_FRAME_INTR  (1 << 3)#define LAST_FRAME_INTR (1 << 4)#define END_BLOCK_INTR  (1 << 5)#define SYNC            (1 << 6)static void omap_dma_interrupts_update(struct omap_dma_s *s){    struct omap_dma_channel_s *ch = s->ch;    int i;    if (s->omap_3_1_mapping_disabled) {        for (i = 0; i < s->chans; i ++, ch ++)            if (ch->status)                qemu_irq_raise(ch->irq);    } else {        /* First three interrupts are shared between two channels each. */        for (i = 0; i < 6; i ++, ch ++) {            if (ch->status || (ch->sibling && ch->sibling->status))                qemu_irq_raise(ch->irq);        }    }}static void omap_dma_channel_load(struct omap_dma_s *s,                struct omap_dma_channel_s *ch){    struct omap_dma_reg_set_s *a = &ch->active_set;    int i;    int omap_3_1 = !ch->omap_3_1_compatible_disable;    /*     * TODO: verify address ranges and alignment     * TODO: port endianness     */    a->src = ch->addr[0];    a->dest = ch->addr[1];    a->frames = ch->frames;    a->elements = ch->elements;    a->frame = 0;    a->element = 0;    if (unlikely(!ch->elements || !ch->frames)) {        printf("%s: bad DMA request\n", __FUNCTION__);        return;    }    for (i = 0; i < 2; i ++)        switch (ch->mode[i]) {        case constant:            a->elem_delta[i] = 0;            a->frame_delta[i] = 0;            break;        case post_incremented:            a->elem_delta[i] = ch->data_type;            a->frame_delta[i] = 0;            break;        case single_index:            a->elem_delta[i] = ch->data_type +                    ch->element_index[omap_3_1 ? 0 : i] - 1;            a->frame_delta[i] = 0;            break;        case double_index:            a->elem_delta[i] = ch->data_type +                    ch->element_index[omap_3_1 ? 0 : i] - 1;            a->frame_delta[i] = ch->frame_index[omap_3_1 ? 0 : i] -                    ch->element_index[omap_3_1 ? 0 : i];            break;        default:            break;        }}static void omap_dma_activate_channel(struct omap_dma_s *s,                struct omap_dma_channel_s *ch){    if (!ch->active) {        ch->active = 1;        if (ch->sync)            ch->status |= SYNC;        s->run_count ++;    }    if (s->delay && !qemu_timer_pending(s->tm))        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);}static void omap_dma_deactivate_channel(struct omap_dma_s *s,                struct omap_dma_channel_s *ch){    /* Update cpc */    ch->cpc = ch->active_set.dest & 0xffff;    if (ch->pending_request && !ch->waiting_end_prog) {        /* Don't deactivate the channel */        ch->pending_request = 0;        return;    }    /* Don't deactive the channel if it is synchronized and the DMA request is       active */    if (ch->sync && (s->drq & (1 << ch->sync)))        return;    if (ch->active) {        ch->active = 0;        ch->status &= ~SYNC;        s->run_count --;    }    if (!s->run_count)        qemu_del_timer(s->tm);}static void omap_dma_enable_channel(struct omap_dma_s *s,                struct omap_dma_channel_s *ch){    if (!ch->enable) {        ch->enable = 1;        ch->waiting_end_prog = 0;        omap_dma_channel_load(s, ch);        if ((!ch->sync) || (s->drq & (1 << ch->sync)))            omap_dma_activate_channel(s, ch);    }}static void omap_dma_disable_channel(struct omap_dma_s *s,                struct omap_dma_channel_s *ch){    if (ch->enable) {        ch->enable = 0;        /* Discard any pending request */        ch->pending_request = 0;        omap_dma_deactivate_channel(s, ch);    }}static void omap_dma_channel_end_prog(struct omap_dma_s *s,                struct omap_dma_channel_s *ch){    if (ch->waiting_end_prog) {        ch->waiting_end_prog = 0;        if (!ch->sync || ch->pending_request) {            ch->pending_request = 0;            omap_dma_activate_channel(s, ch);        }    }}static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s){    s->omap_3_1_mapping_disabled = 0;    s->chans = 9;}static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s){    s->omap_3_1_mapping_disabled = 1;    s->chans = 16;}static void omap_dma_process_request(struct omap_dma_s *s, int request){    int channel;    int drop_event = 0;    struct omap_dma_channel_s *ch = s->ch;    for (channel = 0; channel < s->chans; channel ++, ch ++) {        if (ch->enable && ch->sync == request) {            if (!ch->active)                omap_dma_activate_channel(s, ch);            else if (!ch->pending_request)                ch->pending_request = 1;            else {                /* Request collision */                /* Second request received while processing other request */                ch->status |= EVENT_DROP_INTR;                drop_event = 1;            }        }    }    if (drop_event)        omap_dma_interrupts_update(s);}static void omap_dma_channel_run(struct omap_dma_s *s){    int n = s->chans;    uint16_t status;    uint8_t value[4];    struct omap_dma_port_if_s *src_p, *dest_p;    struct omap_dma_reg_set_s *a;    struct omap_dma_channel_s *ch;    for (ch = s->ch; n; n --, ch ++) {        if (!ch->active)            continue;        a = &ch->active_set;        src_p = &s->mpu->port[ch->port[0]];        dest_p = &s->mpu->port[ch->port[1]];        if ((!ch->constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||                        (!dest_p->addr_valid(s->mpu, a->dest))) {#if 0            /* Bus time-out */            if (ch->interrupts & TIMEOUT_INTR)                ch->status |= TIMEOUT_INTR;            omap_dma_deactivate_channel(s, ch);            continue;#endif            printf("%s: Bus time-out in DMA%i operation\n",                            __FUNCTION__, s->chans - n);        }        status = ch->status;        while (status == ch->status && ch->active) {            /* Transfer a single element */            /* FIXME: check the endianness */            if (!ch->constant_fill)                cpu_physical_memory_read(a->src, value, ch->data_type);            else                *(uint32_t *) value = ch->color;            if (!ch->transparent_copy ||                    *(uint32_t *) value != ch->color)                cpu_physical_memory_write(a->dest, value, ch->data_type);            a->src += a->elem_delta[0];            a->dest += a->elem_delta[1];            a->element ++;            /* If the channel is element synchronized, deactivate it */            if (ch->sync && !ch->fs && !ch->bs)                omap_dma_deactivate_channel(s, ch);            /* If it is the last frame, set the LAST_FRAME interrupt */            if (a->element == 1 && a->frame == a->frames - 1)                if (ch->interrupts & LAST_FRAME_INTR)                    ch->status |= LAST_FRAME_INTR;            /* If the half of the frame was reached, set the HALF_FRAME               interrupt */            if (a->element == (a->elements >> 1))                if (ch->interrupts & HALF_FRAME_INTR)                    ch->status |= HALF_FRAME_INTR;            if (a->element == a->elements) {                /* End of Frame */                a->element = 0;                a->src += a->frame_delta[0];                a->dest += a->frame_delta[1];                a->frame ++;                /* If the channel is frame synchronized, deactivate it */                if (ch->sync && ch->fs)                    omap_dma_deactivate_channel(s, ch);                /* If the channel is async, update cpc */                if (!ch->sync)                    ch->cpc = a->dest & 0xffff;                /* Set the END_FRAME interrupt */                if (ch->interrupts & END_FRAME_INTR)                    ch->status |= END_FRAME_INTR;                if (a->frame == a->frames) {                    /* End of Block */                    /* Disable the channel */                    if (ch->omap_3_1_compatible_disable) {                        omap_dma_disable_channel(s, ch);                        if (ch->link_enabled)                            omap_dma_enable_channel(s,                                            &s->ch[ch->link_next_ch]);                    } else {                        if (!ch->auto_init)                            omap_dma_disable_channel(s, ch);                        else if (ch->repeat || ch->end_prog)                            omap_dma_channel_load(s, ch);                        else {                            ch->waiting_end_prog = 1;                            omap_dma_deactivate_channel(s, ch);                        }                    }                    if (ch->interrupts & END_BLOCK_INTR)                        ch->status |= END_BLOCK_INTR;                }            }        }    }    omap_dma_interrupts_update(s);    if (s->run_count && s->delay)        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);}static void omap_dma_reset(struct omap_dma_s *s){    int i;    qemu_del_timer(s->tm);    s->gcr = 0x0004;    s->drq = 0x00000000;    s->run_count = 0;    s->lcd_ch.src = emiff;    s->lcd_ch.condition = 0;    s->lcd_ch.interrupts = 0;    s->lcd_ch.dual = 0;    omap_dma_enable_3_1_mapping(s);    for (i = 0; i < s->chans; i ++) {        memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst));        memset(&s->ch[i].port, 0, sizeof(s->ch[i].port));        memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode));        memset(&s->ch[i].elements, 0, sizeof(s->ch[i].elements));        memset(&s->ch[i].frames, 0, sizeof(s->ch[i].frames));        memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index));        memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index));        memset(&s->ch[i].data_type, 0, sizeof(s->ch[i].data_type));        memset(&s->ch[i].transparent_copy, 0,                        sizeof(s->ch[i].transparent_copy));        memset(&s->ch[i].constant_fill, 0, sizeof(s->ch[i].constant_fill));        memset(&s->ch[i].color, 0, sizeof(s->ch[i].color));        memset(&s->ch[i].end_prog, 0, sizeof(s->ch[i].end_prog));        memset(&s->ch[i].repeat, 0, sizeof(s->ch[i].repeat));        memset(&s->ch[i].auto_init, 0, sizeof(s->ch[i].auto_init));        memset(&s->ch[i].link_enabled, 0, sizeof(s->ch[i].link_enabled));        memset(&s->ch[i].link_next_ch, 0, sizeof(s->ch[i].link_next_ch));        s->ch[i].interrupts = 0x0003;        memset(&s->ch[i].status, 0, sizeof(s->ch[i].status));        memset(&s->ch[i].active, 0, sizeof(s->ch[i].active));        memset(&s->ch[i].enable, 0, sizeof(s->ch[i].enable));        memset(&s->ch[i].sync, 0, sizeof(s->ch[i].sync));        memset(&s->ch[i].pending_request, 0, sizeof(s->ch[i].pending_request));        memset(&s->ch[i].waiting_end_prog, 0,                        sizeof(s->ch[i].waiting_end_prog));        memset(&s->ch[i].cpc, 0, sizeof(s->ch[i].cpc));        memset(&s->ch[i].fs, 0, sizeof(s->ch[i].fs));        memset(&s->ch[i].bs, 0, sizeof(s->ch[i].bs));        memset(&s->ch[i].omap_3_1_compatible_disable, 0,                        sizeof(s->ch[i].omap_3_1_compatible_disable));        memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set));        memset(&s->ch[i].priority, 0, sizeof(s->ch[i].priority));        memset(&s->ch[i].interleave_disabled, 0,                        sizeof(s->ch[i].interleave_disabled));        memset(&s->ch[i].type, 0, sizeof(s->ch[i].type));    }}static int omap_dma_ch_reg_read(struct omap_dma_s *s,                struct omap_dma_channel_s *ch, int reg, uint16_t *value){    switch (reg) {    case 0x00:	/* SYS_DMA_CSDP_CH0 */        *value = (ch->burst[1] << 14) |                (ch->pack[1] << 13) |                (ch->port[1] << 9) |                (ch->burst[0] << 7) |                (ch->pack[0] << 6) |                (ch->port[0] << 2) |                (ch->data_type >> 1);        break;    case 0x02:	/* SYS_DMA_CCR_CH0 */        if (s->model == omap_dma_3_1)            *value = 0 << 10;			/* FIFO_FLUSH reads as 0 */        else            *value = ch->omap_3_1_compatible_disable << 10;        *value |= (ch->mode[1] << 14) |                (ch->mode[0] << 12) |                (ch->end_prog << 11) |                (ch->repeat << 9) |                (ch->auto_init << 8) |                (ch->enable << 7) |                (ch->priority << 6) |                (ch->fs << 5) | ch->sync;        break;    case 0x04:	/* SYS_DMA_CICR_CH0 */        *value = ch->interrupts;        break;    case 0x06:	/* SYS_DMA_CSR_CH0 */        *value = ch->status;        ch->status &= SYNC;        if (!ch->omap_3_1_compatible_disable && ch->sibling) {            *value |= (ch->sibling->status & 0x3f) << 6;            ch->sibling->status &= SYNC;        }        qemu_irq_lower(ch->irq);        break;    case 0x08:	/* SYS_DMA_CSSA_L_CH0 */        *value = ch->addr[0] & 0x0000ffff;        break;    case 0x0a:	/* SYS_DMA_CSSA_U_CH0 */        *value = ch->addr[0] >> 16;        break;    case 0x0c:	/* SYS_DMA_CDSA_L_CH0 */        *value = ch->addr[1] & 0x0000ffff;        break;    case 0x0e:	/* SYS_DMA_CDSA_U_CH0 */        *value = ch->addr[1] >> 16;        break;    case 0x10:	/* SYS_DMA_CEN_CH0 */        *value = ch->elements;        break;    case 0x12:	/* SYS_DMA_CFN_CH0 */        *value = ch->frames;        break;    case 0x14:	/* SYS_DMA_CFI_CH0 */        *value = ch->frame_index[0];        break;    case 0x16:	/* SYS_DMA_CEI_CH0 */        *value = ch->element_index[0];        break;    case 0x18:	/* SYS_DMA_CPC_CH0 or DMA_CSAC */        if (ch->omap_3_1_compatible_disable)            *value = ch->active_set.src & 0xffff;	/* CSAC */        else            *value = ch->cpc;        break;    case 0x1a:	/* DMA_CDAC */        *value = ch->active_set.dest & 0xffff;	/* CDAC */        break;    case 0x1c:	/* DMA_CDEI */        *value = ch->element_index[1];        break;    case 0x1e:	/* DMA_CDFI */        *value = ch->frame_index[1];        break;    case 0x20:	/* DMA_COLOR_L */        *value = ch->color & 0xffff;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -