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

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 "cpu.h"
                     21: #include "host-utils.h"
                     22: 
1.1.1.3 ! root       23: int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
1.1.1.2   root       24:                               int mmu_idx)
1.1       root       25: {
                     26:     int prot;
                     27: 
                     28:     address &= TARGET_PAGE_MASK;
                     29:     prot = PAGE_BITS;
                     30:     if (env->flags & LM32_FLAG_IGNORE_MSB) {
                     31:         tlb_set_page(env, address, address & 0x7fffffff, prot, mmu_idx,
                     32:                 TARGET_PAGE_SIZE);
                     33:     } else {
                     34:         tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
                     35:     }
                     36: 
                     37:     return 0;
                     38: }
                     39: 
1.1.1.3 ! root       40: target_phys_addr_t cpu_get_phys_page_debug(CPULM32State *env, target_ulong addr)
1.1       root       41: {
                     42:     return addr & TARGET_PAGE_MASK;
                     43: }
                     44: 
1.1.1.3 ! root       45: void do_interrupt(CPULM32State *env)
1.1       root       46: {
                     47:     qemu_log_mask(CPU_LOG_INT,
                     48:             "exception at pc=%x type=%x\n", env->pc, env->exception_index);
                     49: 
                     50:     switch (env->exception_index) {
                     51:     case EXCP_INSN_BUS_ERROR:
                     52:     case EXCP_DATA_BUS_ERROR:
                     53:     case EXCP_DIVIDE_BY_ZERO:
                     54:     case EXCP_IRQ:
                     55:     case EXCP_SYSTEMCALL:
                     56:         /* non-debug exceptions */
                     57:         env->regs[R_EA] = env->pc;
                     58:         env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;
                     59:         env->ie &= ~IE_IE;
                     60:         if (env->dc & DC_RE) {
                     61:             env->pc = env->deba + (env->exception_index * 32);
                     62:         } else {
                     63:             env->pc = env->eba + (env->exception_index * 32);
                     64:         }
                     65:         log_cpu_state_mask(CPU_LOG_INT, env, 0);
                     66:         break;
                     67:     case EXCP_BREAKPOINT:
                     68:     case EXCP_WATCHPOINT:
                     69:         /* debug exceptions */
                     70:         env->regs[R_BA] = env->pc;
                     71:         env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
                     72:         env->ie &= ~IE_IE;
                     73:         env->pc = env->deba + (env->exception_index * 32);
                     74:         log_cpu_state_mask(CPU_LOG_INT, env, 0);
                     75:         break;
                     76:     default:
                     77:         cpu_abort(env, "unhandled exception type=%d\n",
                     78:                   env->exception_index);
                     79:         break;
                     80:     }
                     81: }
                     82: 
                     83: typedef struct {
                     84:     const char *name;
                     85:     uint32_t revision;
                     86:     uint8_t num_interrupts;
                     87:     uint8_t num_breakpoints;
                     88:     uint8_t num_watchpoints;
                     89:     uint32_t features;
                     90: } LM32Def;
                     91: 
                     92: static const LM32Def lm32_defs[] = {
                     93:     {
                     94:         .name = "lm32-basic",
                     95:         .revision = 3,
                     96:         .num_interrupts = 32,
                     97:         .num_breakpoints = 4,
                     98:         .num_watchpoints = 4,
                     99:         .features = (LM32_FEATURE_SHIFT
                    100:                      | LM32_FEATURE_SIGN_EXTEND
                    101:                      | LM32_FEATURE_CYCLE_COUNT),
                    102:     },
                    103:     {
                    104:         .name = "lm32-standard",
                    105:         .revision = 3,
                    106:         .num_interrupts = 32,
                    107:         .num_breakpoints = 4,
                    108:         .num_watchpoints = 4,
                    109:         .features = (LM32_FEATURE_MULTIPLY
                    110:                      | LM32_FEATURE_DIVIDE
                    111:                      | LM32_FEATURE_SHIFT
                    112:                      | LM32_FEATURE_SIGN_EXTEND
                    113:                      | LM32_FEATURE_I_CACHE
                    114:                      | LM32_FEATURE_CYCLE_COUNT),
                    115:     },
                    116:     {
                    117:         .name = "lm32-full",
                    118:         .revision = 3,
                    119:         .num_interrupts = 32,
                    120:         .num_breakpoints = 4,
                    121:         .num_watchpoints = 4,
                    122:         .features = (LM32_FEATURE_MULTIPLY
                    123:                      | LM32_FEATURE_DIVIDE
                    124:                      | LM32_FEATURE_SHIFT
                    125:                      | LM32_FEATURE_SIGN_EXTEND
                    126:                      | LM32_FEATURE_I_CACHE
                    127:                      | LM32_FEATURE_D_CACHE
                    128:                      | LM32_FEATURE_CYCLE_COUNT),
                    129:     }
                    130: };
                    131: 
                    132: void cpu_lm32_list(FILE *f, fprintf_function cpu_fprintf)
                    133: {
                    134:     int i;
                    135: 
                    136:     cpu_fprintf(f, "Available CPUs:\n");
                    137:     for (i = 0; i < ARRAY_SIZE(lm32_defs); i++) {
                    138:         cpu_fprintf(f, "  %s\n", lm32_defs[i].name);
                    139:     }
                    140: }
                    141: 
                    142: static const LM32Def *cpu_lm32_find_by_name(const char *name)
                    143: {
                    144:     int i;
                    145: 
                    146:     for (i = 0; i < ARRAY_SIZE(lm32_defs); i++) {
                    147:         if (strcasecmp(name, lm32_defs[i].name) == 0) {
                    148:             return &lm32_defs[i];
                    149:         }
                    150:     }
                    151: 
                    152:     return NULL;
                    153: }
                    154: 
                    155: static uint32_t cfg_by_def(const LM32Def *def)
                    156: {
                    157:     uint32_t cfg = 0;
                    158: 
                    159:     if (def->features & LM32_FEATURE_MULTIPLY) {
                    160:         cfg |= CFG_M;
                    161:     }
                    162: 
                    163:     if (def->features & LM32_FEATURE_DIVIDE) {
                    164:         cfg |= CFG_D;
                    165:     }
                    166: 
                    167:     if (def->features & LM32_FEATURE_SHIFT) {
                    168:         cfg |= CFG_S;
                    169:     }
                    170: 
                    171:     if (def->features & LM32_FEATURE_SIGN_EXTEND) {
                    172:         cfg |= CFG_X;
                    173:     }
                    174: 
                    175:     if (def->features & LM32_FEATURE_I_CACHE) {
                    176:         cfg |= CFG_IC;
                    177:     }
                    178: 
                    179:     if (def->features & LM32_FEATURE_D_CACHE) {
                    180:         cfg |= CFG_DC;
                    181:     }
                    182: 
                    183:     if (def->features & LM32_FEATURE_CYCLE_COUNT) {
                    184:         cfg |= CFG_CC;
                    185:     }
                    186: 
                    187:     cfg |= (def->num_interrupts << CFG_INT_SHIFT);
                    188:     cfg |= (def->num_breakpoints << CFG_BP_SHIFT);
                    189:     cfg |= (def->num_watchpoints << CFG_WP_SHIFT);
                    190:     cfg |= (def->revision << CFG_REV_SHIFT);
                    191: 
                    192:     return cfg;
                    193: }
                    194: 
1.1.1.3 ! root      195: CPULM32State *cpu_lm32_init(const char *cpu_model)
1.1       root      196: {
1.1.1.3 ! root      197:     LM32CPU *cpu;
        !           198:     CPULM32State *env;
1.1       root      199:     const LM32Def *def;
                    200:     static int tcg_initialized;
                    201: 
                    202:     def = cpu_lm32_find_by_name(cpu_model);
                    203:     if (!def) {
                    204:         return NULL;
                    205:     }
                    206: 
1.1.1.3 ! root      207:     cpu = LM32_CPU(object_new(TYPE_LM32_CPU));
        !           208:     env = &cpu->env;
1.1       root      209: 
                    210:     env->features = def->features;
                    211:     env->num_bps = def->num_breakpoints;
                    212:     env->num_wps = def->num_watchpoints;
                    213:     env->cfg = cfg_by_def(def);
                    214: 
1.1.1.2   root      215:     qemu_init_vcpu(env);
1.1       root      216: 
1.1.1.3 ! root      217:     if (tcg_enabled() && !tcg_initialized) {
1.1       root      218:         tcg_initialized = 1;
                    219:         lm32_translate_init();
                    220:     }
                    221: 
                    222:     return env;
                    223: }
                    224: 
                    225: /* Some soc ignores the MSB on the address bus. Thus creating a shadow memory
                    226:  * area. As a general rule, 0x00000000-0x7fffffff is cached, whereas
                    227:  * 0x80000000-0xffffffff is not cached and used to access IO devices. */
1.1.1.3 ! root      228: void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value)
1.1       root      229: {
                    230:     if (value) {
                    231:         env->flags |= LM32_FLAG_IGNORE_MSB;
                    232:     } else {
                    233:         env->flags &= ~LM32_FLAG_IGNORE_MSB;
                    234:     }
                    235: }
                    236: 
1.1.1.3 ! root      237: void cpu_state_reset(CPULM32State *env)
1.1       root      238: {
1.1.1.3 ! root      239:     cpu_reset(ENV_GET_CPU(env));
1.1       root      240: }
                    241: 

unix.superglobalmegacorp.com

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