Annotation of qemu/target-lm32/helper.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  LatticeMico32 helper routines.
        !             3:  *
        !             4:  *  Copyright (c) 2010 Michael Walle <[email protected]>
        !             5:  *
        !             6:  * This library is free software; you can redistribute it and/or
        !             7:  * modify it under the terms of the GNU Lesser General Public
        !             8:  * License as published by the Free Software Foundation; either
        !             9:  * version 2 of the License, or (at your option) any later version.
        !            10:  *
        !            11:  * This library 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 GNU
        !            14:  * Lesser General Public License for more details.
        !            15:  *
        !            16:  * You should have received a copy of the GNU Lesser General Public
        !            17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
        !            18:  */
        !            19: 
        !            20: #include <stdio.h>
        !            21: #include <string.h>
        !            22: #include <assert.h>
        !            23: 
        !            24: #include "config.h"
        !            25: #include "cpu.h"
        !            26: #include "host-utils.h"
        !            27: 
        !            28: int cpu_lm32_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
        !            29:                                int mmu_idx, int is_softmmu)
        !            30: {
        !            31:     int prot;
        !            32: 
        !            33:     address &= TARGET_PAGE_MASK;
        !            34:     prot = PAGE_BITS;
        !            35:     if (env->flags & LM32_FLAG_IGNORE_MSB) {
        !            36:         tlb_set_page(env, address, address & 0x7fffffff, prot, mmu_idx,
        !            37:                 TARGET_PAGE_SIZE);
        !            38:     } else {
        !            39:         tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
        !            40:     }
        !            41: 
        !            42:     return 0;
        !            43: }
        !            44: 
        !            45: target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
        !            46: {
        !            47:     return addr & TARGET_PAGE_MASK;
        !            48: }
        !            49: 
        !            50: void do_interrupt(CPUState *env)
        !            51: {
        !            52:     qemu_log_mask(CPU_LOG_INT,
        !            53:             "exception at pc=%x type=%x\n", env->pc, env->exception_index);
        !            54: 
        !            55:     switch (env->exception_index) {
        !            56:     case EXCP_INSN_BUS_ERROR:
        !            57:     case EXCP_DATA_BUS_ERROR:
        !            58:     case EXCP_DIVIDE_BY_ZERO:
        !            59:     case EXCP_IRQ:
        !            60:     case EXCP_SYSTEMCALL:
        !            61:         /* non-debug exceptions */
        !            62:         env->regs[R_EA] = env->pc;
        !            63:         env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;
        !            64:         env->ie &= ~IE_IE;
        !            65:         if (env->dc & DC_RE) {
        !            66:             env->pc = env->deba + (env->exception_index * 32);
        !            67:         } else {
        !            68:             env->pc = env->eba + (env->exception_index * 32);
        !            69:         }
        !            70:         log_cpu_state_mask(CPU_LOG_INT, env, 0);
        !            71:         break;
        !            72:     case EXCP_BREAKPOINT:
        !            73:     case EXCP_WATCHPOINT:
        !            74:         /* debug exceptions */
        !            75:         env->regs[R_BA] = env->pc;
        !            76:         env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
        !            77:         env->ie &= ~IE_IE;
        !            78:         env->pc = env->deba + (env->exception_index * 32);
        !            79:         log_cpu_state_mask(CPU_LOG_INT, env, 0);
        !            80:         break;
        !            81:     default:
        !            82:         cpu_abort(env, "unhandled exception type=%d\n",
        !            83:                   env->exception_index);
        !            84:         break;
        !            85:     }
        !            86: }
        !            87: 
        !            88: typedef struct {
        !            89:     const char *name;
        !            90:     uint32_t revision;
        !            91:     uint8_t num_interrupts;
        !            92:     uint8_t num_breakpoints;
        !            93:     uint8_t num_watchpoints;
        !            94:     uint32_t features;
        !            95: } LM32Def;
        !            96: 
        !            97: static const LM32Def lm32_defs[] = {
        !            98:     {
        !            99:         .name = "lm32-basic",
        !           100:         .revision = 3,
        !           101:         .num_interrupts = 32,
        !           102:         .num_breakpoints = 4,
        !           103:         .num_watchpoints = 4,
        !           104:         .features = (LM32_FEATURE_SHIFT
        !           105:                      | LM32_FEATURE_SIGN_EXTEND
        !           106:                      | LM32_FEATURE_CYCLE_COUNT),
        !           107:     },
        !           108:     {
        !           109:         .name = "lm32-standard",
        !           110:         .revision = 3,
        !           111:         .num_interrupts = 32,
        !           112:         .num_breakpoints = 4,
        !           113:         .num_watchpoints = 4,
        !           114:         .features = (LM32_FEATURE_MULTIPLY
        !           115:                      | LM32_FEATURE_DIVIDE
        !           116:                      | LM32_FEATURE_SHIFT
        !           117:                      | LM32_FEATURE_SIGN_EXTEND
        !           118:                      | LM32_FEATURE_I_CACHE
        !           119:                      | LM32_FEATURE_CYCLE_COUNT),
        !           120:     },
        !           121:     {
        !           122:         .name = "lm32-full",
        !           123:         .revision = 3,
        !           124:         .num_interrupts = 32,
        !           125:         .num_breakpoints = 4,
        !           126:         .num_watchpoints = 4,
        !           127:         .features = (LM32_FEATURE_MULTIPLY
        !           128:                      | LM32_FEATURE_DIVIDE
        !           129:                      | LM32_FEATURE_SHIFT
        !           130:                      | LM32_FEATURE_SIGN_EXTEND
        !           131:                      | LM32_FEATURE_I_CACHE
        !           132:                      | LM32_FEATURE_D_CACHE
        !           133:                      | LM32_FEATURE_CYCLE_COUNT),
        !           134:     }
        !           135: };
        !           136: 
        !           137: void cpu_lm32_list(FILE *f, fprintf_function cpu_fprintf)
        !           138: {
        !           139:     int i;
        !           140: 
        !           141:     cpu_fprintf(f, "Available CPUs:\n");
        !           142:     for (i = 0; i < ARRAY_SIZE(lm32_defs); i++) {
        !           143:         cpu_fprintf(f, "  %s\n", lm32_defs[i].name);
        !           144:     }
        !           145: }
        !           146: 
        !           147: static const LM32Def *cpu_lm32_find_by_name(const char *name)
        !           148: {
        !           149:     int i;
        !           150: 
        !           151:     for (i = 0; i < ARRAY_SIZE(lm32_defs); i++) {
        !           152:         if (strcasecmp(name, lm32_defs[i].name) == 0) {
        !           153:             return &lm32_defs[i];
        !           154:         }
        !           155:     }
        !           156: 
        !           157:     return NULL;
        !           158: }
        !           159: 
        !           160: static uint32_t cfg_by_def(const LM32Def *def)
        !           161: {
        !           162:     uint32_t cfg = 0;
        !           163: 
        !           164:     if (def->features & LM32_FEATURE_MULTIPLY) {
        !           165:         cfg |= CFG_M;
        !           166:     }
        !           167: 
        !           168:     if (def->features & LM32_FEATURE_DIVIDE) {
        !           169:         cfg |= CFG_D;
        !           170:     }
        !           171: 
        !           172:     if (def->features & LM32_FEATURE_SHIFT) {
        !           173:         cfg |= CFG_S;
        !           174:     }
        !           175: 
        !           176:     if (def->features & LM32_FEATURE_SIGN_EXTEND) {
        !           177:         cfg |= CFG_X;
        !           178:     }
        !           179: 
        !           180:     if (def->features & LM32_FEATURE_I_CACHE) {
        !           181:         cfg |= CFG_IC;
        !           182:     }
        !           183: 
        !           184:     if (def->features & LM32_FEATURE_D_CACHE) {
        !           185:         cfg |= CFG_DC;
        !           186:     }
        !           187: 
        !           188:     if (def->features & LM32_FEATURE_CYCLE_COUNT) {
        !           189:         cfg |= CFG_CC;
        !           190:     }
        !           191: 
        !           192:     cfg |= (def->num_interrupts << CFG_INT_SHIFT);
        !           193:     cfg |= (def->num_breakpoints << CFG_BP_SHIFT);
        !           194:     cfg |= (def->num_watchpoints << CFG_WP_SHIFT);
        !           195:     cfg |= (def->revision << CFG_REV_SHIFT);
        !           196: 
        !           197:     return cfg;
        !           198: }
        !           199: 
        !           200: CPUState *cpu_lm32_init(const char *cpu_model)
        !           201: {
        !           202:     CPUState *env;
        !           203:     const LM32Def *def;
        !           204:     static int tcg_initialized;
        !           205: 
        !           206:     def = cpu_lm32_find_by_name(cpu_model);
        !           207:     if (!def) {
        !           208:         return NULL;
        !           209:     }
        !           210: 
        !           211:     env = qemu_mallocz(sizeof(CPUState));
        !           212: 
        !           213:     env->features = def->features;
        !           214:     env->num_bps = def->num_breakpoints;
        !           215:     env->num_wps = def->num_watchpoints;
        !           216:     env->cfg = cfg_by_def(def);
        !           217:     env->flags = 0;
        !           218: 
        !           219:     cpu_exec_init(env);
        !           220:     cpu_reset(env);
        !           221: 
        !           222:     if (!tcg_initialized) {
        !           223:         tcg_initialized = 1;
        !           224:         lm32_translate_init();
        !           225:     }
        !           226: 
        !           227:     return env;
        !           228: }
        !           229: 
        !           230: /* Some soc ignores the MSB on the address bus. Thus creating a shadow memory
        !           231:  * area. As a general rule, 0x00000000-0x7fffffff is cached, whereas
        !           232:  * 0x80000000-0xffffffff is not cached and used to access IO devices. */
        !           233: void cpu_lm32_set_phys_msb_ignore(CPUState *env, int value)
        !           234: {
        !           235:     if (value) {
        !           236:         env->flags |= LM32_FLAG_IGNORE_MSB;
        !           237:     } else {
        !           238:         env->flags &= ~LM32_FLAG_IGNORE_MSB;
        !           239:     }
        !           240: }
        !           241: 
        !           242: void cpu_reset(CPUState *env)
        !           243: {
        !           244:     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
        !           245:         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
        !           246:         log_cpu_state(env, 0);
        !           247:     }
        !           248: 
        !           249:     tlb_flush(env, 1);
        !           250: 
        !           251:     /* reset cpu state */
        !           252:     memset(env, 0, offsetof(CPULM32State, breakpoints));
        !           253: }
        !           254: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.