mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
hw/arm: Correctly disable FPU/DSP for some ARMSSE-based boards
The SSE-200 hardware has configurable integration settings which determine whether its two CPUs have the FPU and DSP: * CPU0_FPU (default 0) * CPU0_DSP (default 0) * CPU1_FPU (default 1) * CPU1_DSP (default 1) Similarly, the IoTKit has settings for its single CPU: * CPU0_FPU (default 1) * CPU0_DSP (default 1) Of our four boards that use either the IoTKit or the SSE-200: * mps2-an505, mps2-an521 and musca-a use the default settings * musca-b1 enables FPU and DSP on both CPUs Currently QEMU models all these boards using CPUs with both FPU and DSP enabled. This means that we are incorrect for mps2-an521 and musca-a, which should not have FPU or DSP on CPU0. Create QOM properties on the ARMSSE devices corresponding to the default h/w integration settings, and make the Musca-B1 board enable FPU and DSP on both CPUs. This fixes the mps2-an521 and musca-a behaviour, and leaves the musca-b1 and mps2-an505 behaviour unchanged. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20190517174046.11146-5-peter.maydell@linaro.org
This commit is contained in:
parent
e0cf7b8163
commit
a90a862b9e
3 changed files with 61 additions and 12 deletions
|
@ -38,6 +38,33 @@ struct ARMSSEInfo {
|
||||||
bool has_cachectrl;
|
bool has_cachectrl;
|
||||||
bool has_cpusecctrl;
|
bool has_cpusecctrl;
|
||||||
bool has_cpuid;
|
bool has_cpuid;
|
||||||
|
Property *props;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Property iotkit_properties[] = {
|
||||||
|
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
|
||||||
|
MemoryRegion *),
|
||||||
|
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
|
||||||
|
DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
|
||||||
|
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
|
||||||
|
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
|
||||||
|
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
|
||||||
|
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
|
||||||
|
DEFINE_PROP_END_OF_LIST()
|
||||||
|
};
|
||||||
|
|
||||||
|
static Property armsse_properties[] = {
|
||||||
|
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
|
||||||
|
MemoryRegion *),
|
||||||
|
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
|
||||||
|
DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
|
||||||
|
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
|
||||||
|
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
|
||||||
|
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
|
||||||
|
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
|
||||||
|
DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
|
||||||
|
DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
|
||||||
|
DEFINE_PROP_END_OF_LIST()
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ARMSSEInfo armsse_variants[] = {
|
static const ARMSSEInfo armsse_variants[] = {
|
||||||
|
@ -53,6 +80,7 @@ static const ARMSSEInfo armsse_variants[] = {
|
||||||
.has_cachectrl = false,
|
.has_cachectrl = false,
|
||||||
.has_cpusecctrl = false,
|
.has_cpusecctrl = false,
|
||||||
.has_cpuid = false,
|
.has_cpuid = false,
|
||||||
|
.props = iotkit_properties,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = TYPE_SSE200,
|
.name = TYPE_SSE200,
|
||||||
|
@ -66,6 +94,7 @@ static const ARMSSEInfo armsse_variants[] = {
|
||||||
.has_cachectrl = true,
|
.has_cachectrl = true,
|
||||||
.has_cpusecctrl = true,
|
.has_cpusecctrl = true,
|
||||||
.has_cpuid = true,
|
.has_cpuid = true,
|
||||||
|
.props = armsse_properties,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -533,6 +562,20 @@ static void armsse_realize(DeviceState *dev, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!s->cpu_fpu[i]) {
|
||||||
|
object_property_set_bool(cpuobj, false, "vfp", &err);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!s->cpu_dsp[i]) {
|
||||||
|
object_property_set_bool(cpuobj, false, "dsp", &err);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
|
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
|
||||||
|
@ -1222,16 +1265,6 @@ static const VMStateDescription armsse_vmstate = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Property armsse_properties[] = {
|
|
||||||
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
|
|
||||||
MemoryRegion *),
|
|
||||||
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
|
|
||||||
DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
|
|
||||||
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
|
|
||||||
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
|
|
||||||
DEFINE_PROP_END_OF_LIST()
|
|
||||||
};
|
|
||||||
|
|
||||||
static void armsse_reset(DeviceState *dev)
|
static void armsse_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
ARMSSE *s = ARMSSE(dev);
|
ARMSSE *s = ARMSSE(dev);
|
||||||
|
@ -1244,13 +1277,14 @@ static void armsse_class_init(ObjectClass *klass, void *data)
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
|
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
|
||||||
ARMSSEClass *asc = ARMSSE_CLASS(klass);
|
ARMSSEClass *asc = ARMSSE_CLASS(klass);
|
||||||
|
const ARMSSEInfo *info = data;
|
||||||
|
|
||||||
dc->realize = armsse_realize;
|
dc->realize = armsse_realize;
|
||||||
dc->vmsd = &armsse_vmstate;
|
dc->vmsd = &armsse_vmstate;
|
||||||
dc->props = armsse_properties;
|
dc->props = info->props;
|
||||||
dc->reset = armsse_reset;
|
dc->reset = armsse_reset;
|
||||||
iic->check = armsse_idau_check;
|
iic->check = armsse_idau_check;
|
||||||
asc->info = data;
|
asc->info = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo armsse_info = {
|
static const TypeInfo armsse_info = {
|
||||||
|
|
|
@ -385,6 +385,14 @@ static void musca_init(MachineState *machine)
|
||||||
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
|
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
|
||||||
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
|
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
|
||||||
qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
|
qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
|
||||||
|
/*
|
||||||
|
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
|
||||||
|
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
|
||||||
|
*/
|
||||||
|
if (mmc->type == MUSCA_B1) {
|
||||||
|
qdev_prop_set_bit(ssedev, "CPU0_FPU", true);
|
||||||
|
qdev_prop_set_bit(ssedev, "CPU0_DSP", true);
|
||||||
|
}
|
||||||
object_property_set_bool(OBJECT(&mms->sse), true, "realized",
|
object_property_set_bool(OBJECT(&mms->sse), true, "realized",
|
||||||
&error_fatal);
|
&error_fatal);
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,11 @@
|
||||||
* address of each SRAM bank (and thus the total amount of internal SRAM)
|
* address of each SRAM bank (and thus the total amount of internal SRAM)
|
||||||
* + QOM property "init-svtor" sets the initial value of the CPU SVTOR register
|
* + QOM property "init-svtor" sets the initial value of the CPU SVTOR register
|
||||||
* (where it expects to load the PC and SP from the vector table on reset)
|
* (where it expects to load the PC and SP from the vector table on reset)
|
||||||
|
* + QOM properties "CPU0_FPU", "CPU0_DSP", "CPU1_FPU" and "CPU1_DSP" which
|
||||||
|
* set whether the CPUs have the FPU and DSP features present. The default
|
||||||
|
* (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an
|
||||||
|
* SSE-200 both are present; CPU0 in an SSE-200 has neither.
|
||||||
|
* Since the IoTKit has only one CPU, it does not have the CPU1_* properties.
|
||||||
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
|
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
|
||||||
* which are wired to its NVIC lines 32 .. n+32
|
* which are wired to its NVIC lines 32 .. n+32
|
||||||
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
|
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
|
||||||
|
@ -208,6 +213,8 @@ typedef struct ARMSSE {
|
||||||
uint32_t mainclk_frq;
|
uint32_t mainclk_frq;
|
||||||
uint32_t sram_addr_width;
|
uint32_t sram_addr_width;
|
||||||
uint32_t init_svtor;
|
uint32_t init_svtor;
|
||||||
|
bool cpu_fpu[SSE_MAX_CPUS];
|
||||||
|
bool cpu_dsp[SSE_MAX_CPUS];
|
||||||
} ARMSSE;
|
} ARMSSE;
|
||||||
|
|
||||||
typedef struct ARMSSEInfo ARMSSEInfo;
|
typedef struct ARMSSEInfo ARMSSEInfo;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue