@@ -58,13 +58,55 @@ static void riscv_hart_realize(RISCVHartArrayState *s, int hart,
static void riscv_harts_realize(DeviceState *dev, Error **errp)
{
RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
- int n;
+ char *cpu_types;
+ char *first_type, *last_type, *tmp_type;
+ int n = 0;
s->harts = g_new0(RISCVCPU, s->num_harts);
- for (n = 0; n < s->num_harts; n++) {
- riscv_hart_realize(s, n, s->cpu_type, errp);
+ /* we should not touch the original s->cpu_type */
+ cpu_types = g_strdup(s->cpu_type);
+
+ /*
+ * Expect s->cpu_type property was initialized this way:
+ *
+ * "cpu-type-a": symmetric harts
+ * "cpu-type-a,cpu-type-b,cpu-type-c": heterogeneous harts
+ *
+ * For heterogeneous harts, hart cpu types are separated by delimiter ",".
+ * The frist cpu type before the delimiter is assigned to hart 0, and the
+ * second cpu type before delimiter is assigned to hart 1, and so on.
+ *
+ * If the total number of cpu types is less than s->num_harts, the last
+ * cpu type in s->cpu_type will be used to populate remaining harts.
+ */
+
+ first_type = strtok(cpu_types, ",");
+ riscv_hart_realize(s, n++, first_type, errp);
+ tmp_type = strtok(NULL, ",");
+ if (!tmp_type) {
+ /* symmetric harts */
+ for (; n < s->num_harts; n++) {
+ riscv_hart_realize(s, n, first_type, errp);
+ }
+ } else {
+ /* heterogeneous harts */
+ while (tmp_type) {
+ if (n >= s->num_harts) {
+ break;
+ }
+ riscv_hart_realize(s, n++, tmp_type, errp);
+ last_type = tmp_type;
+ tmp_type = strtok(NULL, ",");
+ }
+
+ /* populate remaining harts using the last cpu type in s->cpu_type */
+ for (; n < s->num_harts; n++) {
+ riscv_hart_realize(s, n, last_type, errp);
+ }
}
+
+ g_free(cpu_types);
}
static void riscv_harts_class_init(ObjectClass *klass, void *data)
At present we only allow symmetric harts to be created. In order to support heterogeneous harts like SiFive FU540, update hart array's "cpu-type" property to allow cpu type to be set per hart, separated by delimiter ",". The frist cpu type before the delimiter is assigned to hart 0, and the second cpu type before delimiter is assigned to hart 1, and so on. If the total number of cpu types supplied in "cpu-type" property is less than number of maximum harts, the last cpu type in the property will be used to populate remaining harts. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> --- Changes in v3: None Changes in v2: None hw/riscv/riscv_hart.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-)