Revision 777dc784 target-arm/helper.c
b/target-arm/helper.c | ||
---|---|---|
46 | 46 |
static uint32_t arm1176_cp15_c0_c2[8] = |
47 | 47 |
{ 0x0140011, 0x12002111, 0x11231121, 0x01102131, 0x01141, 0, 0, 0 }; |
48 | 48 |
|
49 |
static uint32_t cpu_arm_find_by_name(const char *name); |
|
50 |
|
|
51 | 49 |
static inline void set_feature(CPUARMState *env, int feature) |
52 | 50 |
{ |
53 | 51 |
env->features |= 1u << feature; |
... | ... | |
55 | 53 |
|
56 | 54 |
static void cpu_reset_model_id(CPUARMState *env, uint32_t id) |
57 | 55 |
{ |
58 |
env->cp15.c0_cpuid = id; |
|
59 | 56 |
switch (id) { |
60 | 57 |
case ARM_CPUID_ARM926: |
61 | 58 |
set_feature(env, ARM_FEATURE_V5); |
... | ... | |
201 | 198 |
case ARM_CPUID_TI925T: |
202 | 199 |
set_feature(env, ARM_FEATURE_V4T); |
203 | 200 |
set_feature(env, ARM_FEATURE_OMAPCP); |
204 |
env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring. */ |
|
205 | 201 |
env->cp15.c0_cachetype = 0x5109149; |
206 | 202 |
env->cp15.c1_sys = 0x00000070; |
207 | 203 |
env->cp15.c15_i_max = 0x000; |
... | ... | |
287 | 283 |
{ |
288 | 284 |
uint32_t id; |
289 | 285 |
uint32_t tmp = 0; |
286 |
ARMCPU *cpu = arm_env_get_cpu(env); |
|
290 | 287 |
|
291 | 288 |
if (qemu_loglevel_mask(CPU_LOG_RESET)) { |
292 | 289 |
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); |
293 | 290 |
log_cpu_state(env, 0); |
294 | 291 |
} |
295 | 292 |
|
296 |
id = env->cp15.c0_cpuid;
|
|
293 |
id = cpu->midr;
|
|
297 | 294 |
tmp = env->cp15.c15_config_base_address; |
298 | 295 |
memset(env, 0, offsetof(CPUARMState, breakpoints)); |
299 | 296 |
if (id) |
300 | 297 |
cpu_reset_model_id(env, id); |
301 | 298 |
env->cp15.c15_config_base_address = tmp; |
299 |
env->cp15.c0_cpuid = cpu->midr; |
|
302 | 300 |
#if defined (CONFIG_USER_ONLY) |
303 | 301 |
env->uncached_cpsr = ARM_CPU_MODE_USR; |
304 | 302 |
/* For user mode we must enable access to coprocessors */ |
... | ... | |
407 | 405 |
{ |
408 | 406 |
ARMCPU *cpu; |
409 | 407 |
CPUARMState *env; |
410 |
uint32_t id; |
|
411 | 408 |
static int inited = 0; |
412 | 409 |
|
413 |
id = cpu_arm_find_by_name(cpu_model); |
|
414 |
if (id == 0) |
|
410 |
if (!object_class_by_name(cpu_model)) { |
|
415 | 411 |
return NULL; |
416 |
cpu = ARM_CPU(object_new(TYPE_ARM_CPU)); |
|
412 |
} |
|
413 |
cpu = ARM_CPU(object_new(cpu_model)); |
|
417 | 414 |
env = &cpu->env; |
418 |
cpu_exec_init(env); |
|
415 |
env->cpu_model_str = cpu_model; |
|
416 |
|
|
419 | 417 |
if (tcg_enabled() && !inited) { |
420 | 418 |
inited = 1; |
421 | 419 |
arm_translate_init(); |
422 | 420 |
} |
423 | 421 |
|
424 |
env->cpu_model_str = cpu_model; |
|
425 |
env->cp15.c0_cpuid = id; |
|
426 | 422 |
cpu_state_reset(env); |
427 | 423 |
if (arm_feature(env, ARM_FEATURE_NEON)) { |
428 | 424 |
gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, |
... | ... | |
438 | 434 |
return env; |
439 | 435 |
} |
440 | 436 |
|
441 |
struct arm_cpu_t { |
|
442 |
uint32_t id; |
|
443 |
const char *name; |
|
444 |
}; |
|
445 |
|
|
446 |
static const struct arm_cpu_t arm_cpu_names[] = { |
|
447 |
{ ARM_CPUID_ARM926, "arm926"}, |
|
448 |
{ ARM_CPUID_ARM946, "arm946"}, |
|
449 |
{ ARM_CPUID_ARM1026, "arm1026"}, |
|
450 |
{ ARM_CPUID_ARM1136, "arm1136"}, |
|
451 |
{ ARM_CPUID_ARM1136_R2, "arm1136-r2"}, |
|
452 |
{ ARM_CPUID_ARM1176, "arm1176"}, |
|
453 |
{ ARM_CPUID_ARM11MPCORE, "arm11mpcore"}, |
|
454 |
{ ARM_CPUID_CORTEXM3, "cortex-m3"}, |
|
455 |
{ ARM_CPUID_CORTEXA8, "cortex-a8"}, |
|
456 |
{ ARM_CPUID_CORTEXA9, "cortex-a9"}, |
|
457 |
{ ARM_CPUID_CORTEXA15, "cortex-a15" }, |
|
458 |
{ ARM_CPUID_TI925T, "ti925t" }, |
|
459 |
{ ARM_CPUID_PXA250, "pxa250" }, |
|
460 |
{ ARM_CPUID_SA1100, "sa1100" }, |
|
461 |
{ ARM_CPUID_SA1110, "sa1110" }, |
|
462 |
{ ARM_CPUID_PXA255, "pxa255" }, |
|
463 |
{ ARM_CPUID_PXA260, "pxa260" }, |
|
464 |
{ ARM_CPUID_PXA261, "pxa261" }, |
|
465 |
{ ARM_CPUID_PXA262, "pxa262" }, |
|
466 |
{ ARM_CPUID_PXA270, "pxa270" }, |
|
467 |
{ ARM_CPUID_PXA270_A0, "pxa270-a0" }, |
|
468 |
{ ARM_CPUID_PXA270_A1, "pxa270-a1" }, |
|
469 |
{ ARM_CPUID_PXA270_B0, "pxa270-b0" }, |
|
470 |
{ ARM_CPUID_PXA270_B1, "pxa270-b1" }, |
|
471 |
{ ARM_CPUID_PXA270_C0, "pxa270-c0" }, |
|
472 |
{ ARM_CPUID_PXA270_C5, "pxa270-c5" }, |
|
473 |
{ ARM_CPUID_ANY, "any"}, |
|
474 |
{ 0, NULL} |
|
475 |
}; |
|
437 |
typedef struct ARMCPUListState { |
|
438 |
fprintf_function cpu_fprintf; |
|
439 |
FILE *file; |
|
440 |
} ARMCPUListState; |
|
476 | 441 |
|
477 |
void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf) |
|
442 |
/* Sort alphabetically by type name, except for "any". */ |
|
443 |
static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b) |
|
478 | 444 |
{ |
479 |
int i; |
|
445 |
ObjectClass *class_a = (ObjectClass *)a; |
|
446 |
ObjectClass *class_b = (ObjectClass *)b; |
|
447 |
const char *name_a, *name_b; |
|
480 | 448 |
|
481 |
(*cpu_fprintf)(f, "Available CPUs:\n"); |
|
482 |
for (i = 0; arm_cpu_names[i].name; i++) { |
|
483 |
(*cpu_fprintf)(f, " %s\n", arm_cpu_names[i].name); |
|
449 |
name_a = object_class_get_name(class_a); |
|
450 |
name_b = object_class_get_name(class_b); |
|
451 |
if (strcmp(name_a, "any") == 0) { |
|
452 |
return 1; |
|
453 |
} else if (strcmp(name_b, "any") == 0) { |
|
454 |
return -1; |
|
455 |
} else { |
|
456 |
return strcmp(name_a, name_b); |
|
484 | 457 |
} |
485 | 458 |
} |
486 | 459 |
|
487 |
/* return 0 if not found */ |
|
488 |
static uint32_t cpu_arm_find_by_name(const char *name) |
|
460 |
static void arm_cpu_list_entry(gpointer data, gpointer user_data) |
|
489 | 461 |
{ |
490 |
int i;
|
|
491 |
uint32_t id;
|
|
462 |
ObjectClass *oc = data;
|
|
463 |
ARMCPUListState *s = user_data;
|
|
492 | 464 |
|
493 |
id = 0; |
|
494 |
for (i = 0; arm_cpu_names[i].name; i++) { |
|
495 |
if (strcmp(name, arm_cpu_names[i].name) == 0) { |
|
496 |
id = arm_cpu_names[i].id; |
|
497 |
break; |
|
498 |
} |
|
499 |
} |
|
500 |
return id; |
|
465 |
(*s->cpu_fprintf)(s->file, " %s\n", |
|
466 |
object_class_get_name(oc)); |
|
467 |
} |
|
468 |
|
|
469 |
void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf) |
|
470 |
{ |
|
471 |
ARMCPUListState s = { |
|
472 |
.file = f, |
|
473 |
.cpu_fprintf = cpu_fprintf, |
|
474 |
}; |
|
475 |
GSList *list; |
|
476 |
|
|
477 |
list = object_class_get_list(TYPE_ARM_CPU, false); |
|
478 |
list = g_slist_sort(list, arm_cpu_list_compare); |
|
479 |
(*cpu_fprintf)(f, "Available CPUs:\n"); |
|
480 |
g_slist_foreach(list, arm_cpu_list_entry, &s); |
|
481 |
g_slist_free(list); |
|
501 | 482 |
} |
502 | 483 |
|
503 | 484 |
static int bad_mode_switch(CPUARMState *env, int mode) |
Also available in: Unified diff