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

📄 omap.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/* * TI OMAP processors emulation. * * Copyright (C) 2006-2007 Andrzej Zaborowski  <balrog@zabor.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include "hw.h"#include "arm-misc.h"#include "omap.h"#include "sysemu.h"#include "qemu-timer.h"/* We use pc-style serial ports.  */#include "pc.h"/* Should signal the TCMI */uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr){    uint8_t ret;    OMAP_8B_REG(addr);    cpu_physical_memory_read(addr, (void *) &ret, 1);    return ret;}void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,                uint32_t value){    uint8_t val8 = value;    OMAP_8B_REG(addr);    cpu_physical_memory_write(addr, (void *) &val8, 1);}uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr){    uint16_t ret;    OMAP_16B_REG(addr);    cpu_physical_memory_read(addr, (void *) &ret, 2);    return ret;}void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,                uint32_t value){    uint16_t val16 = value;    OMAP_16B_REG(addr);    cpu_physical_memory_write(addr, (void *) &val16, 2);}uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr){    uint32_t ret;    OMAP_32B_REG(addr);    cpu_physical_memory_read(addr, (void *) &ret, 4);    return ret;}void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,                uint32_t value){    OMAP_32B_REG(addr);    cpu_physical_memory_write(addr, (void *) &value, 4);}/* Interrupt Handlers */struct omap_intr_handler_bank_s {    uint32_t irqs;    uint32_t inputs;    uint32_t mask;    uint32_t fiq;    uint32_t sens_edge;    unsigned char priority[32];};struct omap_intr_handler_s {    qemu_irq *pins;    qemu_irq parent_intr[2];    target_phys_addr_t base;    unsigned char nbanks;    /* state */    uint32_t new_agr[2];    int sir_intr[2];    struct omap_intr_handler_bank_s banks[];};static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq){    int i, j, sir_intr, p_intr, p, f;    uint32_t level;    sir_intr = 0;    p_intr = 255;    /* Find the interrupt line with the highest dynamic priority.     * Note: 0 denotes the hightest priority.     * If all interrupts have the same priority, the default order is IRQ_N,     * IRQ_N-1,...,IRQ_0. */    for (j = 0; j < s->nbanks; ++j) {        level = s->banks[j].irqs & ~s->banks[j].mask &                (is_fiq ? s->banks[j].fiq : ~s->banks[j].fiq);        for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,                        level >>= f) {            p = s->banks[j].priority[i];            if (p <= p_intr) {                p_intr = p;                sir_intr = 32 * j + i;            }            f = ffs(level >> 1);        }    }    s->sir_intr[is_fiq] = sir_intr;}static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq){    int i;    uint32_t has_intr = 0;    for (i = 0; i < s->nbanks; ++i)        has_intr |= s->banks[i].irqs & ~s->banks[i].mask &                (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq);    if (s->new_agr[is_fiq] && has_intr) {        s->new_agr[is_fiq] = 0;        omap_inth_sir_update(s, is_fiq);        qemu_set_irq(s->parent_intr[is_fiq], 1);    }}#define INT_FALLING_EDGE	0#define INT_LOW_LEVEL		1static void omap_set_intr(void *opaque, int irq, int req){    struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;    uint32_t rise;    struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5];    int n = irq & 31;    if (req) {        rise = ~bank->irqs & (1 << n);        if (~bank->sens_edge & (1 << n))            rise &= ~bank->inputs & (1 << n);        bank->inputs |= (1 << n);        if (rise) {            bank->irqs |= rise;            omap_inth_update(ih, 0);            omap_inth_update(ih, 1);        }    } else {        rise = bank->sens_edge & bank->irqs & (1 << n);        bank->irqs &= ~rise;        bank->inputs &= ~(1 << n);    }}static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr){    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;    int i, offset = addr - s->base;    int bank_no = offset >> 8;    int line_no;    struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];    offset &= 0xff;    switch (offset) {    case 0x00:	/* ITR */        return bank->irqs;    case 0x04:	/* MIR */        return bank->mask;    case 0x10:	/* SIR_IRQ_CODE */    case 0x14:  /* SIR_FIQ_CODE */        if (bank_no != 0)            break;        line_no = s->sir_intr[(offset - 0x10) >> 2];        bank = &s->banks[line_no >> 5];        i = line_no & 31;        if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)            bank->irqs &= ~(1 << i);        return line_no;    case 0x18:	/* CONTROL_REG */        if (bank_no != 0)            break;        return 0;    case 0x1c:	/* ILR0 */    case 0x20:	/* ILR1 */    case 0x24:	/* ILR2 */    case 0x28:	/* ILR3 */    case 0x2c:	/* ILR4 */    case 0x30:	/* ILR5 */    case 0x34:	/* ILR6 */    case 0x38:	/* ILR7 */    case 0x3c:	/* ILR8 */    case 0x40:	/* ILR9 */    case 0x44:	/* ILR10 */    case 0x48:	/* ILR11 */    case 0x4c:	/* ILR12 */    case 0x50:	/* ILR13 */    case 0x54:	/* ILR14 */    case 0x58:	/* ILR15 */    case 0x5c:	/* ILR16 */    case 0x60:	/* ILR17 */    case 0x64:	/* ILR18 */    case 0x68:	/* ILR19 */    case 0x6c:	/* ILR20 */    case 0x70:	/* ILR21 */    case 0x74:	/* ILR22 */    case 0x78:	/* ILR23 */    case 0x7c:	/* ILR24 */    case 0x80:	/* ILR25 */    case 0x84:	/* ILR26 */    case 0x88:	/* ILR27 */    case 0x8c:	/* ILR28 */    case 0x90:	/* ILR29 */    case 0x94:	/* ILR30 */    case 0x98:	/* ILR31 */        i = (offset - 0x1c) >> 2;        return (bank->priority[i] << 2) |                (((bank->sens_edge >> i) & 1) << 1) |                ((bank->fiq >> i) & 1);    case 0x9c:	/* ISR */        return 0x00000000;    }    OMAP_BAD_REG(addr);    return 0;}static void omap_inth_write(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;    int i, offset = addr - s->base;    int bank_no = offset >> 8;    struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];    offset &= 0xff;    switch (offset) {    case 0x00:	/* ITR */        /* Important: ignore the clearing if the IRQ is level-triggered and           the input bit is 1 */        bank->irqs &= value | (bank->inputs & bank->sens_edge);        return;    case 0x04:	/* MIR */        bank->mask = value;        omap_inth_update(s, 0);        omap_inth_update(s, 1);        return;    case 0x10:	/* SIR_IRQ_CODE */    case 0x14:	/* SIR_FIQ_CODE */        OMAP_RO_REG(addr);        break;    case 0x18:	/* CONTROL_REG */        if (bank_no != 0)            break;        if (value & 2) {            qemu_set_irq(s->parent_intr[1], 0);            s->new_agr[1] = ~0;            omap_inth_update(s, 1);        }        if (value & 1) {            qemu_set_irq(s->parent_intr[0], 0);            s->new_agr[0] = ~0;            omap_inth_update(s, 0);        }        return;    case 0x1c:	/* ILR0 */    case 0x20:	/* ILR1 */    case 0x24:	/* ILR2 */    case 0x28:	/* ILR3 */    case 0x2c:	/* ILR4 */    case 0x30:	/* ILR5 */    case 0x34:	/* ILR6 */    case 0x38:	/* ILR7 */    case 0x3c:	/* ILR8 */    case 0x40:	/* ILR9 */    case 0x44:	/* ILR10 */    case 0x48:	/* ILR11 */    case 0x4c:	/* ILR12 */    case 0x50:	/* ILR13 */    case 0x54:	/* ILR14 */    case 0x58:	/* ILR15 */    case 0x5c:	/* ILR16 */    case 0x60:	/* ILR17 */    case 0x64:	/* ILR18 */    case 0x68:	/* ILR19 */    case 0x6c:	/* ILR20 */    case 0x70:	/* ILR21 */    case 0x74:	/* ILR22 */    case 0x78:	/* ILR23 */    case 0x7c:	/* ILR24 */    case 0x80:	/* ILR25 */    case 0x84:	/* ILR26 */    case 0x88:	/* ILR27 */    case 0x8c:	/* ILR28 */    case 0x90:	/* ILR29 */    case 0x94:	/* ILR30 */    case 0x98:	/* ILR31 */        i = (offset - 0x1c) >> 2;        bank->priority[i] = (value >> 2) & 0x1f;        bank->sens_edge &= ~(1 << i);        bank->sens_edge |= ((value >> 1) & 1) << i;        bank->fiq &= ~(1 << i);        bank->fiq |= (value & 1) << i;        return;    case 0x9c:	/* ISR */        for (i = 0; i < 32; i ++)            if (value & (1 << i)) {                omap_set_intr(s, 32 * bank_no + i, 1);                return;            }        return;    }    OMAP_BAD_REG(addr);}static CPUReadMemoryFunc *omap_inth_readfn[] = {    omap_badwidth_read32,    omap_badwidth_read32,    omap_inth_read,};static CPUWriteMemoryFunc *omap_inth_writefn[] = {    omap_inth_write,    omap_inth_write,    omap_inth_write,};void omap_inth_reset(struct omap_intr_handler_s *s){    int i;    for (i = 0; i < s->nbanks; ++i){        s->banks[i].irqs = 0x00000000;        s->banks[i].mask = 0xffffffff;        s->banks[i].sens_edge = 0x00000000;        s->banks[i].fiq = 0x00000000;        s->banks[i].inputs = 0x00000000;        memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority));    }    s->new_agr[0] = ~0;    s->new_agr[1] = ~0;    s->sir_intr[0] = 0;    s->sir_intr[1] = 0;    qemu_set_irq(s->parent_intr[0], 0);    qemu_set_irq(s->parent_intr[1], 0);}struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,                unsigned long size, unsigned char nbanks,                qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk){    int iomemtype;    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)            qemu_mallocz(sizeof(struct omap_intr_handler_s) +                            sizeof(struct omap_intr_handler_bank_s) * nbanks);    s->parent_intr[0] = parent_irq;    s->parent_intr[1] = parent_fiq;    s->base = base;    s->nbanks = nbanks;    s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);    omap_inth_reset(s);    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,                    omap_inth_writefn, s);    cpu_register_physical_memory(s->base, size, iomemtype);    return s;}/* OMAP1 DMA module */struct omap_dma_channel_s {    /* transfer data */    int burst[2];    int pack[2];    enum omap_dma_port port[2];    target_phys_addr_t addr[2];    omap_dma_addressing_t mode[2];    uint16_t elements;    uint16_t frames;    int16_t frame_index[2];    int16_t element_index[2];    int data_type;    /* transfer type */    int transparent_copy;    int constant_fill;    uint32_t color;    /* auto init and linked channel data */    int end_prog;    int repeat;    int auto_init;    int link_enabled;    int link_next_ch;    /* interruption data */    int interrupts;    int status;    /* state data */    int active;    int enable;    int sync;    int pending_request;    int waiting_end_prog;    uint16_t cpc;    /* sync type */    int fs;    int bs;    /* compatibility */    int omap_3_1_compatible_disable;    qemu_irq irq;    struct omap_dma_channel_s *sibling;    struct omap_dma_reg_set_s {        target_phys_addr_t src, dest;        int frame;        int element;        int frame_delta[2];        int elem_delta[2];        int frames;        int elements;    } active_set;    /* unused parameters */    int priority;    int interleave_disabled;    int type;};struct omap_dma_s {

⌨️ 快捷键说明

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