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

📄 omap.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    case 0x08:	/* READ_TIM */        return omap_timer_read(s);    }    OMAP_BAD_REG(addr);    return 0;}static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;    int offset = addr - s->base;    switch (offset) {    case 0x00:	/* CNTL_TIMER */        omap_timer_sync(s);        s->enable = (value >> 5) & 1;        s->ptv = (value >> 2) & 7;        s->ar = (value >> 1) & 1;        s->st = value & 1;        omap_timer_update(s);        return;    case 0x04:	/* LOAD_TIM */        s->reset_val = value;        return;    case 0x08:	/* READ_TIM */        OMAP_RO_REG(addr);        break;    default:        OMAP_BAD_REG(addr);    }}static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {    omap_badwidth_read32,    omap_badwidth_read32,    omap_mpu_timer_read,};static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {    omap_badwidth_write32,    omap_badwidth_write32,    omap_mpu_timer_write,};static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s){    qemu_del_timer(s->timer);    s->enable = 0;    s->reset_val = 31337;    s->val = 0;    s->ptv = 0;    s->ar = 0;    s->st = 0;    s->it_ena = 1;}struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,                qemu_irq irq, omap_clk clk){    int iomemtype;    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)            qemu_mallocz(sizeof(struct omap_mpu_timer_s));    s->irq = irq;    s->clk = clk;    s->base = base;    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);    omap_mpu_timer_reset(s);    omap_timer_clk_setup(s);    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,                    omap_mpu_timer_writefn, s);    cpu_register_physical_memory(s->base, 0x100, iomemtype);    return s;}/* Watchdog timer */struct omap_watchdog_timer_s {    struct omap_mpu_timer_s timer;    uint8_t last_wr;    int mode;    int free;    int reset;};static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr){    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;    int offset = addr - s->timer.base;    switch (offset) {    case 0x00:	/* CNTL_TIMER */        return (s->timer.ptv << 9) | (s->timer.ar << 8) |                (s->timer.st << 7) | (s->free << 1);    case 0x04:	/* READ_TIMER */        return omap_timer_read(&s->timer);    case 0x08:	/* TIMER_MODE */        return s->mode << 15;    }    OMAP_BAD_REG(addr);    return 0;}static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;    int offset = addr - s->timer.base;    switch (offset) {    case 0x00:	/* CNTL_TIMER */        omap_timer_sync(&s->timer);        s->timer.ptv = (value >> 9) & 7;        s->timer.ar = (value >> 8) & 1;        s->timer.st = (value >> 7) & 1;        s->free = (value >> 1) & 1;        omap_timer_update(&s->timer);        break;    case 0x04:	/* LOAD_TIMER */        s->timer.reset_val = value & 0xffff;        break;    case 0x08:	/* TIMER_MODE */        if (!s->mode && ((value >> 15) & 1))            omap_clk_get(s->timer.clk);        s->mode |= (value >> 15) & 1;        if (s->last_wr == 0xf5) {            if ((value & 0xff) == 0xa0) {                if (s->mode) {                    s->mode = 0;                    omap_clk_put(s->timer.clk);                }            } else {                /* XXX: on T|E hardware somehow this has no effect,                 * on Zire 71 it works as specified.  */                s->reset = 1;                qemu_system_reset_request();            }        }        s->last_wr = value & 0xff;        break;    default:        OMAP_BAD_REG(addr);    }}static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {    omap_badwidth_read16,    omap_wd_timer_read,    omap_badwidth_read16,};static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {    omap_badwidth_write16,    omap_wd_timer_write,    omap_badwidth_write16,};static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s){    qemu_del_timer(s->timer.timer);    if (!s->mode)        omap_clk_get(s->timer.clk);    s->mode = 1;    s->free = 1;    s->reset = 0;    s->timer.enable = 1;    s->timer.it_ena = 1;    s->timer.reset_val = 0xffff;    s->timer.val = 0;    s->timer.st = 0;    s->timer.ptv = 0;    s->timer.ar = 0;    omap_timer_update(&s->timer);}struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,                qemu_irq irq, omap_clk clk){    int iomemtype;    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));    s->timer.irq = irq;    s->timer.clk = clk;    s->timer.base = base;    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);    omap_wd_timer_reset(s);    omap_timer_clk_setup(&s->timer);    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,                    omap_wd_timer_writefn, s);    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);    return s;}/* 32-kHz timer */struct omap_32khz_timer_s {    struct omap_mpu_timer_s timer;};static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr){    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;    int offset = addr & OMAP_MPUI_REG_MASK;    switch (offset) {    case 0x00:	/* TVR */        return s->timer.reset_val;    case 0x04:	/* TCR */        return omap_timer_read(&s->timer);    case 0x08:	/* CR */        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;    default:        break;    }    OMAP_BAD_REG(addr);    return 0;}static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;    int offset = addr & OMAP_MPUI_REG_MASK;    switch (offset) {    case 0x00:	/* TVR */        s->timer.reset_val = value & 0x00ffffff;        break;    case 0x04:	/* TCR */        OMAP_RO_REG(addr);        break;    case 0x08:	/* CR */        s->timer.ar = (value >> 3) & 1;        s->timer.it_ena = (value >> 2) & 1;        if (s->timer.st != (value & 1) || (value & 2)) {            omap_timer_sync(&s->timer);            s->timer.enable = value & 1;            s->timer.st = value & 1;            omap_timer_update(&s->timer);        }        break;    default:        OMAP_BAD_REG(addr);    }}static CPUReadMemoryFunc *omap_os_timer_readfn[] = {    omap_badwidth_read32,    omap_badwidth_read32,    omap_os_timer_read,};static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {    omap_badwidth_write32,    omap_badwidth_write32,    omap_os_timer_write,};static void omap_os_timer_reset(struct omap_32khz_timer_s *s){    qemu_del_timer(s->timer.timer);    s->timer.enable = 0;    s->timer.it_ena = 0;    s->timer.reset_val = 0x00ffffff;    s->timer.val = 0;    s->timer.st = 0;    s->timer.ptv = 0;    s->timer.ar = 1;}struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,                qemu_irq irq, omap_clk clk){    int iomemtype;    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)            qemu_mallocz(sizeof(struct omap_32khz_timer_s));    s->timer.irq = irq;    s->timer.clk = clk;    s->timer.base = base;    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);    omap_os_timer_reset(s);    omap_timer_clk_setup(&s->timer);    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,                    omap_os_timer_writefn, s);    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);    return s;}/* Ultra Low-Power Device Module */static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr){    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;    int offset = addr - s->ulpd_pm_base;    uint16_t ret;    switch (offset) {    case 0x14:	/* IT_STATUS */        ret = s->ulpd_pm_regs[offset >> 2];        s->ulpd_pm_regs[offset >> 2] = 0;        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);        return ret;    case 0x18:	/* Reserved */    case 0x1c:	/* Reserved */    case 0x20:	/* Reserved */    case 0x28:	/* Reserved */    case 0x2c:	/* Reserved */        OMAP_BAD_REG(addr);    case 0x00:	/* COUNTER_32_LSB */    case 0x04:	/* COUNTER_32_MSB */    case 0x08:	/* COUNTER_HIGH_FREQ_LSB */    case 0x0c:	/* COUNTER_HIGH_FREQ_MSB */    case 0x10:	/* GAUGING_CTRL */    case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */    case 0x30:	/* CLOCK_CTRL */    case 0x34:	/* SOFT_REQ */    case 0x38:	/* COUNTER_32_FIQ */    case 0x3c:	/* DPLL_CTRL */    case 0x40:	/* STATUS_REQ */        /* XXX: check clk::usecount state for every clock */    case 0x48:	/* LOCL_TIME */    case 0x4c:	/* APLL_CTRL */    case 0x50:	/* POWER_CTRL */        return s->ulpd_pm_regs[offset >> 2];    }    OMAP_BAD_REG(addr);    return 0;}static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,                uint16_t diff, uint16_t value){    if (diff & (1 << 4))				/* USB_MCLK_EN */        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);    if (diff & (1 << 5))				/* DIS_USB_PVCI_CLK */        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);}static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,                uint16_t diff, uint16_t value){    if (diff & (1 << 0))				/* SOFT_DPLL_REQ */        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);    if (diff & (1 << 1))				/* SOFT_COM_REQ */        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);    if (diff & (1 << 2))				/* SOFT_SDW_REQ */        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);    if (diff & (1 << 3))				/* SOFT_USB_REQ */        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);}static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;    int offset = addr - s->ulpd_pm_base;    int64_t now, ticks;    int div, mult;    static const int bypass_div[4] = { 1, 2, 4, 4 };    uint16_t diff;    switch (offset) {    case 0x00:	/* COUNTER_32_LSB */    case 0x04:	/* COUNTER_32_MSB */    case 0x08:	/* COUNTER_HIGH_FREQ_LSB */    case 0x0c:	/* COUNTER_HIGH_FREQ_MSB */    case 0x14:	/* IT_STATUS */    case 0x40:	/* STATUS_REQ */        OMAP_RO_REG(addr);        break;    case 0x10:	/* GAUGING_CTRL */        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {            now = qemu_get_clock(vm_clock);            if (value & 1)                s->ulpd_gauge_start = now;            else {                now -= s->ulpd_gauge_start;                /* 32-kHz ticks */                ticks = muldiv64(now, 32768, ticks_per_sec);                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;                if (ticks >> 32)	/* OVERFLOW_32K */                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;                /* High frequency ticks */                ticks = muldiv64(now, 12000000, ticks_per_sec);                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;                if (ticks >> 32)	/* OVERFLOW_HI_FREQ */                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;	/* IT_GAUGING */                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);            }        }        s->ulpd_pm_regs[offset >> 2] = value;        break;    case 0x18:	/* Reserved */    case 0x1c:	/* Reserved */    case 0x20:	/* Reserved */    case 0x28:	/* Reserved */    case 0x2c:	/* Reserved */        OMAP_BAD_REG(addr);    case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */    case 0x38:	/* COUNTER_32_FIQ */    case 0x48:	/* LOCL_TIME */    case 0x50:	/* POWER_CTRL */        s->ulpd_pm_regs[offset >> 2] = value;        break;    case 0x30:	/* CLOCK_CTRL */        diff = s->ulpd_pm_regs[offset >> 2] ^ value;        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;        omap_ulpd_clk_update(s, diff, value);        break;    case 0x34:	/* SOFT_REQ */        diff = s->ulpd_pm_regs[offset >> 2] ^ value;        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;        omap_ulpd_req_update(s, diff, value);        break;    case 0x3c:	/* DPLL_CTRL */        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is         * omitted altogether, probably a typo.  */        /* This register has identical semantics with DPLL(1:3) control         * registers, see omap_dpll_write() */        diff = s->ulpd_pm_regs[offset >> 2] & value;        s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;        if (diff & (0x3ff << 2)) {            if (value & (1 << 4)) {			/* PLL_ENABLE */                div = ((value >> 5) & 3) + 1;		/* PLL_DIV */                mult = MIN((value >> 7) & 0x1f, 1);	/* PLL_MULT */

⌨️ 快捷键说明

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