diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/arch/x86/cpu/qfw_cpu.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot/arch/x86/cpu/qfw_cpu.c')
-rw-r--r-- | roms/u-boot/arch/x86/cpu/qfw_cpu.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/roms/u-boot/arch/x86/cpu/qfw_cpu.c b/roms/u-boot/arch/x86/cpu/qfw_cpu.c new file mode 100644 index 000000000..ee00b8fe7 --- /dev/null +++ b/roms/u-boot/arch/x86/cpu/qfw_cpu.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015 Google, Inc + */ + +#include <common.h> +#include <cpu.h> +#include <dm.h> +#include <malloc.h> +#include <qfw.h> +#include <dm/lists.h> +#include <dm/uclass-internal.h> +#include <dm/root.h> + +int qemu_cpu_fixup(void) +{ + int ret; + int cpu_num; + int cpu_online; + struct uclass *uc; + struct udevice *dev, *pdev, *qfwdev; + struct cpu_plat *plat; + char *cpu; + + /* This will cause the CPUs devices to be bound */ + ret = uclass_get(UCLASS_CPU, &uc); + if (ret) + return ret; + + /* first we need to find '/cpus' */ + for (device_find_first_child(dm_root(), &pdev); + pdev; + device_find_next_child(&pdev)) { + if (!strcmp(pdev->name, "cpus")) + break; + } + if (!pdev) { + printf("unable to find cpus device\n"); + return -ENODEV; + } + + /* get qfw dev */ + ret = qfw_get_dev(&qfwdev); + if (ret) { + printf("unable to find qfw device\n"); + return ret; + } + + /* calculate cpus that are already bound */ + cpu_num = 0; + for (uclass_find_first_device(UCLASS_CPU, &dev); + dev; + uclass_find_next_device(&dev)) { + cpu_num++; + } + + /* get actual cpu number */ + cpu_online = qfw_online_cpus(qfwdev); + if (cpu_online < 0) { + printf("unable to get online cpu number: %d\n", cpu_online); + return cpu_online; + } + + /* bind addtional cpus */ + dev = NULL; + for (; cpu_num < cpu_online; cpu_num++) { + /* + * allocate device name here as device_bind_driver() does + * not copy device name, 8 bytes are enough for + * sizeof("cpu@") + 3 digits cpu number + '\0' + */ + cpu = malloc(8); + if (!cpu) { + printf("unable to allocate device name\n"); + return -ENOMEM; + } + sprintf(cpu, "cpu@%d", cpu_num); + ret = device_bind_driver(pdev, "cpu_qemu", cpu, &dev); + if (ret) { + printf("binding cpu@%d failed: %d\n", cpu_num, ret); + return ret; + } + plat = dev_get_parent_plat(dev); + plat->cpu_id = cpu_num; + } + return 0; +} |