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

📄 ppc.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* * QEMU generic PowerPC hardware System Emulator * * Copyright (c) 2003-2007 Jocelyn Mayer * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */#include "hw.h"#include "ppc.h"#include "qemu-timer.h"#include "sysemu.h"#include "nvram.h"//#define PPC_DEBUG_IRQ//#define PPC_DEBUG_TBextern FILE *logfile;extern int loglevel;static void cpu_ppc_tb_stop (CPUState *env);static void cpu_ppc_tb_start (CPUState *env);static void ppc_set_irq (CPUState *env, int n_IRQ, int level){    printf("\n ppc_set_irq n_irq:%x, level:%x \n",n_IRQ,level);//debugger        if (level) {        env->pending_interrupts |= 1 << n_IRQ;        cpu_interrupt(env, CPU_INTERRUPT_HARD);    } else {        env->pending_interrupts &= ~(1 << n_IRQ);        if (env->pending_interrupts == 0)            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);    }#if defined(PPC_DEBUG_IRQ)    if (loglevel & CPU_LOG_INT) {        fprintf(logfile, "%s: %p n_IRQ %d level %d => pending %08" PRIx32                "req %08x\n", __func__, env, n_IRQ, level,                env->pending_interrupts, env->interrupt_request);    }#endif}/* PowerPC 6xx / 7xx internal IRQ controller */static void ppc6xx_set_irq (void *opaque, int pin, int level){    CPUState *env = opaque;    int cur_level;#if defined(PPC_DEBUG_IRQ)    if (loglevel & CPU_LOG_INT) {        fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,                env, pin, level);    }#endif    cur_level = (env->irq_input_state >> pin) & 1;    /* Don't generate spurious events */    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {        switch (pin) {        case PPC6xx_INPUT_TBEN:            /* Level sensitive - active high */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: %s the time base\n",                        __func__, level ? "start" : "stop");            }#endif            if (level) {                cpu_ppc_tb_start(env);            } else {                cpu_ppc_tb_stop(env);            }        case PPC6xx_INPUT_INT:            /* Level sensitive - active high */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the external IRQ state to %d\n",                        __func__, level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);            break;        case PPC6xx_INPUT_SMI:            /* Level sensitive - active high */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the SMI IRQ state to %d\n",                        __func__, level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_SMI, level);            break;        case PPC6xx_INPUT_MCP:            /* Negative edge sensitive */            /* XXX: TODO: actual reaction may depends on HID0 status             *            603/604/740/750: check HID0[EMCP]             */            if (cur_level == 1 && level == 0) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: raise machine check state\n",                            __func__);                }#endif                ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);            }            break;        case PPC6xx_INPUT_CKSTP_IN:            /* Level sensitive - active low */            /* XXX: TODO: relay the signal to CKSTP_OUT pin */            /* XXX: Note that the only way to restart the CPU is to reset it */            if (level) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: stop the CPU\n", __func__);                }#endif                env->halted = 1;            }            break;        case PPC6xx_INPUT_HRESET:            /* Level sensitive - active low */            if (level) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: reset the CPU\n", __func__);                }#endif                env->interrupt_request |= CPU_INTERRUPT_EXITTB;                /* XXX: TOFIX */#if 0                cpu_ppc_reset(env);#else                qemu_system_reset_request();#endif            }            break;        case PPC6xx_INPUT_SRESET:#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the RESET IRQ state to %d\n",                        __func__, level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);            break;        default:            /* Unknown pin - do nothing */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);            }#endif            return;        }        if (level)            env->irq_input_state |= 1 << pin;        else            env->irq_input_state &= ~(1 << pin);    }}void ppc6xx_irq_init (CPUState *env){    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env,                                                  PPC6xx_INPUT_NB);}#if defined(TARGET_PPC64)/* PowerPC 970 internal IRQ controller */static void ppc970_set_irq (void *opaque, int pin, int level){    CPUState *env = opaque;    int cur_level;#if defined(PPC_DEBUG_IRQ)    if (loglevel & CPU_LOG_INT) {        fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,                env, pin, level);    }#endif    cur_level = (env->irq_input_state >> pin) & 1;    /* Don't generate spurious events */    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {        switch (pin) {        case PPC970_INPUT_INT:            /* Level sensitive - active high */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the external IRQ state to %d\n",                        __func__, level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);            break;        case PPC970_INPUT_THINT:            /* Level sensitive - active high */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the SMI IRQ state to %d\n", __func__,                        level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_THERM, level);            break;        case PPC970_INPUT_MCP:            /* Negative edge sensitive */            /* XXX: TODO: actual reaction may depends on HID0 status             *            603/604/740/750: check HID0[EMCP]             */            if (cur_level == 1 && level == 0) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: raise machine check state\n",                            __func__);                }#endif                ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);            }            break;        case PPC970_INPUT_CKSTP:            /* Level sensitive - active low */            /* XXX: TODO: relay the signal to CKSTP_OUT pin */            if (level) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: stop the CPU\n", __func__);                }#endif                env->halted = 1;            } else {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: restart the CPU\n", __func__);                }#endif                env->halted = 0;            }            break;        case PPC970_INPUT_HRESET:            /* Level sensitive - active low */            if (level) {#if 0 // XXX: TOFIX#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: reset the CPU\n", __func__);                }#endif                cpu_reset(env);#endif            }            break;        case PPC970_INPUT_SRESET:#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the RESET IRQ state to %d\n",                        __func__, level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);            break;        case PPC970_INPUT_TBEN:#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the TBEN state to %d\n", __func__,                        level);            }#endif            /* XXX: TODO */            break;        default:            /* Unknown pin - do nothing */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);            }#endif            return;        }        if (level)            env->irq_input_state |= 1 << pin;        else            env->irq_input_state &= ~(1 << pin);    }}void ppc970_irq_init (CPUState *env){    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env,                                                  PPC970_INPUT_NB);}#endif /* defined(TARGET_PPC64) *//* PowerPC 40x internal IRQ controller */static void ppc40x_set_irq (void *opaque, int pin, int level){    CPUState *env = opaque;    int cur_level;#if defined(PPC_DEBUG_IRQ)    if (loglevel & CPU_LOG_INT) {        fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,                env, pin, level);    }#endif    cur_level = (env->irq_input_state >> pin) & 1;    /* Don't generate spurious events */    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {        switch (pin) {        case PPC40x_INPUT_RESET_SYS:            if (level) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: reset the PowerPC system\n",                            __func__);                }#endif                ppc40x_system_reset(env);//qemu reset            }            break;        case PPC40x_INPUT_RESET_CHIP:            if (level) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: reset the PowerPC chip\n", __func__);                }#endif                ppc40x_chip_reset(env);//cpu reset            }            break;        case PPC40x_INPUT_RESET_CORE:            /* XXX: TODO: update DBSR[MRR] */            if (level) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: reset the PowerPC core\n", __func__);                }#endif                ppc40x_core_reset(env);            }            break;        case PPC40x_INPUT_CINT:            /* Level sensitive - active high */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the critical IRQ state to %d\n",                        __func__, level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);            break;        case PPC40x_INPUT_INT:            /* Level sensitive - active high */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the external IRQ state to %d\n",                        __func__, level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);            printf("PPC40x_INPUT_INT is happend\n");//debbugger            break;        case PPC40x_INPUT_HALT:            /* Level sensitive - active low */            if (level) {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: stop the CPU\n", __func__);                }#endif                env->halted = 1;            } else {#if defined(PPC_DEBUG_IRQ)                if (loglevel & CPU_LOG_INT) {                    fprintf(logfile, "%s: restart the CPU\n", __func__);                }#endif                env->halted = 0;            }            break;        case PPC40x_INPUT_DEBUG:            /* Level sensitive - active high */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: set the debug pin state to %d\n",                        __func__, level);            }#endif            ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);            break;        default:            /* Unknown pin - do nothing */#if defined(PPC_DEBUG_IRQ)            if (loglevel & CPU_LOG_INT) {                fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);            }#endif            return;        }        if (level)            env->irq_input_state |= 1 << pin;        else            env->irq_input_state &= ~(1 << pin);    }}void ppc40x_irq_init (CPUState *env){    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq, env, PPC40x_INPUT_NB);	}/*****************************************************************************//* PowerPC time base and decrementer emulation */struct ppc_tb_t {//debugger    /* Time base management */    int64_t  tb_offset;    /* Compensation                    */    int64_t  atb_offset;   /* Compensation                    */    uint32_t tb_freq;      /* TB frequency                    */    /* Decrementer management */    uint64_t decr_next;    /* Tick for next decr interrupt    */		int decrement;//debugger for clock,	    uint32_t decr_freq;    /* decrementer frequency           */    struct QEMUTimer *decr_timer;    /* Hypervisor decrementer management */    uint64_t hdecr_next;    /* Tick for next hdecr interrupt  */    struct QEMUTimer *hdecr_timer;    uint64_t purr_load;    uint64_t purr_start;    void *opaque;};static always_inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env, uint64_t vmclk,                                              int64_t tb_offset){    /* TB time in tb periods */    return muldiv64(vmclk, tb_env->tb_freq, ticks_per_sec) + tb_offset;}uint32_t cpu_ppc_load_tbl (CPUState *env){    ppc_tb_t *tb_env = env->tb_env;    uint64_t tb;    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);#if defined(PPC_DEBUG_TB)    if (loglevel != 0) {        fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb);    }#endif    return tb & 0xFFFFFFFF;}static always_inline uint32_t _cpu_ppc_load_tbu (CPUState *env){    ppc_tb_t *tb_env = env->tb_env;    uint64_t tb;    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);#if defined(PPC_DEBUG_TB)    if (loglevel != 0) {        fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb);    }#endif    return tb >> 32;

⌨️ 快捷键说明

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