From 85215d419b17aeedbfe93ff8d739b27937f72739 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Sun, 15 Apr 2012 07:36:49 +0000 Subject: [PATCH 01/27] qtest: add register fuzzing to RTC test Reviewed-by: Anthony Liguori Signed-off-by: Blue Swirl --- tests/rtc-test.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/rtc-test.c b/tests/rtc-test.c index 983a980bab..f23ac3a6cf 100644 --- a/tests/rtc-test.c +++ b/tests/rtc-test.c @@ -240,6 +240,22 @@ static void alarm_time(void) g_assert(cmos_read(RTC_REG_C) == 0); } +/* success if no crash or abort */ +static void fuzz_registers(void) +{ + unsigned int i; + + for (i = 0; i < 1000; i++) { + uint8_t reg, val; + + reg = (uint8_t)g_test_rand_int_range(0, 16); + val = (uint8_t)g_test_rand_int_range(0, 256); + + cmos_write(reg, val); + cmos_read(reg); + } +} + int main(int argc, char **argv) { QTestState *s = NULL; @@ -253,6 +269,7 @@ int main(int argc, char **argv) qtest_add_func("/rtc/bcd/check-time", bcd_check_time); qtest_add_func("/rtc/dec/check-time", dec_check_time); qtest_add_func("/rtc/alarm-time", alarm_time); + qtest_add_func("/rtc/fuzz-registers", fuzz_registers); ret = g_test_run(); if (s) { From e776bffb53973619e93e805fa441bd5f3d999e27 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Thu, 19 Apr 2012 18:52:35 +0000 Subject: [PATCH 02/27] qtest: add dummy functions for user emulators Allow qtest to be used also in files used for user emulators by introducing dummy functions. Signed-off-by: Blue Swirl --- qtest.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/qtest.h b/qtest.h index 1478343ff0..723a4f9536 100644 --- a/qtest.h +++ b/qtest.h @@ -16,6 +16,7 @@ #include "qemu-common.h" +#if !defined(CONFIG_USER_ONLY) extern int qtest_allowed; extern const char *qtest_chrdev; extern const char *qtest_log; @@ -31,5 +32,22 @@ static inline int qtest_available(void) } int qtest_init(void); +#else +static inline bool qtest_enabled(void) +{ + return false; +} + +static inline int qtest_available(void) +{ + return 0; +} + +static inline int qtest_init(void) +{ + return 0; +} + +#endif #endif From 90449c388711c3defdc76da490926d1eca177b06 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Thu, 19 Apr 2012 18:33:05 +0000 Subject: [PATCH 03/27] sparc: fix qtest Initialize TCG only when enabled. Signed-off-by: Blue Swirl --- target-sparc/cpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 24f90f1ded..7ac6bdb058 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -119,7 +119,9 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model) cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU)); env = &cpu->env; - gen_intermediate_code_init(env); + if (tcg_enabled()) { + gen_intermediate_code_init(env); + } if (cpu_sparc_register(env, cpu_model) < 0) { object_delete(OBJECT(cpu)); From d1157ca418b9426be5e1857eca8142966397a32b Mon Sep 17 00:00:00 2001 From: Oskar Andero Date: Fri, 20 Apr 2012 15:38:52 +0000 Subject: [PATCH 04/27] realview: break out versatile i2c controller code The versatile i2c controller implementation was separated to its own file called versatile_i2c.c. This is done as a preparation for adding i2c support to the versatilepb board. Signed-off-by: Oskar Andero Signed-off-by: Peter Maydell --- Makefile.target | 1 + hw/realview.c | 83 +---------------------------------- hw/versatile_i2c.c | 105 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 81 deletions(-) create mode 100644 hw/versatile_i2c.c diff --git a/Makefile.target b/Makefile.target index 84951a09ec..b6a9330b90 100644 --- a/Makefile.target +++ b/Makefile.target @@ -364,6 +364,7 @@ endif obj-arm-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o obj-arm-y += versatile_pci.o +obj-arm-y += versatile_i2c.o obj-arm-y += cadence_uart.o obj-arm-y += cadence_ttc.o obj-arm-y += cadence_gem.o diff --git a/hw/realview.c b/hw/realview.c index cf55204c96..ecf470179a 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -15,91 +15,13 @@ #include "net.h" #include "sysemu.h" #include "boards.h" -#include "bitbang_i2c.h" +#include "i2c.h" #include "blockdev.h" #include "exec-memory.h" #define SMP_BOOT_ADDR 0xe0000000 #define SMP_BOOTREG_ADDR 0x10000030 -typedef struct { - SysBusDevice busdev; - MemoryRegion iomem; - bitbang_i2c_interface *bitbang; - int out; - int in; -} RealViewI2CState; - -static uint64_t realview_i2c_read(void *opaque, target_phys_addr_t offset, - unsigned size) -{ - RealViewI2CState *s = (RealViewI2CState *)opaque; - - if (offset == 0) { - return (s->out & 1) | (s->in << 1); - } else { - hw_error("realview_i2c_read: Bad offset 0x%x\n", (int)offset); - return -1; - } -} - -static void realview_i2c_write(void *opaque, target_phys_addr_t offset, - uint64_t value, unsigned size) -{ - RealViewI2CState *s = (RealViewI2CState *)opaque; - - switch (offset) { - case 0: - s->out |= value & 3; - break; - case 4: - s->out &= ~value; - break; - default: - hw_error("realview_i2c_write: Bad offset 0x%x\n", (int)offset); - } - bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0); - s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0); -} - -static const MemoryRegionOps realview_i2c_ops = { - .read = realview_i2c_read, - .write = realview_i2c_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static int realview_i2c_init(SysBusDevice *dev) -{ - RealViewI2CState *s = FROM_SYSBUS(RealViewI2CState, dev); - i2c_bus *bus; - - bus = i2c_init_bus(&dev->qdev, "i2c"); - s->bitbang = bitbang_i2c_init(bus); - memory_region_init_io(&s->iomem, &realview_i2c_ops, s, - "realview-i2c", 0x1000); - sysbus_init_mmio(dev, &s->iomem); - return 0; -} - -static void realview_i2c_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = realview_i2c_init; -} - -static TypeInfo realview_i2c_info = { - .name = "realview_i2c", - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(RealViewI2CState), - .class_init = realview_i2c_class_init, -}; - -static void realview_register_types(void) -{ - type_register_static(&realview_i2c_info); -} - /* Board init. */ static struct arm_boot_info realview_binfo = { @@ -328,7 +250,7 @@ static void realview_init(ram_addr_t ram_size, } } - dev = sysbus_create_simple("realview_i2c", 0x10002000, NULL); + dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); i2c_create_slave(i2c, "ds1338", 0x68); @@ -492,4 +414,3 @@ static void realview_machine_init(void) } machine_init(realview_machine_init); -type_init(realview_register_types) diff --git a/hw/versatile_i2c.c b/hw/versatile_i2c.c new file mode 100644 index 0000000000..88f530aefc --- /dev/null +++ b/hw/versatile_i2c.c @@ -0,0 +1,105 @@ +/* + * ARM Versatile I2C controller + * + * Copyright (c) 2006-2007 CodeSourcery. + * Copyright (c) 2012 Oskar Andero + * + * This file is derived from hw/realview.c by Paul Brook + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include "sysbus.h" +#include "bitbang_i2c.h" + +typedef struct { + SysBusDevice busdev; + MemoryRegion iomem; + bitbang_i2c_interface *bitbang; + int out; + int in; +} VersatileI2CState; + +static uint64_t versatile_i2c_read(void *opaque, target_phys_addr_t offset, + unsigned size) +{ + VersatileI2CState *s = (VersatileI2CState *)opaque; + + if (offset == 0) { + return (s->out & 1) | (s->in << 1); + } else { + hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset); + return -1; + } +} + +static void versatile_i2c_write(void *opaque, target_phys_addr_t offset, + uint64_t value, unsigned size) +{ + VersatileI2CState *s = (VersatileI2CState *)opaque; + + switch (offset) { + case 0: + s->out |= value & 3; + break; + case 4: + s->out &= ~value; + break; + default: + hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset); + } + bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0); + s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0); +} + +static const MemoryRegionOps versatile_i2c_ops = { + .read = versatile_i2c_read, + .write = versatile_i2c_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static int versatile_i2c_init(SysBusDevice *dev) +{ + VersatileI2CState *s = FROM_SYSBUS(VersatileI2CState, dev); + i2c_bus *bus; + + bus = i2c_init_bus(&dev->qdev, "i2c"); + s->bitbang = bitbang_i2c_init(bus); + memory_region_init_io(&s->iomem, &versatile_i2c_ops, s, + "versatile_i2c", 0x1000); + sysbus_init_mmio(dev, &s->iomem); + return 0; +} + +static void versatile_i2c_class_init(ObjectClass *klass, void *data) +{ + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = versatile_i2c_init; +} + +static const TypeInfo versatile_i2c_info = { + .name = "versatile_i2c", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(VersatileI2CState), + .class_init = versatile_i2c_class_init, +}; + +static void versatile_i2c_register_types(void) +{ + type_register_static(&versatile_i2c_info); +} + +type_init(versatile_i2c_register_types) From b1f05696ccc7ee2a04a541e373d098ad17568d13 Mon Sep 17 00:00:00 2001 From: Oskar Andero Date: Fri, 20 Apr 2012 15:38:52 +0000 Subject: [PATCH 05/27] versatilepb: add ds1338 rtc device Add ds1338 rtc attached on i2c. Signed-off-by: Oskar Andero Signed-off-by: Peter Maydell --- hw/versatilepb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index 25afb1eb31..d011554063 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -13,6 +13,7 @@ #include "net.h" #include "sysemu.h" #include "pci.h" +#include "i2c.h" #include "boards.h" #include "blockdev.h" #include "exec-memory.h" @@ -178,6 +179,7 @@ static void versatile_init(ram_addr_t ram_size, DeviceState *pl041; PCIBus *pci_bus; NICInfo *nd; + i2c_bus *i2c; int n; int done_smc = 0; @@ -268,6 +270,10 @@ static void versatile_init(ram_addr_t ram_size, /* Add PL031 Real Time Clock. */ sysbus_create_simple("pl031", 0x101e8000, pic[10]); + dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); + i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); + i2c_create_slave(i2c, "ds1338", 0x68); + /* Add PL041 AACI Interface to the LM4549 codec */ pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); From bdac1c1e958c3b0bb1d02e8fb8cc141306eea103 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 15:38:52 +0000 Subject: [PATCH 06/27] hw/arm_mptimer: Reset the qemu_timer at reset On reset of the mpcore timer/watchdog block we need to delete the qemu_timer in case it was running. Signed-off-by: Peter Maydell --- hw/arm_mptimer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c index df7fb4c9bd..fe43cbb5f1 100644 --- a/hw/arm_mptimer.c +++ b/hw/arm_mptimer.c @@ -228,6 +228,9 @@ static void timerblock_reset(timerblock *tb) tb->control = 0; tb->status = 0; tb->tick = 0; + if (tb->timer) { + qemu_del_timer(tb->timer); + } } static void arm_mptimer_reset(DeviceState *dev) From 964c695a54ceda3ac8c965542829d4e482e28de7 Mon Sep 17 00:00:00 2001 From: Eric Benard Date: Mon, 16 Apr 2012 05:02:47 +0000 Subject: [PATCH 07/27] versatiblepb: add NOR flash support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add support for the 64MB NOR CFI01 flash available at 0x34000000 on the versatilepb board http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/BBAJIHEC.html - tested with barebox bootloader Signed-off-by: Eric Bénard Signed-off-by: Peter Maydell --- hw/versatilepb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index d011554063..7c79c54d08 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -17,6 +17,11 @@ #include "boards.h" #include "blockdev.h" #include "exec-memory.h" +#include "flash.h" + +#define VERSATILE_FLASH_ADDR 0x34000000 +#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024) +#define VERSATILE_FLASH_SECT_SIZE (256 * 1024) /* Primary interrupt controller. */ @@ -182,6 +187,7 @@ static void versatile_init(ram_addr_t ram_size, i2c_bus *i2c; int n; int done_smc = 0; + DriveInfo *dinfo; if (!cpu_model) cpu_model = "arm926"; @@ -316,6 +322,16 @@ static void versatile_init(ram_addr_t ram_size, /* 0x101f2000 UART1. */ /* 0x101f3000 UART2. */ /* 0x101f4000 SSPI. */ + /* 0x34000000 NOR Flash */ + + dinfo = drive_get(IF_PFLASH, 0, 0); + if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash", + VERSATILE_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, + VERSATILE_FLASH_SECT_SIZE, + VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE, + 4, 0x0089, 0x0018, 0x0000, 0x0, 0)) { + fprintf(stderr, "qemu: Error registering flash memory.\n"); + } versatile_binfo.ram_size = ram_size; versatile_binfo.kernel_filename = kernel_filename; From f91837a7f173e0334539024e4d8ba10c19a78bb7 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Sun, 15 Apr 2012 11:45:18 +0000 Subject: [PATCH 08/27] qtest: add m48t59 tests for Sparc Add simple m48t59 qtests, enable test only for Sparc32 and Sparc64. On PPC, the device is behind PCI bus. Signed-off-by: Blue Swirl --- tests/Makefile | 3 + tests/m48t59-test.c | 259 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+) create mode 100644 tests/m48t59-test.c diff --git a/tests/Makefile b/tests/Makefile index baf1d70ee8..9988681293 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -20,6 +20,8 @@ check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh # really in libqtest, not in the testcases themselves. check-qtest-i386-y = tests/rtc-test check-qtest-x86_64-y = $(check-qtest-i386-y) +check-qtest-sparc-y = tests/m48t59-test$(EXESUF) +check-qtest-sparc64-y = tests/m48t59-test$(EXESUF) GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h @@ -64,6 +66,7 @@ tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi- tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) +tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y) # QTest rules diff --git a/tests/m48t59-test.c b/tests/m48t59-test.c new file mode 100644 index 0000000000..5179681ca5 --- /dev/null +++ b/tests/m48t59-test.c @@ -0,0 +1,259 @@ +/* + * QTest testcase for the M48T59 and M48T08 real-time clocks + * + * Based on MC146818 RTC test: + * Copyright IBM, Corp. 2012 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#include "libqtest.h" + +#include +#include +#include +#include +#include + +#define RTC_SECONDS 0x9 +#define RTC_MINUTES 0xa +#define RTC_HOURS 0xb + +#define RTC_DAY_OF_WEEK 0xc +#define RTC_DAY_OF_MONTH 0xd +#define RTC_MONTH 0xe +#define RTC_YEAR 0xf + +static uint32_t base; +static uint16_t reg_base = 0x1ff0; /* 0x7f0 for m48t02 */ +static int base_year; +static bool use_mmio; + +static uint8_t cmos_read_mmio(uint8_t reg) +{ + uint8_t data; + + memread(base + (uint32_t)reg_base + (uint32_t)reg, &data, 1); + return data; +} + +static void cmos_write_mmio(uint8_t reg, uint8_t val) +{ + uint8_t data = val; + + memwrite(base + (uint32_t)reg_base + (uint32_t)reg, &data, 1); +} + +static uint8_t cmos_read_ioio(uint8_t reg) +{ + outw(base + 0, reg_base + (uint16_t)reg); + return inb(base + 3); +} + +static void cmos_write_ioio(uint8_t reg, uint8_t val) +{ + outw(base + 0, reg_base + (uint16_t)reg); + outb(base + 3, val); +} + +static uint8_t cmos_read(uint8_t reg) +{ + if (use_mmio) { + return cmos_read_mmio(reg); + } else { + return cmos_read_ioio(reg); + } +} + +static void cmos_write(uint8_t reg, uint8_t val) +{ + if (use_mmio) { + cmos_write_mmio(reg, val); + } else { + cmos_write_ioio(reg, val); + } +} + +static int bcd2dec(int value) +{ + return (((value >> 4) & 0x0F) * 10) + (value & 0x0F); +} + +static int tm_cmp(struct tm *lhs, struct tm *rhs) +{ + time_t a, b; + struct tm d1, d2; + + memcpy(&d1, lhs, sizeof(d1)); + memcpy(&d2, rhs, sizeof(d2)); + + a = mktime(&d1); + b = mktime(&d2); + + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } + + return 0; +} + +#if 0 +static void print_tm(struct tm *tm) +{ + printf("%04d-%02d-%02d %02d:%02d:%02d %+02ld\n", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_gmtoff); +} +#endif + +static void cmos_get_date_time(struct tm *date) +{ + int sec, min, hour, mday, mon, year; + time_t ts; + struct tm dummy; + + sec = cmos_read(RTC_SECONDS); + min = cmos_read(RTC_MINUTES); + hour = cmos_read(RTC_HOURS); + mday = cmos_read(RTC_DAY_OF_MONTH); + mon = cmos_read(RTC_MONTH); + year = cmos_read(RTC_YEAR); + + sec = bcd2dec(sec); + min = bcd2dec(min); + hour = bcd2dec(hour); + mday = bcd2dec(mday); + mon = bcd2dec(mon); + year = bcd2dec(year); + + ts = time(NULL); + localtime_r(&ts, &dummy); + + date->tm_isdst = dummy.tm_isdst; + date->tm_sec = sec; + date->tm_min = min; + date->tm_hour = hour; + date->tm_mday = mday; + date->tm_mon = mon - 1; + date->tm_year = base_year + year - 1900; + date->tm_gmtoff = 0; + + ts = mktime(date); +} + +static void check_time(int wiggle) +{ + struct tm start, date[4], end; + struct tm *datep; + time_t ts; + + /* + * This check assumes a few things. First, we cannot guarantee that we get + * a consistent reading from the wall clock because we may hit an edge of + * the clock while reading. To work around this, we read four clock readings + * such that at least two of them should match. We need to assume that one + * reading is corrupt so we need four readings to ensure that we have at + * least two consecutive identical readings + * + * It's also possible that we'll cross an edge reading the host clock so + * simply check to make sure that the clock reading is within the period of + * when we expect it to be. + */ + + ts = time(NULL); + gmtime_r(&ts, &start); + + cmos_get_date_time(&date[0]); + cmos_get_date_time(&date[1]); + cmos_get_date_time(&date[2]); + cmos_get_date_time(&date[3]); + + ts = time(NULL); + gmtime_r(&ts, &end); + + if (tm_cmp(&date[0], &date[1]) == 0) { + datep = &date[0]; + } else if (tm_cmp(&date[1], &date[2]) == 0) { + datep = &date[1]; + } else if (tm_cmp(&date[2], &date[3]) == 0) { + datep = &date[2]; + } else { + g_assert_not_reached(); + } + + if (!(tm_cmp(&start, datep) <= 0 && tm_cmp(datep, &end) <= 0)) { + long t, s; + + start.tm_isdst = datep->tm_isdst; + + t = (long)mktime(datep); + s = (long)mktime(&start); + if (t < s) { + g_test_message("RTC is %ld second(s) behind wall-clock\n", (s - t)); + } else { + g_test_message("RTC is %ld second(s) ahead of wall-clock\n", (t - s)); + } + + g_assert_cmpint(ABS(t - s), <=, wiggle); + } +} + +static int wiggle = 2; + +static void bcd_check_time(void) +{ + if (strcmp(qtest_get_arch(), "sparc64") == 0) { + base = 0x74; + base_year = 1900; + use_mmio = false; + } else if (strcmp(qtest_get_arch(), "sparc") == 0) { + base = 0x71200000; + base_year = 1968; + use_mmio = true; + } else { /* PPC: need to map macio in PCI */ + g_assert_not_reached(); + } + check_time(wiggle); +} + +/* success if no crash or abort */ +static void fuzz_registers(void) +{ + unsigned int i; + + for (i = 0; i < 1000; i++) { + uint8_t reg, val; + + reg = (uint8_t)g_test_rand_int_range(0, 16); + val = (uint8_t)g_test_rand_int_range(0, 256); + + cmos_write(reg, val); + cmos_read(reg); + } +} + +int main(int argc, char **argv) +{ + QTestState *s = NULL; + int ret; + + g_test_init(&argc, &argv, NULL); + + s = qtest_start("-display none -rtc clock=vm"); + + qtest_add_func("/rtc/bcd/check-time", bcd_check_time); + qtest_add_func("/rtc/fuzz-registers", fuzz_registers); + ret = g_test_run(); + + if (s) { + qtest_quit(s); + } + + return ret; +} From b18b37f7c5bc96dabdb08bcfb699b339a76104bf Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 16 Apr 2012 01:47:06 +0400 Subject: [PATCH 09/27] target-xtensa: fix LOOPNEZ/LOOPGTZ translation Translation of LOOP instructions used to call LEND SR write handler to update LEND and invalidate relevant TBs. Now that LEND SR write handler ends TB, LOOPNEZ and LOOPGTZ generate wrong code (same as for simple LOOP). Fix it by calling wsr_lend helper directly. Signed-off-by: Max Filippov Signed-off-by: Blue Swirl --- target-xtensa/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 6900123983..521c0e6226 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -2278,7 +2278,7 @@ static void disas_xtensa_insn(DisasContext *dc) tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1); tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc); - gen_wsr_lend(dc, LEND, tmp); + gen_helper_wsr_lend(tmp); tcg_temp_free(tmp); if (BRI8_R > 8) { From 536a98d4d66444437e01ff2920df1a554df15efb Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 16 Apr 2012 01:47:07 +0400 Subject: [PATCH 10/27] target-xtensa: add tests for LOOPNEZ and LOOPGTZ Signed-off-by: Max Filippov Signed-off-by: Blue Swirl --- tests/tcg/xtensa/test_loop.S | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/tcg/xtensa/test_loop.S b/tests/tcg/xtensa/test_loop.S index 5cead47a27..1c240e8e9b 100644 --- a/tests/tcg/xtensa/test_loop.S +++ b/tests/tcg/xtensa/test_loop.S @@ -124,4 +124,40 @@ test lend_invalidation assert eqi, a2, 7 test_end +test loopnez + movi a2, 0 + movi a3, 5 + loopnez a3, 1f + addi a2, a2, 1 +1: + assert eqi, a2, 5 + + movi a2, 0 + movi a3, 0 + loopnez a3, 1f + test_fail +1: +test_end + +test loopgtz + movi a2, 0 + movi a3, 5 + loopgtz a3, 1f + addi a2, a2, 1 +1: + assert eqi, a2, 5 + + movi a2, 0 + movi a3, 0 + loopgtz a3, 1f + test_fail +1: + + movi a2, 0 + movi a3, 0x80000000 + loopgtz a3, 1f + test_fail +1: +test_end + test_suite_end From 0eb4fc817fa14347a381d018eb29f1eef2fb43e4 Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Tue, 20 Mar 2012 05:24:25 +0000 Subject: [PATCH 11/27] softfloat: make USE_SOFTFLOAT_STRUCT_TYPES compile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change makes it compile and return the same value than the #undef one. Signed-off-by: Juan Quintela Reviewed-by: Peter Maydell Acked-by: Andreas Färber Signed-off-by: Blue Swirl --- fpu/softfloat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index d37090ac53..9e1b5f9cab 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2219,7 +2219,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM) } } /* Zero plus something non-zero : just return the something */ - return c ^ (signflip << 31); + return make_float32(float32_val(c) ^ (signflip << 31)); } if (aExp == 0) { @@ -3772,7 +3772,7 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM) } } /* Zero plus something non-zero : just return the something */ - return c ^ ((uint64_t)signflip << 63); + return make_float64(float64_val(c) ^ ((uint64_t)signflip << 63)); } if (aExp == 0) { From a896d03bb5f70ed76b3e9e1acba864115cfb5e01 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 12 Mar 2012 06:24:45 +0000 Subject: [PATCH 12/27] gdbstub: Synchronize CPU state unconditionally in gdb_set_cpu_pc Synchronize the CPU state via cpu_sychronize_state() unconditionally in gdb_set_cpu_pc() rather than only in some of the target ifdef ladder cases. We can divide the CPUs into three categories: * non-KVM targets: no change of behaviour since we will use the kvm-stub.c no-op function. * i386 and s390: no change of behaviour since they were already calling this function * PPC (in KVM mode): this fixes an error: failing to synchronise was accidental and probably a bug. This also paves the way for other targets (specifically ARM) which can add KVM support in future without having to add another target specific change to this bit of code. Signed-off-by: Peter Maydell Signed-off-by: Blue Swirl --- gdbstub.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 6a7e2c4934..6a77a6696b 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1903,8 +1903,8 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { -#if defined(TARGET_I386) cpu_synchronize_state(s->c_cpu); +#if defined(TARGET_I386) s->c_cpu->eip = pc; #elif defined (TARGET_PPC) s->c_cpu->nip = pc; @@ -1929,7 +1929,6 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) #elif defined (TARGET_ALPHA) s->c_cpu->pc = pc; #elif defined (TARGET_S390X) - cpu_synchronize_state(s->c_cpu); s->c_cpu->psw.addr = pc; #elif defined (TARGET_LM32) s->c_cpu->pc = pc; From c3ca04679e93a72635d6ef347886dbeba799b2d6 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Tue, 17 Apr 2012 19:22:39 +0200 Subject: [PATCH 13/27] tci: GETPC() macro must return an uintptr_t Change the data type of tci_tb_ptr, so GETPC() returns an uintptr_t now (like for all other TCG targets). This completes commit 2050396801ca0c8359364d61eaadece951006057 and fixes builds with TCI. Signed-off-by: Stefan Weil Reviewed-by: Eric Blake Signed-off-by: Blue Swirl --- exec-all.h | 2 +- tci.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/exec-all.h b/exec-all.h index 6bcc07538f..937d3cef01 100644 --- a/exec-all.h +++ b/exec-all.h @@ -283,7 +283,7 @@ extern int tb_invalidated_flag; /* Alpha and SH4 user mode emulations and Softmmu call GETPC(). For all others, GETPC remains undefined (which makes TCI a little faster. */ # if defined(CONFIG_SOFTMMU) || defined(TARGET_ALPHA) || defined(TARGET_SH4) -extern void *tci_tb_ptr; +extern uintptr_t tci_tb_ptr; # define GETPC() tci_tb_ptr # endif #elif defined(__s390__) && !defined(__s390x__) diff --git a/tci.c b/tci.c index c43fe7d260..71de66d508 100644 --- a/tci.c +++ b/tci.c @@ -58,7 +58,7 @@ CPUArchState *env; /* Targets which don't use GETPC also don't need tci_tb_ptr which makes them a little faster. */ #if defined(GETPC) -void *tci_tb_ptr; +uintptr_t tci_tb_ptr; #endif static tcg_target_ulong tci_reg[TCG_TARGET_NB_REGS]; @@ -450,7 +450,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr) for (;;) { #if defined(GETPC) - tci_tb_ptr = tb_ptr; + tci_tb_ptr = (uintptr_t)tb_ptr; #endif TCGOpcode opc = tb_ptr[0]; #if !defined(NDEBUG) From ce854d7cc3ba71e8d2a97e1fb33e13ac3283cbd4 Mon Sep 17 00:00:00 2001 From: Benoit Canet Date: Wed, 9 Nov 2011 07:32:59 +0000 Subject: [PATCH 14/27] target-arm: remind to keep arm features in sync with linux-user/elfload.c Signed-off-by: Benoit Canet Signed-off-by: Peter Maydell --- target-arm/cpu.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index c208c804aa..d2f5c760f5 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -360,6 +360,10 @@ enum arm_cpu_mode { #define ARM_IWMMXT_wCGR2 10 #define ARM_IWMMXT_wCGR3 11 +/* If adding a feature bit which corresponds to a Linux ELF + * HWCAP bit, remember to update the feature-bit-to-hwcap + * mapping in linux-user/elfload.c:get_elf_hwcap(). + */ enum arm_features { ARM_FEATURE_VFP, ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */ From 777dc78411865f2721f8728c71edb0b215da57fc Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:31 +0000 Subject: [PATCH 15/27] target-arm: Add QOM subclasses for each ARM cpu implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register subclasses for each ARM CPU implementation. Let arm_cpu_list() enumerate CPU subclasses in alphabetical order, except for special value "any". Replace cpu_arm_find_by_name()'s string -> CPUID lookup by storing the CPUID (aka MIDR, Main ID Register) value in the class. Signed-off-by: Andreas Färber Signed-off-by: Peter Maydell --- target-arm/cpu-qom.h | 12 +++ target-arm/cpu.c | 226 ++++++++++++++++++++++++++++++++++++++++++- target-arm/helper.c | 109 +++++++++------------ 3 files changed, 282 insertions(+), 65 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 42d2a6b63b..a4bcb31d47 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -58,6 +58,18 @@ typedef struct ARMCPU { /*< public >*/ CPUARMState env; + + /* The instance init functions for implementation-specific subclasses + * set these fields to specify the implementation-dependent values of + * various constant registers and reset values of non-constant + * registers. + * Some of these might become QOM properties eventually. + * Field names match the official register names as defined in the + * ARMv7AR ARM Architecture Reference Manual. A reset_ prefix + * is used for reset values of non-constant registers; no reset_ + * prefix means a constant register. + */ + uint32_t midr; } ARMCPU; static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index c3ed45b0bc..6d4f8fe473 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -34,6 +34,211 @@ static void arm_cpu_reset(CPUState *s) cpu_state_reset(&cpu->env); } +static void arm_cpu_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + cpu_exec_init(&cpu->env); +} + +/* CPU models */ + +static void arm926_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_ARM926; +} + +static void arm946_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_ARM946; +} + +static void arm1026_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_ARM1026; +} + +static void arm1136_r2_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_ARM1136_R2; +} + +static void arm1136_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_ARM1136; +} + +static void arm1176_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_ARM1176; +} + +static void arm11mpcore_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_ARM11MPCORE; +} + +static void cortex_m3_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_CORTEXM3; +} + +static void cortex_a8_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_CORTEXA8; +} + +static void cortex_a9_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_CORTEXA9; +} + +static void cortex_a15_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_CORTEXA15; +} + +static void ti925t_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_TI925T; +} + +static void sa1100_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_SA1100; +} + +static void sa1110_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_SA1110; +} + +static void pxa250_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA250; +} + +static void pxa255_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA255; +} + +static void pxa260_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA260; +} + +static void pxa261_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA261; +} + +static void pxa262_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA262; +} + +static void pxa270a0_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA270_A0; +} + +static void pxa270a1_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA270_A1; +} + +static void pxa270b0_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA270_B0; +} + +static void pxa270b1_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA270_B1; +} + +static void pxa270c0_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA270_C0; +} + +static void pxa270c5_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_PXA270_C5; +} + +static void arm_any_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + cpu->midr = ARM_CPUID_ANY; +} + +typedef struct ARMCPUInfo { + const char *name; + void (*initfn)(Object *obj); +} ARMCPUInfo; + +static const ARMCPUInfo arm_cpus[] = { + { .name = "arm926", .initfn = arm926_initfn }, + { .name = "arm946", .initfn = arm946_initfn }, + { .name = "arm1026", .initfn = arm1026_initfn }, + /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an + * older core than plain "arm1136". In particular this does not + * have the v6K features. + */ + { .name = "arm1136-r2", .initfn = arm1136_r2_initfn }, + { .name = "arm1136", .initfn = arm1136_initfn }, + { .name = "arm1176", .initfn = arm1176_initfn }, + { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, + { .name = "cortex-m3", .initfn = cortex_m3_initfn }, + { .name = "cortex-a8", .initfn = cortex_a8_initfn }, + { .name = "cortex-a9", .initfn = cortex_a9_initfn }, + { .name = "cortex-a15", .initfn = cortex_a15_initfn }, + { .name = "ti925t", .initfn = ti925t_initfn }, + { .name = "sa1100", .initfn = sa1100_initfn }, + { .name = "sa1110", .initfn = sa1110_initfn }, + { .name = "pxa250", .initfn = pxa250_initfn }, + { .name = "pxa255", .initfn = pxa255_initfn }, + { .name = "pxa260", .initfn = pxa260_initfn }, + { .name = "pxa261", .initfn = pxa261_initfn }, + { .name = "pxa262", .initfn = pxa262_initfn }, + /* "pxa270" is an alias for "pxa270-a0" */ + { .name = "pxa270", .initfn = pxa270a0_initfn }, + { .name = "pxa270-a0", .initfn = pxa270a0_initfn }, + { .name = "pxa270-a1", .initfn = pxa270a1_initfn }, + { .name = "pxa270-b0", .initfn = pxa270b0_initfn }, + { .name = "pxa270-b1", .initfn = pxa270b1_initfn }, + { .name = "pxa270-c0", .initfn = pxa270c0_initfn }, + { .name = "pxa270-c5", .initfn = pxa270c5_initfn }, + { .name = "any", .initfn = arm_any_initfn }, +}; + static void arm_cpu_class_init(ObjectClass *oc, void *data) { ARMCPUClass *acc = ARM_CPU_CLASS(oc); @@ -43,18 +248,37 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->reset = arm_cpu_reset; } +static void cpu_register(const ARMCPUInfo *info) +{ + TypeInfo type_info = { + .name = info->name, + .parent = TYPE_ARM_CPU, + .instance_size = sizeof(ARMCPU), + .instance_init = info->initfn, + .class_size = sizeof(ARMCPUClass), + }; + + type_register_static(&type_info); +} + static const TypeInfo arm_cpu_type_info = { .name = TYPE_ARM_CPU, .parent = TYPE_CPU, .instance_size = sizeof(ARMCPU), - .abstract = false, + .instance_init = arm_cpu_initfn, + .abstract = true, .class_size = sizeof(ARMCPUClass), .class_init = arm_cpu_class_init, }; static void arm_cpu_register_types(void) { + int i; + type_register_static(&arm_cpu_type_info); + for (i = 0; i < ARRAY_SIZE(arm_cpus); i++) { + cpu_register(&arm_cpus[i]); + } } type_init(arm_cpu_register_types) diff --git a/target-arm/helper.c b/target-arm/helper.c index 28f127baf8..afcd68c0c9 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -46,8 +46,6 @@ static uint32_t arm1176_cp15_c0_c1[8] = static uint32_t arm1176_cp15_c0_c2[8] = { 0x0140011, 0x12002111, 0x11231121, 0x01102131, 0x01141, 0, 0, 0 }; -static uint32_t cpu_arm_find_by_name(const char *name); - static inline void set_feature(CPUARMState *env, int feature) { env->features |= 1u << feature; @@ -55,7 +53,6 @@ static inline void set_feature(CPUARMState *env, int feature) static void cpu_reset_model_id(CPUARMState *env, uint32_t id) { - env->cp15.c0_cpuid = id; switch (id) { case ARM_CPUID_ARM926: set_feature(env, ARM_FEATURE_V5); @@ -201,7 +198,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_TI925T: set_feature(env, ARM_FEATURE_V4T); set_feature(env, ARM_FEATURE_OMAPCP); - env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring. */ env->cp15.c0_cachetype = 0x5109149; env->cp15.c1_sys = 0x00000070; env->cp15.c15_i_max = 0x000; @@ -287,18 +283,20 @@ void cpu_state_reset(CPUARMState *env) { uint32_t id; uint32_t tmp = 0; + ARMCPU *cpu = arm_env_get_cpu(env); if (qemu_loglevel_mask(CPU_LOG_RESET)) { qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); log_cpu_state(env, 0); } - id = env->cp15.c0_cpuid; + id = cpu->midr; tmp = env->cp15.c15_config_base_address; memset(env, 0, offsetof(CPUARMState, breakpoints)); if (id) cpu_reset_model_id(env, id); env->cp15.c15_config_base_address = tmp; + env->cp15.c0_cpuid = cpu->midr; #if defined (CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; /* For user mode we must enable access to coprocessors */ @@ -407,22 +405,20 @@ CPUARMState *cpu_arm_init(const char *cpu_model) { ARMCPU *cpu; CPUARMState *env; - uint32_t id; static int inited = 0; - id = cpu_arm_find_by_name(cpu_model); - if (id == 0) + if (!object_class_by_name(cpu_model)) { return NULL; - cpu = ARM_CPU(object_new(TYPE_ARM_CPU)); + } + cpu = ARM_CPU(object_new(cpu_model)); env = &cpu->env; - cpu_exec_init(env); + env->cpu_model_str = cpu_model; + if (tcg_enabled() && !inited) { inited = 1; arm_translate_init(); } - env->cpu_model_str = cpu_model; - env->cp15.c0_cpuid = id; cpu_state_reset(env); if (arm_feature(env, ARM_FEATURE_NEON)) { gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, @@ -438,66 +434,51 @@ CPUARMState *cpu_arm_init(const char *cpu_model) return env; } -struct arm_cpu_t { - uint32_t id; - const char *name; -}; +typedef struct ARMCPUListState { + fprintf_function cpu_fprintf; + FILE *file; +} ARMCPUListState; -static const struct arm_cpu_t arm_cpu_names[] = { - { ARM_CPUID_ARM926, "arm926"}, - { ARM_CPUID_ARM946, "arm946"}, - { ARM_CPUID_ARM1026, "arm1026"}, - { ARM_CPUID_ARM1136, "arm1136"}, - { ARM_CPUID_ARM1136_R2, "arm1136-r2"}, - { ARM_CPUID_ARM1176, "arm1176"}, - { ARM_CPUID_ARM11MPCORE, "arm11mpcore"}, - { ARM_CPUID_CORTEXM3, "cortex-m3"}, - { ARM_CPUID_CORTEXA8, "cortex-a8"}, - { ARM_CPUID_CORTEXA9, "cortex-a9"}, - { ARM_CPUID_CORTEXA15, "cortex-a15" }, - { ARM_CPUID_TI925T, "ti925t" }, - { ARM_CPUID_PXA250, "pxa250" }, - { ARM_CPUID_SA1100, "sa1100" }, - { ARM_CPUID_SA1110, "sa1110" }, - { ARM_CPUID_PXA255, "pxa255" }, - { ARM_CPUID_PXA260, "pxa260" }, - { ARM_CPUID_PXA261, "pxa261" }, - { ARM_CPUID_PXA262, "pxa262" }, - { ARM_CPUID_PXA270, "pxa270" }, - { ARM_CPUID_PXA270_A0, "pxa270-a0" }, - { ARM_CPUID_PXA270_A1, "pxa270-a1" }, - { ARM_CPUID_PXA270_B0, "pxa270-b0" }, - { ARM_CPUID_PXA270_B1, "pxa270-b1" }, - { ARM_CPUID_PXA270_C0, "pxa270-c0" }, - { ARM_CPUID_PXA270_C5, "pxa270-c5" }, - { ARM_CPUID_ANY, "any"}, - { 0, NULL} -}; - -void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf) +/* Sort alphabetically by type name, except for "any". */ +static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b) { - int i; + ObjectClass *class_a = (ObjectClass *)a; + ObjectClass *class_b = (ObjectClass *)b; + const char *name_a, *name_b; - (*cpu_fprintf)(f, "Available CPUs:\n"); - for (i = 0; arm_cpu_names[i].name; i++) { - (*cpu_fprintf)(f, " %s\n", arm_cpu_names[i].name); + name_a = object_class_get_name(class_a); + name_b = object_class_get_name(class_b); + if (strcmp(name_a, "any") == 0) { + return 1; + } else if (strcmp(name_b, "any") == 0) { + return -1; + } else { + return strcmp(name_a, name_b); } } -/* return 0 if not found */ -static uint32_t cpu_arm_find_by_name(const char *name) +static void arm_cpu_list_entry(gpointer data, gpointer user_data) { - int i; - uint32_t id; + ObjectClass *oc = data; + ARMCPUListState *s = user_data; - id = 0; - for (i = 0; arm_cpu_names[i].name; i++) { - if (strcmp(name, arm_cpu_names[i].name) == 0) { - id = arm_cpu_names[i].id; - break; - } - } - return id; + (*s->cpu_fprintf)(s->file, " %s\n", + object_class_get_name(oc)); +} + +void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf) +{ + ARMCPUListState s = { + .file = f, + .cpu_fprintf = cpu_fprintf, + }; + GSList *list; + + list = object_class_get_list(TYPE_ARM_CPU, false); + list = g_slist_sort(list, arm_cpu_list_compare); + (*cpu_fprintf)(f, "Available CPUs:\n"); + g_slist_foreach(list, arm_cpu_list_entry, &s); + g_slist_free(list); } static int bad_mode_switch(CPUARMState *env, int mode) From 581be09434f155ebe0ee7b532c20974843188958 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:31 +0000 Subject: [PATCH 16/27] target-arm: Move feature bit settings to CPU init fns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the setting of the feature bits from cpu_reset_model_id() to each CPU's instance init function. This requires us to move the features field in CPUARMState so that it is not cleared on reset. Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/cpu-qom.h | 1 + target-arm/cpu.c | 132 +++++++++++++++++++++++++++++++++++++++++++ target-arm/cpu.h | 6 +- target-arm/helper.c | 97 +------------------------------ 4 files changed, 137 insertions(+), 99 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index a4bcb31d47..7e2d4c942e 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -79,5 +79,6 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) #define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e)) +void arm_cpu_realize(ARMCPU *cpu); #endif diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 6d4f8fe473..46fbc2d073 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -34,6 +34,11 @@ static void arm_cpu_reset(CPUState *s) cpu_state_reset(&cpu->env); } +static inline void set_feature(CPUARMState *env, int feature) +{ + env->features |= 1u << feature; +} + static void arm_cpu_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); @@ -41,161 +46,288 @@ static void arm_cpu_initfn(Object *obj) cpu_exec_init(&cpu->env); } +void arm_cpu_realize(ARMCPU *cpu) +{ + /* This function is called by cpu_arm_init() because it + * needs to do common actions based on feature bits, etc + * that have been set by the subclass init functions. + * When we have QOM realize support it should become + * a true realize function instead. + */ + CPUARMState *env = &cpu->env; + /* Some features automatically imply others: */ + if (arm_feature(env, ARM_FEATURE_V7)) { + set_feature(env, ARM_FEATURE_VAPA); + set_feature(env, ARM_FEATURE_THUMB2); + if (!arm_feature(env, ARM_FEATURE_M)) { + set_feature(env, ARM_FEATURE_V6K); + } else { + set_feature(env, ARM_FEATURE_V6); + } + } + if (arm_feature(env, ARM_FEATURE_V6K)) { + set_feature(env, ARM_FEATURE_V6); + set_feature(env, ARM_FEATURE_MVFR); + } + if (arm_feature(env, ARM_FEATURE_V6)) { + set_feature(env, ARM_FEATURE_V5); + if (!arm_feature(env, ARM_FEATURE_M)) { + set_feature(env, ARM_FEATURE_AUXCR); + } + } + if (arm_feature(env, ARM_FEATURE_V5)) { + set_feature(env, ARM_FEATURE_V4T); + } + if (arm_feature(env, ARM_FEATURE_M)) { + set_feature(env, ARM_FEATURE_THUMB_DIV); + } + if (arm_feature(env, ARM_FEATURE_ARM_DIV)) { + set_feature(env, ARM_FEATURE_THUMB_DIV); + } + if (arm_feature(env, ARM_FEATURE_VFP4)) { + set_feature(env, ARM_FEATURE_VFP3); + } + if (arm_feature(env, ARM_FEATURE_VFP3)) { + set_feature(env, ARM_FEATURE_VFP); + } +} + /* CPU models */ static void arm926_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM926; } static void arm946_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_MPU); cpu->midr = ARM_CPUID_ARM946; } static void arm1026_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_AUXCR); cpu->midr = ARM_CPUID_ARM1026; } static void arm1136_r2_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V6); + set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM1136_R2; } static void arm1136_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V6K); + set_feature(&cpu->env, ARM_FEATURE_V6); + set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM1136; } static void arm1176_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V6K); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_VAPA); cpu->midr = ARM_CPUID_ARM1176; } static void arm11mpcore_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V6K); + set_feature(&cpu->env, ARM_FEATURE_VFP); + set_feature(&cpu->env, ARM_FEATURE_VAPA); cpu->midr = ARM_CPUID_ARM11MPCORE; } static void cortex_m3_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_M); cpu->midr = ARM_CPUID_CORTEXM3; } static void cortex_a8_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_VFP3); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); cpu->midr = ARM_CPUID_CORTEXA8; } static void cortex_a9_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_VFP3); + set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); + /* Note that A9 supports the MP extensions even for + * A9UP and single-core A9MP (which are both different + * and valid configurations; we don't model A9UP). + */ + set_feature(&cpu->env, ARM_FEATURE_V7MP); cpu->midr = ARM_CPUID_CORTEXA9; } static void cortex_a15_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_VFP4); + set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); + set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); + set_feature(&cpu->env, ARM_FEATURE_V7MP); + set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); cpu->midr = ARM_CPUID_CORTEXA15; } static void ti925t_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V4T); + set_feature(&cpu->env, ARM_FEATURE_OMAPCP); cpu->midr = ARM_CPUID_TI925T; } static void sa1100_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_STRONGARM); cpu->midr = ARM_CPUID_SA1100; } static void sa1110_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_STRONGARM); cpu->midr = ARM_CPUID_SA1110; } static void pxa250_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA250; } static void pxa255_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA255; } static void pxa260_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA260; } static void pxa261_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA261; } static void pxa262_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA262; } static void pxa270a0_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_A0; } static void pxa270a1_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_A1; } static void pxa270b0_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_B0; } static void pxa270b1_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_B1; } static void pxa270c0_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_C0; } static void pxa270c5_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V5); + set_feature(&cpu->env, ARM_FEATURE_XSCALE); + set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_C5; } static void arm_any_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + set_feature(&cpu->env, ARM_FEATURE_V7); + set_feature(&cpu->env, ARM_FEATURE_VFP4); + set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); + set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); + set_feature(&cpu->env, ARM_FEATURE_V7MP); cpu->midr = ARM_CPUID_ANY; } diff --git a/target-arm/cpu.h b/target-arm/cpu.h index d2f5c760f5..01e0e36c2f 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -170,9 +170,6 @@ typedef struct CPUARMState { uint32_t teecr; uint32_t teehbr; - /* Internal CPU feature flags. */ - uint32_t features; - /* VFP coprocessor state. */ struct { float64 regs[32]; @@ -228,6 +225,9 @@ typedef struct CPUARMState { /* These fields after the common ones so they are preserved on reset. */ + /* Internal CPU feature flags. */ + uint32_t features; + /* Coprocessor IO used by peripherals */ struct { ARMReadCPFunc *cp_read; diff --git a/target-arm/helper.c b/target-arm/helper.c index afcd68c0c9..e495de683b 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -46,46 +46,30 @@ static uint32_t arm1176_cp15_c0_c1[8] = static uint32_t arm1176_cp15_c0_c2[8] = { 0x0140011, 0x12002111, 0x11231121, 0x01102131, 0x01141, 0, 0, 0 }; -static inline void set_feature(CPUARMState *env, int feature) -{ - env->features |= 1u << feature; -} - static void cpu_reset_model_id(CPUARMState *env, uint32_t id) { switch (id) { case ARM_CPUID_ARM926: - set_feature(env, ARM_FEATURE_V5); - set_feature(env, ARM_FEATURE_VFP); env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM946: - set_feature(env, ARM_FEATURE_V5); - set_feature(env, ARM_FEATURE_MPU); env->cp15.c0_cachetype = 0x0f004006; env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_ARM1026: - set_feature(env, ARM_FEATURE_V5); - set_feature(env, ARM_FEATURE_VFP); - set_feature(env, ARM_FEATURE_AUXCR); env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0; env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM1136: /* This is the 1136 r1, which is a v6K core */ - set_feature(env, ARM_FEATURE_V6K); - /* Fall through */ case ARM_CPUID_ARM1136_R2: /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an * older core than plain "arm1136". In particular this does not * have the v6K features. */ - set_feature(env, ARM_FEATURE_V6); - set_feature(env, ARM_FEATURE_VFP); /* These ID register values are correct for 1136 but may be wrong * for 1136_r2 (in particular r0p2 does not actually implement most * of the ID registers). @@ -99,9 +83,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM1176: - set_feature(env, ARM_FEATURE_V6K); - set_feature(env, ARM_FEATURE_VFP); - set_feature(env, ARM_FEATURE_VAPA); env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b5; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; @@ -111,9 +92,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM11MPCORE: - set_feature(env, ARM_FEATURE_V6K); - set_feature(env, ARM_FEATURE_VFP); - set_feature(env, ARM_FEATURE_VAPA); env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; @@ -122,10 +100,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_cachetype = 0x1dd20d2; break; case ARM_CPUID_CORTEXA8: - set_feature(env, ARM_FEATURE_V7); - set_feature(env, ARM_FEATURE_VFP3); - set_feature(env, ARM_FEATURE_NEON); - set_feature(env, ARM_FEATURE_THUMB2EE); env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100; @@ -139,16 +113,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA9: - set_feature(env, ARM_FEATURE_V7); - set_feature(env, ARM_FEATURE_VFP3); - set_feature(env, ARM_FEATURE_VFP_FP16); - set_feature(env, ARM_FEATURE_NEON); - set_feature(env, ARM_FEATURE_THUMB2EE); - /* Note that A9 supports the MP extensions even for - * A9UP and single-core A9MP (which are both different - * and valid configurations; we don't model A9UP). - */ - set_feature(env, ARM_FEATURE_V7MP); env->vfp.xregs[ARM_VFP_FPSID] = 0x41033090; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x01111111; @@ -161,14 +125,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA15: - set_feature(env, ARM_FEATURE_V7); - set_feature(env, ARM_FEATURE_VFP4); - set_feature(env, ARM_FEATURE_VFP_FP16); - set_feature(env, ARM_FEATURE_NEON); - set_feature(env, ARM_FEATURE_THUMB2EE); - set_feature(env, ARM_FEATURE_ARM_DIV); - set_feature(env, ARM_FEATURE_V7MP); - set_feature(env, ARM_FEATURE_GENERIC_TIMER); env->vfp.xregs[ARM_VFP_FPSID] = 0x410430f0; env->vfp.xregs[ARM_VFP_MVFR0] = 0x10110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x11111111; @@ -182,22 +138,11 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXM3: - set_feature(env, ARM_FEATURE_V7); - set_feature(env, ARM_FEATURE_M); break; case ARM_CPUID_ANY: /* For userspace emulation. */ - set_feature(env, ARM_FEATURE_V7); - set_feature(env, ARM_FEATURE_VFP4); - set_feature(env, ARM_FEATURE_VFP_FP16); - set_feature(env, ARM_FEATURE_NEON); - set_feature(env, ARM_FEATURE_THUMB2EE); - set_feature(env, ARM_FEATURE_ARM_DIV); - set_feature(env, ARM_FEATURE_V7MP); break; case ARM_CPUID_TI915T: case ARM_CPUID_TI925T: - set_feature(env, ARM_FEATURE_V4T); - set_feature(env, ARM_FEATURE_OMAPCP); env->cp15.c0_cachetype = 0x5109149; env->cp15.c1_sys = 0x00000070; env->cp15.c15_i_max = 0x000; @@ -208,8 +153,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA260: case ARM_CPUID_PXA261: case ARM_CPUID_PXA262: - set_feature(env, ARM_FEATURE_V5); - set_feature(env, ARM_FEATURE_XSCALE); /* JTAG_ID is ((id << 28) | 0x09265013) */ env->cp15.c0_cachetype = 0xd172172; env->cp15.c1_sys = 0x00000078; @@ -220,17 +163,13 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA270_B1: case ARM_CPUID_PXA270_C0: case ARM_CPUID_PXA270_C5: - set_feature(env, ARM_FEATURE_V5); - set_feature(env, ARM_FEATURE_XSCALE); /* JTAG_ID is ((id << 28) | 0x09265013) */ - set_feature(env, ARM_FEATURE_IWMMXT); env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; env->cp15.c0_cachetype = 0xd172172; env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_SA1100: case ARM_CPUID_SA1110: - set_feature(env, ARM_FEATURE_STRONGARM); env->cp15.c1_sys = 0x00000070; break; default: @@ -238,41 +177,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) break; } - /* Some features automatically imply others: */ - if (arm_feature(env, ARM_FEATURE_V7)) { - set_feature(env, ARM_FEATURE_VAPA); - set_feature(env, ARM_FEATURE_THUMB2); - if (!arm_feature(env, ARM_FEATURE_M)) { - set_feature(env, ARM_FEATURE_V6K); - } else { - set_feature(env, ARM_FEATURE_V6); - } - } - if (arm_feature(env, ARM_FEATURE_V6K)) { - set_feature(env, ARM_FEATURE_V6); - set_feature(env, ARM_FEATURE_MVFR); - } - if (arm_feature(env, ARM_FEATURE_V6)) { - set_feature(env, ARM_FEATURE_V5); - if (!arm_feature(env, ARM_FEATURE_M)) { - set_feature(env, ARM_FEATURE_AUXCR); - } - } - if (arm_feature(env, ARM_FEATURE_V5)) { - set_feature(env, ARM_FEATURE_V4T); - } - if (arm_feature(env, ARM_FEATURE_M)) { - set_feature(env, ARM_FEATURE_THUMB_DIV); - } - if (arm_feature(env, ARM_FEATURE_ARM_DIV)) { - set_feature(env, ARM_FEATURE_THUMB_DIV); - } - if (arm_feature(env, ARM_FEATURE_VFP4)) { - set_feature(env, ARM_FEATURE_VFP3); - } - if (arm_feature(env, ARM_FEATURE_VFP3)) { - set_feature(env, ARM_FEATURE_VFP); - } } /* TODO Move contents into arm_cpu_reset() in cpu.c, @@ -413,6 +317,7 @@ CPUARMState *cpu_arm_init(const char *cpu_model) cpu = ARM_CPU(object_new(cpu_model)); env = &cpu->env; env->cpu_model_str = cpu_model; + arm_cpu_realize(cpu); if (tcg_enabled() && !inited) { inited = 1; From 325b3ceff69c987e90acf9c8ef6f55e646b39767 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:32 +0000 Subject: [PATCH 17/27] target-arm: Move FPSID config to cpu init fns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the reset FPSID to the ARMCPU struct, and set it in the per-implementation instance init function. At reset we then just copy the reset value into the CPUARMState field. Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/cpu-qom.h | 1 + target-arm/cpu.c | 9 +++++++++ target-arm/helper.c | 10 ++-------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 7e2d4c942e..7cc4cd51ba 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -70,6 +70,7 @@ typedef struct ARMCPU { * prefix means a constant register. */ uint32_t midr; + uint32_t reset_fpsid; } ARMCPU; static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 46fbc2d073..5fb78030a3 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -100,6 +100,7 @@ static void arm926_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V5); set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM926; + cpu->reset_fpsid = 0x41011090; } static void arm946_initfn(Object *obj) @@ -117,6 +118,7 @@ static void arm1026_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VFP); set_feature(&cpu->env, ARM_FEATURE_AUXCR); cpu->midr = ARM_CPUID_ARM1026; + cpu->reset_fpsid = 0x410110a0; } static void arm1136_r2_initfn(Object *obj) @@ -125,6 +127,7 @@ static void arm1136_r2_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V6); set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM1136_R2; + cpu->reset_fpsid = 0x410120b4; } static void arm1136_initfn(Object *obj) @@ -134,6 +137,7 @@ static void arm1136_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V6); set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM1136; + cpu->reset_fpsid = 0x410120b4; } static void arm1176_initfn(Object *obj) @@ -143,6 +147,7 @@ static void arm1176_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VFP); set_feature(&cpu->env, ARM_FEATURE_VAPA); cpu->midr = ARM_CPUID_ARM1176; + cpu->reset_fpsid = 0x410120b5; } static void arm11mpcore_initfn(Object *obj) @@ -152,6 +157,7 @@ static void arm11mpcore_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VFP); set_feature(&cpu->env, ARM_FEATURE_VAPA); cpu->midr = ARM_CPUID_ARM11MPCORE; + cpu->reset_fpsid = 0x410120b4; } static void cortex_m3_initfn(Object *obj) @@ -170,6 +176,7 @@ static void cortex_a8_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_NEON); set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); cpu->midr = ARM_CPUID_CORTEXA8; + cpu->reset_fpsid = 0x410330c0; } static void cortex_a9_initfn(Object *obj) @@ -186,6 +193,7 @@ static void cortex_a9_initfn(Object *obj) */ set_feature(&cpu->env, ARM_FEATURE_V7MP); cpu->midr = ARM_CPUID_CORTEXA9; + cpu->reset_fpsid = 0x41033090; } static void cortex_a15_initfn(Object *obj) @@ -200,6 +208,7 @@ static void cortex_a15_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V7MP); set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); cpu->midr = ARM_CPUID_CORTEXA15; + cpu->reset_fpsid = 0x410430f0; } static void ti925t_initfn(Object *obj) diff --git a/target-arm/helper.c b/target-arm/helper.c index e495de683b..3247dd31d7 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -50,7 +50,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) { switch (id) { case ARM_CPUID_ARM926: - env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; @@ -59,7 +58,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_ARM1026: - env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0; env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; @@ -74,7 +72,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) * for 1136_r2 (in particular r0p2 does not actually implement most * of the ID registers). */ - env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -83,7 +80,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM1176: - env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b5; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; memcpy(env->cp15.c0_c1, arm1176_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -92,7 +88,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM11MPCORE: - env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -100,7 +95,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_cachetype = 0x1dd20d2; break; case ARM_CPUID_CORTEXA8: - env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100; memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -113,7 +107,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA9: - env->vfp.xregs[ARM_VFP_FPSID] = 0x41033090; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x01111111; memcpy(env->cp15.c0_c1, cortexa9_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -125,7 +118,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA15: - env->vfp.xregs[ARM_VFP_FPSID] = 0x410430f0; env->vfp.xregs[ARM_VFP_MVFR0] = 0x10110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x11111111; memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -201,6 +193,8 @@ void cpu_state_reset(CPUARMState *env) cpu_reset_model_id(env, id); env->cp15.c15_config_base_address = tmp; env->cp15.c0_cpuid = cpu->midr; + env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; + #if defined (CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; /* For user mode we must enable access to coprocessors */ From bd35c3553bfe6acb47034b1bfb2cf093684f406d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:32 +0000 Subject: [PATCH 18/27] target-arm: Move MVFR* setup to per cpu init fns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the MVFR* VFP feature register values to ARMCPU, so they are set up by the implementation-specific instance init functions rather than in cpu_reset_model_id(). Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/cpu-qom.h | 2 ++ target-arm/cpu.c | 14 ++++++++++++++ target-arm/helper.c | 14 ++------------ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 7cc4cd51ba..c51eb84817 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -71,6 +71,8 @@ typedef struct ARMCPU { */ uint32_t midr; uint32_t reset_fpsid; + uint32_t mvfr0; + uint32_t mvfr1; } ARMCPU; static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 5fb78030a3..80ca7aa2a8 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -128,6 +128,8 @@ static void arm1136_r2_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM1136_R2; cpu->reset_fpsid = 0x410120b4; + cpu->mvfr0 = 0x11111111; + cpu->mvfr1 = 0x00000000; } static void arm1136_initfn(Object *obj) @@ -138,6 +140,8 @@ static void arm1136_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM1136; cpu->reset_fpsid = 0x410120b4; + cpu->mvfr0 = 0x11111111; + cpu->mvfr1 = 0x00000000; } static void arm1176_initfn(Object *obj) @@ -148,6 +152,8 @@ static void arm1176_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VAPA); cpu->midr = ARM_CPUID_ARM1176; cpu->reset_fpsid = 0x410120b5; + cpu->mvfr0 = 0x11111111; + cpu->mvfr1 = 0x00000000; } static void arm11mpcore_initfn(Object *obj) @@ -158,6 +164,8 @@ static void arm11mpcore_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VAPA); cpu->midr = ARM_CPUID_ARM11MPCORE; cpu->reset_fpsid = 0x410120b4; + cpu->mvfr0 = 0x11111111; + cpu->mvfr1 = 0x00000000; } static void cortex_m3_initfn(Object *obj) @@ -177,6 +185,8 @@ static void cortex_a8_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); cpu->midr = ARM_CPUID_CORTEXA8; cpu->reset_fpsid = 0x410330c0; + cpu->mvfr0 = 0x11110222; + cpu->mvfr1 = 0x00011100; } static void cortex_a9_initfn(Object *obj) @@ -194,6 +204,8 @@ static void cortex_a9_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V7MP); cpu->midr = ARM_CPUID_CORTEXA9; cpu->reset_fpsid = 0x41033090; + cpu->mvfr0 = 0x11110222; + cpu->mvfr1 = 0x01111111; } static void cortex_a15_initfn(Object *obj) @@ -209,6 +221,8 @@ static void cortex_a15_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); cpu->midr = ARM_CPUID_CORTEXA15; cpu->reset_fpsid = 0x410430f0; + cpu->mvfr0 = 0x10110222; + cpu->mvfr1 = 0x11111111; } static void ti925t_initfn(Object *obj) diff --git a/target-arm/helper.c b/target-arm/helper.c index 3247dd31d7..777bb036e4 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -72,31 +72,23 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) * for 1136_r2 (in particular r0p2 does not actually implement most * of the ID registers). */ - env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; - env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM1176: - env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; - env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; memcpy(env->cp15.c0_c1, arm1176_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, arm1176_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM11MPCORE: - env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; - env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x1dd20d2; break; case ARM_CPUID_CORTEXA8: - env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; - env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100; memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x82048004; @@ -107,8 +99,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA9: - env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; - env->vfp.xregs[ARM_VFP_MVFR1] = 0x01111111; memcpy(env->cp15.c0_c1, cortexa9_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, cortexa9_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x80038003; @@ -118,8 +108,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA15: - env->vfp.xregs[ARM_VFP_MVFR0] = 0x10110222; - env->vfp.xregs[ARM_VFP_MVFR1] = 0x11111111; memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, cortexa15_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x8444c004; @@ -194,6 +182,8 @@ void cpu_state_reset(CPUARMState *env) env->cp15.c15_config_base_address = tmp; env->cp15.c0_cpuid = cpu->midr; env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; + env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; + env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; #if defined (CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; From 64e1671fd46669f097763f71b9a8cbcc0bf61cce Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:33 +0000 Subject: [PATCH 19/27] target-arm: Move CTR setup to per cpu init fns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move CTR (cache type register) value to an ARMCPU field set up by per-cpu init fns. Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/cpu-qom.h | 1 + target-arm/cpu.c | 22 ++++++++++++++++++++++ target-arm/helper.c | 13 +------------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index c51eb84817..cb9198a668 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -73,6 +73,7 @@ typedef struct ARMCPU { uint32_t reset_fpsid; uint32_t mvfr0; uint32_t mvfr1; + uint32_t ctr; } ARMCPU; static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 80ca7aa2a8..4f19d5c1e8 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -101,6 +101,7 @@ static void arm926_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM926; cpu->reset_fpsid = 0x41011090; + cpu->ctr = 0x1dd20d2; } static void arm946_initfn(Object *obj) @@ -109,6 +110,7 @@ static void arm946_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V5); set_feature(&cpu->env, ARM_FEATURE_MPU); cpu->midr = ARM_CPUID_ARM946; + cpu->ctr = 0x0f004006; } static void arm1026_initfn(Object *obj) @@ -119,6 +121,7 @@ static void arm1026_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_AUXCR); cpu->midr = ARM_CPUID_ARM1026; cpu->reset_fpsid = 0x410110a0; + cpu->ctr = 0x1dd20d2; } static void arm1136_r2_initfn(Object *obj) @@ -130,6 +133,7 @@ static void arm1136_r2_initfn(Object *obj) cpu->reset_fpsid = 0x410120b4; cpu->mvfr0 = 0x11111111; cpu->mvfr1 = 0x00000000; + cpu->ctr = 0x1dd20d2; } static void arm1136_initfn(Object *obj) @@ -142,6 +146,7 @@ static void arm1136_initfn(Object *obj) cpu->reset_fpsid = 0x410120b4; cpu->mvfr0 = 0x11111111; cpu->mvfr1 = 0x00000000; + cpu->ctr = 0x1dd20d2; } static void arm1176_initfn(Object *obj) @@ -154,6 +159,7 @@ static void arm1176_initfn(Object *obj) cpu->reset_fpsid = 0x410120b5; cpu->mvfr0 = 0x11111111; cpu->mvfr1 = 0x00000000; + cpu->ctr = 0x1dd20d2; } static void arm11mpcore_initfn(Object *obj) @@ -166,6 +172,7 @@ static void arm11mpcore_initfn(Object *obj) cpu->reset_fpsid = 0x410120b4; cpu->mvfr0 = 0x11111111; cpu->mvfr1 = 0x00000000; + cpu->ctr = 0x1dd20d2; } static void cortex_m3_initfn(Object *obj) @@ -187,6 +194,7 @@ static void cortex_a8_initfn(Object *obj) cpu->reset_fpsid = 0x410330c0; cpu->mvfr0 = 0x11110222; cpu->mvfr1 = 0x00011100; + cpu->ctr = 0x82048004; } static void cortex_a9_initfn(Object *obj) @@ -206,6 +214,7 @@ static void cortex_a9_initfn(Object *obj) cpu->reset_fpsid = 0x41033090; cpu->mvfr0 = 0x11110222; cpu->mvfr1 = 0x01111111; + cpu->ctr = 0x80038003; } static void cortex_a15_initfn(Object *obj) @@ -223,6 +232,7 @@ static void cortex_a15_initfn(Object *obj) cpu->reset_fpsid = 0x410430f0; cpu->mvfr0 = 0x10110222; cpu->mvfr1 = 0x11111111; + cpu->ctr = 0x8444c004; } static void ti925t_initfn(Object *obj) @@ -231,6 +241,7 @@ static void ti925t_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V4T); set_feature(&cpu->env, ARM_FEATURE_OMAPCP); cpu->midr = ARM_CPUID_TI925T; + cpu->ctr = 0x5109149; } static void sa1100_initfn(Object *obj) @@ -253,6 +264,7 @@ static void pxa250_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V5); set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA250; + cpu->ctr = 0xd172172; } static void pxa255_initfn(Object *obj) @@ -261,6 +273,7 @@ static void pxa255_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V5); set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA255; + cpu->ctr = 0xd172172; } static void pxa260_initfn(Object *obj) @@ -269,6 +282,7 @@ static void pxa260_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V5); set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA260; + cpu->ctr = 0xd172172; } static void pxa261_initfn(Object *obj) @@ -277,6 +291,7 @@ static void pxa261_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V5); set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA261; + cpu->ctr = 0xd172172; } static void pxa262_initfn(Object *obj) @@ -285,6 +300,7 @@ static void pxa262_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V5); set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA262; + cpu->ctr = 0xd172172; } static void pxa270a0_initfn(Object *obj) @@ -294,6 +310,7 @@ static void pxa270a0_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_A0; + cpu->ctr = 0xd172172; } static void pxa270a1_initfn(Object *obj) @@ -303,6 +320,7 @@ static void pxa270a1_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_A1; + cpu->ctr = 0xd172172; } static void pxa270b0_initfn(Object *obj) @@ -312,6 +330,7 @@ static void pxa270b0_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_B0; + cpu->ctr = 0xd172172; } static void pxa270b1_initfn(Object *obj) @@ -321,6 +340,7 @@ static void pxa270b1_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_B1; + cpu->ctr = 0xd172172; } static void pxa270c0_initfn(Object *obj) @@ -330,6 +350,7 @@ static void pxa270c0_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_C0; + cpu->ctr = 0xd172172; } static void pxa270c5_initfn(Object *obj) @@ -339,6 +360,7 @@ static void pxa270c5_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_C5; + cpu->ctr = 0xd172172; } static void arm_any_initfn(Object *obj) diff --git a/target-arm/helper.c b/target-arm/helper.c index 777bb036e4..a23df14706 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -50,15 +50,12 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) { switch (id) { case ARM_CPUID_ARM926: - env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM946: - env->cp15.c0_cachetype = 0x0f004006; env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_ARM1026: - env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM1136: @@ -74,24 +71,20 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) */ memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t)); - env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM1176: memcpy(env->cp15.c0_c1, arm1176_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, arm1176_cp15_c0_c2, 8 * sizeof(uint32_t)); - env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM11MPCORE: memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t)); - env->cp15.c0_cachetype = 0x1dd20d2; break; case ARM_CPUID_CORTEXA8: memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t)); - env->cp15.c0_cachetype = 0x82048004; env->cp15.c0_clid = (1 << 27) | (2 << 24) | 3; env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */ env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */ @@ -101,7 +94,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_CORTEXA9: memcpy(env->cp15.c0_c1, cortexa9_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, cortexa9_cp15_c0_c2, 8 * sizeof(uint32_t)); - env->cp15.c0_cachetype = 0x80038003; env->cp15.c0_clid = (1 << 27) | (1 << 24) | 3; env->cp15.c0_ccsid[0] = 0xe00fe015; /* 16k L1 dcache. */ env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */ @@ -110,7 +102,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_CORTEXA15: memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, cortexa15_cp15_c0_c2, 8 * sizeof(uint32_t)); - env->cp15.c0_cachetype = 0x8444c004; env->cp15.c0_clid = 0x0a200023; env->cp15.c0_ccsid[0] = 0x701fe00a; /* 32K L1 dcache */ env->cp15.c0_ccsid[1] = 0x201fe00a; /* 32K L1 icache */ @@ -123,7 +114,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) break; case ARM_CPUID_TI915T: case ARM_CPUID_TI925T: - env->cp15.c0_cachetype = 0x5109149; env->cp15.c1_sys = 0x00000070; env->cp15.c15_i_max = 0x000; env->cp15.c15_i_min = 0xff0; @@ -134,7 +124,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA261: case ARM_CPUID_PXA262: /* JTAG_ID is ((id << 28) | 0x09265013) */ - env->cp15.c0_cachetype = 0xd172172; env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_PXA270_A0: @@ -145,7 +134,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA270_C5: /* JTAG_ID is ((id << 28) | 0x09265013) */ env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; - env->cp15.c0_cachetype = 0xd172172; env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_SA1100: @@ -184,6 +172,7 @@ void cpu_state_reset(CPUARMState *env) env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; + env->cp15.c0_cachetype = cpu->ctr; #if defined (CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; From 0ca7e01cbc5f2850560e6a170ae1e4541aecce17 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:33 +0000 Subject: [PATCH 20/27] target-arm: Move SCTLR reset value setup to per cpu init fns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the reset value of SCTLR to ARMCPU, initialised in the per-cpu init functions. It can then be reset by a simple copy, and we can drop the code from cpu_reset_model_id(). Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/cpu-qom.h | 1 + target-arm/cpu.c | 23 +++++++++++++++++++++++ target-arm/helper.c | 13 +------------ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index cb9198a668..97f7e9099b 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -74,6 +74,7 @@ typedef struct ARMCPU { uint32_t mvfr0; uint32_t mvfr1; uint32_t ctr; + uint32_t reset_sctlr; } ARMCPU; static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 4f19d5c1e8..74a7d208ba 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -102,6 +102,7 @@ static void arm926_initfn(Object *obj) cpu->midr = ARM_CPUID_ARM926; cpu->reset_fpsid = 0x41011090; cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00090078; } static void arm946_initfn(Object *obj) @@ -111,6 +112,7 @@ static void arm946_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_MPU); cpu->midr = ARM_CPUID_ARM946; cpu->ctr = 0x0f004006; + cpu->reset_sctlr = 0x00000078; } static void arm1026_initfn(Object *obj) @@ -122,6 +124,7 @@ static void arm1026_initfn(Object *obj) cpu->midr = ARM_CPUID_ARM1026; cpu->reset_fpsid = 0x410110a0; cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00090078; } static void arm1136_r2_initfn(Object *obj) @@ -134,6 +137,7 @@ static void arm1136_r2_initfn(Object *obj) cpu->mvfr0 = 0x11111111; cpu->mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00050078; } static void arm1136_initfn(Object *obj) @@ -147,6 +151,7 @@ static void arm1136_initfn(Object *obj) cpu->mvfr0 = 0x11111111; cpu->mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00050078; } static void arm1176_initfn(Object *obj) @@ -160,6 +165,7 @@ static void arm1176_initfn(Object *obj) cpu->mvfr0 = 0x11111111; cpu->mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; + cpu->reset_sctlr = 0x00050078; } static void arm11mpcore_initfn(Object *obj) @@ -195,6 +201,7 @@ static void cortex_a8_initfn(Object *obj) cpu->mvfr0 = 0x11110222; cpu->mvfr1 = 0x00011100; cpu->ctr = 0x82048004; + cpu->reset_sctlr = 0x00c50078; } static void cortex_a9_initfn(Object *obj) @@ -215,6 +222,7 @@ static void cortex_a9_initfn(Object *obj) cpu->mvfr0 = 0x11110222; cpu->mvfr1 = 0x01111111; cpu->ctr = 0x80038003; + cpu->reset_sctlr = 0x00c50078; } static void cortex_a15_initfn(Object *obj) @@ -233,6 +241,7 @@ static void cortex_a15_initfn(Object *obj) cpu->mvfr0 = 0x10110222; cpu->mvfr1 = 0x11111111; cpu->ctr = 0x8444c004; + cpu->reset_sctlr = 0x00c50078; } static void ti925t_initfn(Object *obj) @@ -242,6 +251,7 @@ static void ti925t_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_OMAPCP); cpu->midr = ARM_CPUID_TI925T; cpu->ctr = 0x5109149; + cpu->reset_sctlr = 0x00000070; } static void sa1100_initfn(Object *obj) @@ -249,6 +259,7 @@ static void sa1100_initfn(Object *obj) ARMCPU *cpu = ARM_CPU(obj); set_feature(&cpu->env, ARM_FEATURE_STRONGARM); cpu->midr = ARM_CPUID_SA1100; + cpu->reset_sctlr = 0x00000070; } static void sa1110_initfn(Object *obj) @@ -256,6 +267,7 @@ static void sa1110_initfn(Object *obj) ARMCPU *cpu = ARM_CPU(obj); set_feature(&cpu->env, ARM_FEATURE_STRONGARM); cpu->midr = ARM_CPUID_SA1110; + cpu->reset_sctlr = 0x00000070; } static void pxa250_initfn(Object *obj) @@ -265,6 +277,7 @@ static void pxa250_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA250; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa255_initfn(Object *obj) @@ -274,6 +287,7 @@ static void pxa255_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA255; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa260_initfn(Object *obj) @@ -283,6 +297,7 @@ static void pxa260_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA260; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa261_initfn(Object *obj) @@ -292,6 +307,7 @@ static void pxa261_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA261; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa262_initfn(Object *obj) @@ -301,6 +317,7 @@ static void pxa262_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_XSCALE); cpu->midr = ARM_CPUID_PXA262; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa270a0_initfn(Object *obj) @@ -311,6 +328,7 @@ static void pxa270a0_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_A0; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa270a1_initfn(Object *obj) @@ -321,6 +339,7 @@ static void pxa270a1_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_A1; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa270b0_initfn(Object *obj) @@ -331,6 +350,7 @@ static void pxa270b0_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_B0; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa270b1_initfn(Object *obj) @@ -341,6 +361,7 @@ static void pxa270b1_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_B1; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa270c0_initfn(Object *obj) @@ -351,6 +372,7 @@ static void pxa270c0_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_C0; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void pxa270c5_initfn(Object *obj) @@ -361,6 +383,7 @@ static void pxa270c5_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_IWMMXT); cpu->midr = ARM_CPUID_PXA270_C5; cpu->ctr = 0xd172172; + cpu->reset_sctlr = 0x00000078; } static void arm_any_initfn(Object *obj) diff --git a/target-arm/helper.c b/target-arm/helper.c index a23df14706..eab25ca5ec 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -50,13 +50,10 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) { switch (id) { case ARM_CPUID_ARM926: - env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM946: - env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_ARM1026: - env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM1136: /* This is the 1136 r1, which is a v6K core */ @@ -71,12 +68,10 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) */ memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t)); - env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM1176: memcpy(env->cp15.c0_c1, arm1176_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c2, arm1176_cp15_c0_c2, 8 * sizeof(uint32_t)); - env->cp15.c1_sys = 0x00050078; break; case ARM_CPUID_ARM11MPCORE: memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -89,7 +84,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */ env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */ env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */ - env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA9: memcpy(env->cp15.c0_c1, cortexa9_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -97,7 +91,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_clid = (1 << 27) | (1 << 24) | 3; env->cp15.c0_ccsid[0] = 0xe00fe015; /* 16k L1 dcache. */ env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */ - env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA15: memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t)); @@ -106,7 +99,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_ccsid[0] = 0x701fe00a; /* 32K L1 dcache */ env->cp15.c0_ccsid[1] = 0x201fe00a; /* 32K L1 icache */ env->cp15.c0_ccsid[2] = 0x711fe07a; /* 4096K L2 unified cache */ - env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXM3: break; @@ -114,7 +106,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) break; case ARM_CPUID_TI915T: case ARM_CPUID_TI925T: - env->cp15.c1_sys = 0x00000070; env->cp15.c15_i_max = 0x000; env->cp15.c15_i_min = 0xff0; break; @@ -124,7 +115,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA261: case ARM_CPUID_PXA262: /* JTAG_ID is ((id << 28) | 0x09265013) */ - env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_PXA270_A0: case ARM_CPUID_PXA270_A1: @@ -134,11 +124,9 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA270_C5: /* JTAG_ID is ((id << 28) | 0x09265013) */ env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; - env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_SA1100: case ARM_CPUID_SA1110: - env->cp15.c1_sys = 0x00000070; break; default: cpu_abort(env, "Bad CPU ID: %x\n", id); @@ -173,6 +161,7 @@ void cpu_state_reset(CPUARMState *env) env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; env->cp15.c0_cachetype = cpu->ctr; + env->cp15.c1_sys = cpu->reset_sctlr; #if defined (CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; From 4e851c380eda2bf27ff2ded85e4c80a342e6a72f Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:33 +0000 Subject: [PATCH 21/27] target-arm: Drop JTAG_ID documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit None of the machines in QEMU offer a JTAG debug interface, so this info was unused. Further, the PXA250 ID contradicts the February 2002 Developer's Manual, which has it as 0xn9264013 with n the MIDR Revision. Signed-off-by: Andreas Färber Signed-off-by: Peter Maydell --- target-arm/helper.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index eab25ca5ec..3e31f9446f 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -114,7 +114,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA260: case ARM_CPUID_PXA261: case ARM_CPUID_PXA262: - /* JTAG_ID is ((id << 28) | 0x09265013) */ break; case ARM_CPUID_PXA270_A0: case ARM_CPUID_PXA270_A1: @@ -122,7 +121,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA270_B1: case ARM_CPUID_PXA270_C0: case ARM_CPUID_PXA270_C5: - /* JTAG_ID is ((id << 28) | 0x09265013) */ env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; break; case ARM_CPUID_SA1100: From 0cc892fd97b2d232ae45a30aec342a2e0fb148aa Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:34 +0000 Subject: [PATCH 22/27] target-arm: Move iWMMXT wCID reset to cpu_state_reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the iWMMXT wCID reset to cpu_state_reset(). Since we use the same value for all CPUs with this feature (with the major/minor revision fields set to the QEMU specific 'Q' value) there's no need to create an ARMCPU field just for this. Signed-off-by: Peter Maydell Reviewed-by: Andreas Färber --- target-arm/helper.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 3e31f9446f..319614ae62 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -121,7 +121,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA270_B1: case ARM_CPUID_PXA270_C0: case ARM_CPUID_PXA270_C5: - env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; break; case ARM_CPUID_SA1100: case ARM_CPUID_SA1110: @@ -161,6 +160,10 @@ void cpu_state_reset(CPUARMState *env) env->cp15.c0_cachetype = cpu->ctr; env->cp15.c1_sys = cpu->reset_sctlr; + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { + env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; + } + #if defined (CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; /* For user mode we must enable access to coprocessors */ From 2e4d7e3e3e97c4e0e68aca6221e3e7cb10b6041c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:34 +0000 Subject: [PATCH 23/27] target-arm: Move feature register setup to per-CPU init fns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move feature register value setup to per-CPU init functions. Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/cpu-qom.h | 14 +++++++ target-arm/cpu.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ target-arm/helper.c | 73 +++++++--------------------------- 3 files changed, 122 insertions(+), 59 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 97f7e9099b..7603eff604 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -75,6 +75,20 @@ typedef struct ARMCPU { uint32_t mvfr1; uint32_t ctr; uint32_t reset_sctlr; + uint32_t id_pfr0; + uint32_t id_pfr1; + uint32_t id_dfr0; + uint32_t id_afr0; + uint32_t id_mmfr0; + uint32_t id_mmfr1; + uint32_t id_mmfr2; + uint32_t id_mmfr3; + uint32_t id_isar0; + uint32_t id_isar1; + uint32_t id_isar2; + uint32_t id_isar3; + uint32_t id_isar4; + uint32_t id_isar5; } ARMCPU; static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 74a7d208ba..333f7fc161 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -130,6 +130,13 @@ static void arm1026_initfn(Object *obj) static void arm1136_r2_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an + * older core than plain "arm1136". In particular this does not + * have the v6K features. + * These ID register values are correct for 1136 but may be wrong + * for 1136_r2 (in particular r0p2 does not actually implement most + * of the ID registers). + */ set_feature(&cpu->env, ARM_FEATURE_V6); set_feature(&cpu->env, ARM_FEATURE_VFP); cpu->midr = ARM_CPUID_ARM1136_R2; @@ -138,6 +145,18 @@ static void arm1136_r2_initfn(Object *obj) cpu->mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; + cpu->id_pfr0 = 0x111; + cpu->id_pfr1 = 0x1; + cpu->id_dfr0 = 0x2; + cpu->id_afr0 = 0x3; + cpu->id_mmfr0 = 0x01130003; + cpu->id_mmfr1 = 0x10030302; + cpu->id_mmfr2 = 0x01222110; + cpu->id_isar0 = 0x00140011; + cpu->id_isar1 = 0x12002111; + cpu->id_isar2 = 0x11231111; + cpu->id_isar3 = 0x01102131; + cpu->id_isar4 = 0x141; } static void arm1136_initfn(Object *obj) @@ -152,6 +171,18 @@ static void arm1136_initfn(Object *obj) cpu->mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; + cpu->id_pfr0 = 0x111; + cpu->id_pfr1 = 0x1; + cpu->id_dfr0 = 0x2; + cpu->id_afr0 = 0x3; + cpu->id_mmfr0 = 0x01130003; + cpu->id_mmfr1 = 0x10030302; + cpu->id_mmfr2 = 0x01222110; + cpu->id_isar0 = 0x00140011; + cpu->id_isar1 = 0x12002111; + cpu->id_isar2 = 0x11231111; + cpu->id_isar3 = 0x01102131; + cpu->id_isar4 = 0x141; } static void arm1176_initfn(Object *obj) @@ -166,6 +197,18 @@ static void arm1176_initfn(Object *obj) cpu->mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; + cpu->id_pfr0 = 0x111; + cpu->id_pfr1 = 0x11; + cpu->id_dfr0 = 0x33; + cpu->id_afr0 = 0; + cpu->id_mmfr0 = 0x01130003; + cpu->id_mmfr1 = 0x10030302; + cpu->id_mmfr2 = 0x01222100; + cpu->id_isar0 = 0x0140011; + cpu->id_isar1 = 0x12002111; + cpu->id_isar2 = 0x11231121; + cpu->id_isar3 = 0x01102131; + cpu->id_isar4 = 0x01141; } static void arm11mpcore_initfn(Object *obj) @@ -179,6 +222,18 @@ static void arm11mpcore_initfn(Object *obj) cpu->mvfr0 = 0x11111111; cpu->mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; + cpu->id_pfr0 = 0x111; + cpu->id_pfr1 = 0x1; + cpu->id_dfr0 = 0; + cpu->id_afr0 = 0x2; + cpu->id_mmfr0 = 0x01100103; + cpu->id_mmfr1 = 0x10020302; + cpu->id_mmfr2 = 0x01222000; + cpu->id_isar0 = 0x00100011; + cpu->id_isar1 = 0x12002111; + cpu->id_isar2 = 0x11221011; + cpu->id_isar3 = 0x01102131; + cpu->id_isar4 = 0x141; } static void cortex_m3_initfn(Object *obj) @@ -202,6 +257,19 @@ static void cortex_a8_initfn(Object *obj) cpu->mvfr1 = 0x00011100; cpu->ctr = 0x82048004; cpu->reset_sctlr = 0x00c50078; + cpu->id_pfr0 = 0x1031; + cpu->id_pfr1 = 0x11; + cpu->id_dfr0 = 0x400; + cpu->id_afr0 = 0; + cpu->id_mmfr0 = 0x31100003; + cpu->id_mmfr1 = 0x20000000; + cpu->id_mmfr2 = 0x01202000; + cpu->id_mmfr3 = 0x11; + cpu->id_isar0 = 0x00101111; + cpu->id_isar1 = 0x12112111; + cpu->id_isar2 = 0x21232031; + cpu->id_isar3 = 0x11112131; + cpu->id_isar4 = 0x00111142; } static void cortex_a9_initfn(Object *obj) @@ -223,6 +291,19 @@ static void cortex_a9_initfn(Object *obj) cpu->mvfr1 = 0x01111111; cpu->ctr = 0x80038003; cpu->reset_sctlr = 0x00c50078; + cpu->id_pfr0 = 0x1031; + cpu->id_pfr1 = 0x11; + cpu->id_dfr0 = 0x000; + cpu->id_afr0 = 0; + cpu->id_mmfr0 = 0x00100103; + cpu->id_mmfr1 = 0x20000000; + cpu->id_mmfr2 = 0x01230000; + cpu->id_mmfr3 = 0x00002111; + cpu->id_isar0 = 0x00101111; + cpu->id_isar1 = 0x13112111; + cpu->id_isar2 = 0x21232041; + cpu->id_isar3 = 0x11112131; + cpu->id_isar4 = 0x00111142; } static void cortex_a15_initfn(Object *obj) @@ -242,6 +323,19 @@ static void cortex_a15_initfn(Object *obj) cpu->mvfr1 = 0x11111111; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50078; + cpu->id_pfr0 = 0x00001131; + cpu->id_pfr1 = 0x00011011; + cpu->id_dfr0 = 0x02010555; + cpu->id_afr0 = 0x00000000; + cpu->id_mmfr0 = 0x10201105; + cpu->id_mmfr1 = 0x20000000; + cpu->id_mmfr2 = 0x01240000; + cpu->id_mmfr3 = 0x02102211; + cpu->id_isar0 = 0x02101110; + cpu->id_isar1 = 0x13112111; + cpu->id_isar2 = 0x21232041; + cpu->id_isar3 = 0x11112131; + cpu->id_isar4 = 0x10011142; } static void ti925t_initfn(Object *obj) diff --git a/target-arm/helper.c b/target-arm/helper.c index 319614ae62..84830ff81a 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -7,45 +7,6 @@ #endif #include "sysemu.h" -static uint32_t cortexa15_cp15_c0_c1[8] = { - 0x00001131, 0x00011011, 0x02010555, 0x00000000, - 0x10201105, 0x20000000, 0x01240000, 0x02102211 -}; - -static uint32_t cortexa15_cp15_c0_c2[8] = { - 0x02101110, 0x13112111, 0x21232041, 0x11112131, 0x10011142, 0, 0, 0 -}; - -static uint32_t cortexa9_cp15_c0_c1[8] = -{ 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 }; - -static uint32_t cortexa9_cp15_c0_c2[8] = -{ 0x00101111, 0x13112111, 0x21232041, 0x11112131, 0x00111142, 0, 0, 0 }; - -static uint32_t cortexa8_cp15_c0_c1[8] = -{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 }; - -static uint32_t cortexa8_cp15_c0_c2[8] = -{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 }; - -static uint32_t mpcore_cp15_c0_c1[8] = -{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 }; - -static uint32_t mpcore_cp15_c0_c2[8] = -{ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 }; - -static uint32_t arm1136_cp15_c0_c1[8] = -{ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 }; - -static uint32_t arm1136_cp15_c0_c2[8] = -{ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 }; - -static uint32_t arm1176_cp15_c0_c1[8] = -{ 0x111, 0x11, 0x33, 0, 0x01130003, 0x10030302, 0x01222100, 0 }; - -static uint32_t arm1176_cp15_c0_c2[8] = -{ 0x0140011, 0x12002111, 0x11231121, 0x01102131, 0x01141, 0, 0, 0 }; - static void cpu_reset_model_id(CPUARMState *env, uint32_t id) { switch (id) { @@ -58,43 +19,23 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_ARM1136: /* This is the 1136 r1, which is a v6K core */ case ARM_CPUID_ARM1136_R2: - /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an - * older core than plain "arm1136". In particular this does not - * have the v6K features. - */ - /* These ID register values are correct for 1136 but may be wrong - * for 1136_r2 (in particular r0p2 does not actually implement most - * of the ID registers). - */ - memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t)); - memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t)); break; case ARM_CPUID_ARM1176: - memcpy(env->cp15.c0_c1, arm1176_cp15_c0_c1, 8 * sizeof(uint32_t)); - memcpy(env->cp15.c0_c2, arm1176_cp15_c0_c2, 8 * sizeof(uint32_t)); break; case ARM_CPUID_ARM11MPCORE: - memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t)); - memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t)); break; case ARM_CPUID_CORTEXA8: - memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t)); - memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_clid = (1 << 27) | (2 << 24) | 3; env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */ env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */ env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */ break; case ARM_CPUID_CORTEXA9: - memcpy(env->cp15.c0_c1, cortexa9_cp15_c0_c1, 8 * sizeof(uint32_t)); - memcpy(env->cp15.c0_c2, cortexa9_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_clid = (1 << 27) | (1 << 24) | 3; env->cp15.c0_ccsid[0] = 0xe00fe015; /* 16k L1 dcache. */ env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */ break; case ARM_CPUID_CORTEXA15: - memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t)); - memcpy(env->cp15.c0_c2, cortexa15_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_clid = 0x0a200023; env->cp15.c0_ccsid[0] = 0x701fe00a; /* 32K L1 dcache */ env->cp15.c0_ccsid[1] = 0x201fe00a; /* 32K L1 icache */ @@ -159,6 +100,20 @@ void cpu_state_reset(CPUARMState *env) env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; env->cp15.c0_cachetype = cpu->ctr; env->cp15.c1_sys = cpu->reset_sctlr; + env->cp15.c0_c1[0] = cpu->id_pfr0; + env->cp15.c0_c1[1] = cpu->id_pfr1; + env->cp15.c0_c1[2] = cpu->id_dfr0; + env->cp15.c0_c1[3] = cpu->id_afr0; + env->cp15.c0_c1[4] = cpu->id_mmfr0; + env->cp15.c0_c1[5] = cpu->id_mmfr1; + env->cp15.c0_c1[6] = cpu->id_mmfr2; + env->cp15.c0_c1[7] = cpu->id_mmfr3; + env->cp15.c0_c2[0] = cpu->id_isar0; + env->cp15.c0_c2[1] = cpu->id_isar1; + env->cp15.c0_c2[2] = cpu->id_isar2; + env->cp15.c0_c2[3] = cpu->id_isar3; + env->cp15.c0_c2[4] = cpu->id_isar4; + env->cp15.c0_c2[5] = cpu->id_isar5; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; From 8092d2f031e70eb2664d5fa1d9ed00ef1113ee71 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:35 +0000 Subject: [PATCH 24/27] target-arm: Move OMAP cp15_i_{max,min} reset to cpu_state_reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the OMAP-specific cp15_i_{max,min} reset to cpu_state_reset; since these registers are only accessible on CPUs with the OMAPCP feature set there's no need to guard this reset with either a CPUID or feature bit check. Signed-off-by: Peter Maydell Reviewed-by: Andreas Färber --- target-arm/helper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 84830ff81a..fb618a7e5b 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -47,8 +47,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) break; case ARM_CPUID_TI915T: case ARM_CPUID_TI925T: - env->cp15.c15_i_max = 0x000; - env->cp15.c15_i_min = 0xff0; break; case ARM_CPUID_PXA250: case ARM_CPUID_PXA255: @@ -114,6 +112,7 @@ void cpu_state_reset(CPUARMState *env) env->cp15.c0_c2[3] = cpu->id_isar3; env->cp15.c0_c2[4] = cpu->id_isar4; env->cp15.c0_c2[5] = cpu->id_isar5; + env->cp15.c15_i_min = 0xff0; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; From 85df3786b21191d49d17dcb77f45ae75f6addad0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:35 +0000 Subject: [PATCH 25/27] target-arm: Move cache ID register setup to cpu specific init fns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move cache ID register reset out of cpu_reset_model_id() by creating a field for the reset value in ARMCPU and setting it up in the cpu specific init functions. Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/cpu-qom.h | 5 +++++ target-arm/cpu.c | 11 +++++++++++ target-arm/helper.c | 13 ++----------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 7603eff604..b6c044a251 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -89,6 +89,11 @@ typedef struct ARMCPU { uint32_t id_isar3; uint32_t id_isar4; uint32_t id_isar5; + uint32_t clidr; + /* The elements of this array are the CCSIDR values for each cache, + * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc. + */ + uint32_t ccsidr[16]; } ARMCPU; static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 333f7fc161..8259a0df43 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -270,6 +270,10 @@ static void cortex_a8_initfn(Object *obj) cpu->id_isar2 = 0x21232031; cpu->id_isar3 = 0x11112131; cpu->id_isar4 = 0x00111142; + cpu->clidr = (1 << 27) | (2 << 24) | 3; + cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ + cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ + cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */ } static void cortex_a9_initfn(Object *obj) @@ -304,6 +308,9 @@ static void cortex_a9_initfn(Object *obj) cpu->id_isar2 = 0x21232041; cpu->id_isar3 = 0x11112131; cpu->id_isar4 = 0x00111142; + cpu->clidr = (1 << 27) | (1 << 24) | 3; + cpu->ccsidr[0] = 0xe00fe015; /* 16k L1 dcache. */ + cpu->ccsidr[1] = 0x200fe015; /* 16k L1 icache. */ } static void cortex_a15_initfn(Object *obj) @@ -336,6 +343,10 @@ static void cortex_a15_initfn(Object *obj) cpu->id_isar2 = 0x21232041; cpu->id_isar3 = 0x11112131; cpu->id_isar4 = 0x10011142; + cpu->clidr = 0x0a200023; + cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ + cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ + cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ } static void ti925t_initfn(Object *obj) diff --git a/target-arm/helper.c b/target-arm/helper.c index fb618a7e5b..5cbc7e0656 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -25,21 +25,10 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_ARM11MPCORE: break; case ARM_CPUID_CORTEXA8: - env->cp15.c0_clid = (1 << 27) | (2 << 24) | 3; - env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */ - env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */ - env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */ break; case ARM_CPUID_CORTEXA9: - env->cp15.c0_clid = (1 << 27) | (1 << 24) | 3; - env->cp15.c0_ccsid[0] = 0xe00fe015; /* 16k L1 dcache. */ - env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */ break; case ARM_CPUID_CORTEXA15: - env->cp15.c0_clid = 0x0a200023; - env->cp15.c0_ccsid[0] = 0x701fe00a; /* 32K L1 dcache */ - env->cp15.c0_ccsid[1] = 0x201fe00a; /* 32K L1 icache */ - env->cp15.c0_ccsid[2] = 0x711fe07a; /* 4096K L2 unified cache */ break; case ARM_CPUID_CORTEXM3: break; @@ -113,6 +102,8 @@ void cpu_state_reset(CPUARMState *env) env->cp15.c0_c2[4] = cpu->id_isar4; env->cp15.c0_c2[5] = cpu->id_isar5; env->cp15.c15_i_min = 0xff0; + env->cp15.c0_clid = cpu->clidr; + memcpy(env->cp15.c0_ccsid, cpu->ccsidr, ARRAY_SIZE(cpu->ccsidr)); if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; From caa1d0779e956afe694922ca4bf7e2903356fcff Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:35 +0000 Subject: [PATCH 26/27] target-arm: Drop cpu_reset_model_id() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cpu_reset_model_id() is now empty and we can remove it. Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/helper.c | 59 +-------------------------------------------- 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 5cbc7e0656..653885a418 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -7,66 +7,12 @@ #endif #include "sysemu.h" -static void cpu_reset_model_id(CPUARMState *env, uint32_t id) -{ - switch (id) { - case ARM_CPUID_ARM926: - break; - case ARM_CPUID_ARM946: - break; - case ARM_CPUID_ARM1026: - break; - case ARM_CPUID_ARM1136: - /* This is the 1136 r1, which is a v6K core */ - case ARM_CPUID_ARM1136_R2: - break; - case ARM_CPUID_ARM1176: - break; - case ARM_CPUID_ARM11MPCORE: - break; - case ARM_CPUID_CORTEXA8: - break; - case ARM_CPUID_CORTEXA9: - break; - case ARM_CPUID_CORTEXA15: - break; - case ARM_CPUID_CORTEXM3: - break; - case ARM_CPUID_ANY: /* For userspace emulation. */ - break; - case ARM_CPUID_TI915T: - case ARM_CPUID_TI925T: - break; - case ARM_CPUID_PXA250: - case ARM_CPUID_PXA255: - case ARM_CPUID_PXA260: - case ARM_CPUID_PXA261: - case ARM_CPUID_PXA262: - break; - case ARM_CPUID_PXA270_A0: - case ARM_CPUID_PXA270_A1: - case ARM_CPUID_PXA270_B0: - case ARM_CPUID_PXA270_B1: - case ARM_CPUID_PXA270_C0: - case ARM_CPUID_PXA270_C5: - break; - case ARM_CPUID_SA1100: - case ARM_CPUID_SA1110: - break; - default: - cpu_abort(env, "Bad CPU ID: %x\n", id); - break; - } - -} - /* TODO Move contents into arm_cpu_reset() in cpu.c, * once cpu_reset_model_id() is eliminated, * and then forward to cpu_reset() here. */ void cpu_state_reset(CPUARMState *env) { - uint32_t id; uint32_t tmp = 0; ARMCPU *cpu = arm_env_get_cpu(env); @@ -75,11 +21,8 @@ void cpu_state_reset(CPUARMState *env) log_cpu_state(env, 0); } - id = cpu->midr; tmp = env->cp15.c15_config_base_address; memset(env, 0, offsetof(CPUARMState, breakpoints)); - if (id) - cpu_reset_model_id(env, id); env->cp15.c15_config_base_address = tmp; env->cp15.c0_cpuid = cpu->midr; env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; @@ -144,7 +87,7 @@ void cpu_state_reset(CPUARMState *env) /* v7 performance monitor control register: same implementor * field as main ID register, and we implement no event counters. */ - env->cp15.c9_pmcr = (id & 0xff000000); + env->cp15.c9_pmcr = (cpu->midr & 0xff000000); #endif set_flush_to_zero(1, &env->vfp.standard_fp_status); set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); From 3c30dd5a68e9fee6af67cfd0d14ed7520820f36a Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Apr 2012 17:58:36 +0000 Subject: [PATCH 27/27] target-arm: Move reset handling to arm_cpu_reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that cpu_reset_model_id() has gone we can move the reset code over to the class reset function and have cpu_state_reset simply do a reset on the CPU QOM object. Signed-off-by: Peter Maydell Acked-by: Andreas Färber --- target-arm/cpu.c | 94 +++++++++++++++++++++++++++++++++++++++++-- target-arm/helper.c | 97 +-------------------------------------------- 2 files changed, 92 insertions(+), 99 deletions(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 8259a0df43..cc67d4d9f4 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -20,18 +20,106 @@ #include "cpu-qom.h" #include "qemu-common.h" +#if !defined(CONFIG_USER_ONLY) +#include "hw/loader.h" +#endif /* CPUClass::reset() */ static void arm_cpu_reset(CPUState *s) { ARMCPU *cpu = ARM_CPU(s); ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); + CPUARMState *env = &cpu->env; + uint32_t tmp = 0; + + if (qemu_loglevel_mask(CPU_LOG_RESET)) { + qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); + log_cpu_state(env, 0); + } acc->parent_reset(s); - /* TODO Inline the current contents of cpu_state_reset(), - once cpu_reset_model_id() is eliminated. */ - cpu_state_reset(&cpu->env); + tmp = env->cp15.c15_config_base_address; + memset(env, 0, offsetof(CPUARMState, breakpoints)); + env->cp15.c15_config_base_address = tmp; + env->cp15.c0_cpuid = cpu->midr; + env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; + env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; + env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; + env->cp15.c0_cachetype = cpu->ctr; + env->cp15.c1_sys = cpu->reset_sctlr; + env->cp15.c0_c1[0] = cpu->id_pfr0; + env->cp15.c0_c1[1] = cpu->id_pfr1; + env->cp15.c0_c1[2] = cpu->id_dfr0; + env->cp15.c0_c1[3] = cpu->id_afr0; + env->cp15.c0_c1[4] = cpu->id_mmfr0; + env->cp15.c0_c1[5] = cpu->id_mmfr1; + env->cp15.c0_c1[6] = cpu->id_mmfr2; + env->cp15.c0_c1[7] = cpu->id_mmfr3; + env->cp15.c0_c2[0] = cpu->id_isar0; + env->cp15.c0_c2[1] = cpu->id_isar1; + env->cp15.c0_c2[2] = cpu->id_isar2; + env->cp15.c0_c2[3] = cpu->id_isar3; + env->cp15.c0_c2[4] = cpu->id_isar4; + env->cp15.c0_c2[5] = cpu->id_isar5; + env->cp15.c15_i_min = 0xff0; + env->cp15.c0_clid = cpu->clidr; + memcpy(env->cp15.c0_ccsid, cpu->ccsidr, ARRAY_SIZE(cpu->ccsidr)); + + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { + env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; + } + +#if defined(CONFIG_USER_ONLY) + env->uncached_cpsr = ARM_CPU_MODE_USR; + /* For user mode we must enable access to coprocessors */ + env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { + env->cp15.c15_cpar = 3; + } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { + env->cp15.c15_cpar = 1; + } +#else + /* SVC mode with interrupts disabled. */ + env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; + /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is + clear at reset. Initial SP and PC are loaded from ROM. */ + if (IS_M(env)) { + uint32_t pc; + uint8_t *rom; + env->uncached_cpsr &= ~CPSR_I; + rom = rom_ptr(0); + if (rom) { + /* We should really use ldl_phys here, in case the guest + modified flash and reset itself. However images + loaded via -kernel have not been copied yet, so load the + values directly from there. */ + env->regs[13] = ldl_p(rom); + pc = ldl_p(rom + 4); + env->thumb = pc & 1; + env->regs[15] = pc & ~1; + } + } + env->vfp.xregs[ARM_VFP_FPEXC] = 0; + env->cp15.c2_base_mask = 0xffffc000u; + /* v7 performance monitor control register: same implementor + * field as main ID register, and we implement no event counters. + */ + env->cp15.c9_pmcr = (cpu->midr & 0xff000000); +#endif + set_flush_to_zero(1, &env->vfp.standard_fp_status); + set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); + set_default_nan_mode(1, &env->vfp.standard_fp_status); + set_float_detect_tininess(float_tininess_before_rounding, + &env->vfp.fp_status); + set_float_detect_tininess(float_tininess_before_rounding, + &env->vfp.standard_fp_status); + tlb_flush(env, 1); + /* Reset is a state change for some CPUARMState fields which we + * bake assumptions about into translated code, so we need to + * tb_flush(). + */ + tb_flush(env); } static inline void set_feature(CPUARMState *env, int feature) diff --git a/target-arm/helper.c b/target-arm/helper.c index 653885a418..101031dd75 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2,106 +2,11 @@ #include "gdbstub.h" #include "helper.h" #include "host-utils.h" -#if !defined(CONFIG_USER_ONLY) -#include "hw/loader.h" -#endif #include "sysemu.h" -/* TODO Move contents into arm_cpu_reset() in cpu.c, - * once cpu_reset_model_id() is eliminated, - * and then forward to cpu_reset() here. - */ void cpu_state_reset(CPUARMState *env) { - uint32_t tmp = 0; - ARMCPU *cpu = arm_env_get_cpu(env); - - if (qemu_loglevel_mask(CPU_LOG_RESET)) { - qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); - log_cpu_state(env, 0); - } - - tmp = env->cp15.c15_config_base_address; - memset(env, 0, offsetof(CPUARMState, breakpoints)); - env->cp15.c15_config_base_address = tmp; - env->cp15.c0_cpuid = cpu->midr; - env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; - env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; - env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; - env->cp15.c0_cachetype = cpu->ctr; - env->cp15.c1_sys = cpu->reset_sctlr; - env->cp15.c0_c1[0] = cpu->id_pfr0; - env->cp15.c0_c1[1] = cpu->id_pfr1; - env->cp15.c0_c1[2] = cpu->id_dfr0; - env->cp15.c0_c1[3] = cpu->id_afr0; - env->cp15.c0_c1[4] = cpu->id_mmfr0; - env->cp15.c0_c1[5] = cpu->id_mmfr1; - env->cp15.c0_c1[6] = cpu->id_mmfr2; - env->cp15.c0_c1[7] = cpu->id_mmfr3; - env->cp15.c0_c2[0] = cpu->id_isar0; - env->cp15.c0_c2[1] = cpu->id_isar1; - env->cp15.c0_c2[2] = cpu->id_isar2; - env->cp15.c0_c2[3] = cpu->id_isar3; - env->cp15.c0_c2[4] = cpu->id_isar4; - env->cp15.c0_c2[5] = cpu->id_isar5; - env->cp15.c15_i_min = 0xff0; - env->cp15.c0_clid = cpu->clidr; - memcpy(env->cp15.c0_ccsid, cpu->ccsidr, ARRAY_SIZE(cpu->ccsidr)); - - if (arm_feature(env, ARM_FEATURE_IWMMXT)) { - env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; - } - -#if defined (CONFIG_USER_ONLY) - env->uncached_cpsr = ARM_CPU_MODE_USR; - /* For user mode we must enable access to coprocessors */ - env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; - if (arm_feature(env, ARM_FEATURE_IWMMXT)) { - env->cp15.c15_cpar = 3; - } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { - env->cp15.c15_cpar = 1; - } -#else - /* SVC mode with interrupts disabled. */ - env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; - /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is - clear at reset. Initial SP and PC are loaded from ROM. */ - if (IS_M(env)) { - uint32_t pc; - uint8_t *rom; - env->uncached_cpsr &= ~CPSR_I; - rom = rom_ptr(0); - if (rom) { - /* We should really use ldl_phys here, in case the guest - modified flash and reset itself. However images - loaded via -kernel have not been copied yet, so load the - values directly from there. */ - env->regs[13] = ldl_p(rom); - pc = ldl_p(rom + 4); - env->thumb = pc & 1; - env->regs[15] = pc & ~1; - } - } - env->vfp.xregs[ARM_VFP_FPEXC] = 0; - env->cp15.c2_base_mask = 0xffffc000u; - /* v7 performance monitor control register: same implementor - * field as main ID register, and we implement no event counters. - */ - env->cp15.c9_pmcr = (cpu->midr & 0xff000000); -#endif - set_flush_to_zero(1, &env->vfp.standard_fp_status); - set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); - set_default_nan_mode(1, &env->vfp.standard_fp_status); - set_float_detect_tininess(float_tininess_before_rounding, - &env->vfp.fp_status); - set_float_detect_tininess(float_tininess_before_rounding, - &env->vfp.standard_fp_status); - tlb_flush(env, 1); - /* Reset is a state change for some CPUARMState fields which we - * bake assumptions about into translated code, so we need to - * tb_flush(). - */ - tb_flush(env); + cpu_reset(ENV_GET_CPU(env)); } static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)