qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: OpenMPIC controller emulation in qemu ?


From: BALATON Zoltan
Subject: Re: OpenMPIC controller emulation in qemu ?
Date: Sat, 18 May 2024 11:39:14 +0200 (CEST)

On Sat, 18 May 2024, Andrew Randrianasulu wrote:
yeah. I  modified openbios like this:

bash-5.1$ cat /dev/shm/new_smp_openbios.txt
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c
index 253394c..7b7b09d 100644
--- a/arch/ppc/qemu/init.c
+++ b/arch/ppc/qemu/init.c
@@ -348,8 +348,9 @@ cpu_add_pir_property(void)
    unsigned long pir;

    asm("mfspr %0, 1023\n"
-        : "=r"(pir) :);
+        : "=r"(pir) :);;
    PUSH(pir);
+    printk("Pir = %lu \n", pir);
    fword("encode-int");
    push_str("reg");
    fword("property");
@@ -381,9 +382,9 @@ static void
cpu_g4_init(const struct cpudef *cpu)
{
    cpu_generic_init(cpu);
-    cpu_add_pir_property();
+        //cpu_add_pir_property();

-    fword("finish-device");
+    //fword("finish-device");
}

#ifdef CONFIG_PPC_64BITSUPPORT
@@ -1073,13 +1074,23 @@ arch_of_init(void)
    push_str("reg");
    fword("property");

+    int i;
+
+    for (i= 0; i<temp; i++) {
    cpu = id_cpu();
    cpu->initfn(cpu);
-    printk("CPU type %s\n", cpu->name);

-    snprintf(buf, sizeof(buf), "/cpus/%s", cpu->name);
+    printk("CPU type %s\n", cpu->name);
+        snprintf(buf, sizeof(buf), "/cpus/%s", cpu->name);
+    PUSH(i);
+        fword("encode-int");
+        push_str("reg");
+        fword("property");
+        fword("finish-device");
+    }
    ofmem_register(find_dev("/memory"), find_dev(buf));
    node_methods_init(buf);
+

#ifdef CONFIG_RTAS
    /* OldWorld Macs don't have an /rtas node. */
bash-5.1$

OK this could be cleaned up but for testing will do and shows the idea.

and now it prints devices correctly in openfirmware!

/dev/shm/qemu-9.0.0/build/qemu-system-ppc -m 512 -M mac99 -smp 4 -nographic
-bios /dev/shm/openbios-qemu.elf

Forget about -smp 4 for now as no real G4 existed with more than 2 CPUs so you're testing an non-existent setup that could lead to additional problems so better just stick to -smp 2 first and make that work before trying more CPUs.

=============================================================
OpenBIOS 1.1 [May 17 2024 14:27]
Configuration device id QEMU version 1 machine id 1
CPUs: 4
Memory: 512M
UUID: 00000000-0000-0000-0000-000000000000
CPU type PowerPC,G4
CPU type PowerPC,G4
CPU type PowerPC,G4
CPU type PowerPC,G4
milliseconds isn't unique.
Welcome to OpenBIOS v1.1 built on May 17 2024 14:27
Trying hd:,\\:tbxi...
Trying hd:,\ppc\bootinfo.txt...
Trying hd:,%BOOT...
No valid state has been set by load or init-program

0 > show-devs
fff56d28 / (bootrom)
fff56e44 /aliases
fff56ee8 /openprom (BootROM)
fff5d110 /openprom/client-services
fff57090 /options
fff57108 /chosen
fff571b8 /builtin
fff5725c /builtin/console
fff5ce1c /packages
fff5e000 /packages/cmdline
fff5e140 /packages/disk-label
fff5fe64 /packages/terminal-emulator
fff60ed0 /packages/deblocker
fff61224 /packages/hfsplus-files
fff615b0 /packages/hfs-files
fff61938 /packages/ext2-files
fff61c5c /packages/iso9660-files
fff61f80 /packages/grubfs-files
fff622a4 /packages/mac-parts
fff62608 /packages/pc-parts
fff62928 /packages/xcoff-loader
fff629f4 /packages/elf-loader
fff62abc /packages/bootinfo-loader
fff5fb8c /cpus
fff6bdf8 /cpus/PowerPC,G4@0 (cpu)
fff6c0ac /cpus/PowerPC,G4@1 (cpu)
fff6c360 /cpus/PowerPC,G4@2 (cpu)
fff6c614 /cpus/PowerPC,G4@3 (cpu)
fff5fc8c /memory@0 (memory)
fff5fd54 /rom@ff800000
fff62be8 /nvram@fff04000 (nvram)
fff62e80 /pci@f2000000 (pci)
fff633a8 /pci@f2000000/mac-io@c (mac-io)
fff63868 /pci@f2000000/mac-io@c/via-cuda@16000 (via-cuda)
fff63a88 /pci@f2000000/mac-io@c/via-cuda@16000/adb (adb)
fff63bf0 /pci@f2000000/mac-io@c/via-cuda@16000/adb/keyboard@8 (keyboard)
fff63dcc /pci@f2000000/mac-io@c/via-cuda@16000/adb/mouse@9 (mouse)
fff63f58 /pci@f2000000/mac-io@c/via-cuda@16000/rtc (rtc)
fff640e8 /pci@f2000000/mac-io@c/via-cuda@16000/power-mgt (power-mgt)
fff642d0 /pci@f2000000/mac-io@c/escc@13000 (escc)
fff643f0 /pci@f2000000/mac-io@c/escc@13000/ch-a@13020 (serial)
fff64648 /pci@f2000000/mac-io@c/escc@13000/ch-b@13000 (serial)
fff64910 /pci@f2000000/mac-io@c/escc-legacy@12000 (escc-legacy)
fff64a34 /pci@f2000000/mac-io@c/escc-legacy@12000/ch-a@12002 (serial)
fff64c50 /pci@f2000000/mac-io@c/escc-legacy@12000/ch-b@12000 (serial)
fff64edc /pci@f2000000/mac-io@c/ata-3@20000 (ata)
fff652ac /pci@f2000000/mac-io@c/ata-3@21000 (ata)
fff6567c /pci@f2000000/mac-io@c/ata-3@21000/cdrom@0 (block)
fff65b18 /pci@f2000000/mac-io@c/interrupt-controller@40000 (open-pic)
fff65d68 /pci@f2000000/usb@d (usb)
fff660b4 /pci@f2000000/QEMU,VGA@e (display)
fff6b688 /pci@f2000000/ethernet@f (network)
fff6bc0c /uni-n@f8000000 (memory-controller)
ok
0 >

void ppc Kernel also boot further:

Quiescing Open Firmware ...
of_client_interface: quiesce
of_client_interface return:
Booting Linux via __start() @ 0x01000000 ...
Hello World !
[    0.000000] Total memory = 512MB; using 1024kB for hash table
[    0.000000] Activating Kernel Userspace Execution Prevention
[    0.000000] Activating Kernel Userspace Access Protection
[    0.000000] Linux version 5.13.12_1 (voidlinux@voidlinux) (gcc (GCC)
10.2.1 20201203, GNU ld (GNU Binutils) 2.35.1) #1 SMP Thu Aug 19 14:12:26
UTC 2021
[    0.000000] ioremap() called early from pmac_feature_init+0xd4/0xad4.
Use early_ioremap() instead
[    0.000000] Found UniNorth memory controller & host bridge @ 0xf8000000
revision: 0x07
[    0.000000] Mapped at 0xf73c0000
[    0.000000] ioremap() called early from probe_one_macio+0x17c/0x2b4. Use
early_ioremap() instead
[    0.000000] Found a Keylargo mac-io controller, rev: 0, mapped at
0x(ptrval)
[    0.000000] PowerMac motherboard: PowerMac G4 AGP Graphics
[    0.000000] ioremap() called early from udbg_scc_init+0x1e4/0x3f8. Use
early_ioremap() instead
[    0.000000] boot stdout isn't a display !
[    0.000000] ioremap() called early from find_via_cuda+0xb4/0x404. Use
early_ioremap() instead
[    0.000000] Using PowerMac machine description
[    0.000000] printk: bootconsole [udbg0] enabled
[    0.000000] CPU maps initialized for 1 thread per core
[    0.000000] -----------------------------------------------------
[    0.000000] phys_mem_size     = 0x20000000
[    0.000000] dcache_bsize      = 0x20
[    0.000000] icache_bsize      = 0x20
[    0.000000] cpu_features      = 0x000000000501a00a
[    0.000000]   possible        = 0x00000000277de14a
[    0.000000]   always          = 0x0000000001000000
[    0.000000] cpu_user_features = 0x9c000001 0x00000000
[    0.000000] mmu_features      = 0x00000001
[    0.000000] Hash_size         = 0x100000
[    0.000000] Hash_mask         = 0x3fff
[    0.000000] -----------------------------------------------------
[    0.000000] ioremap() called early from pmac_setup_arch+0x118/0x290. Use
early_ioremap() instead
[    0.000000] ioremap() called early from pmac_nvram_init+0x150/0x53c. Use
early_ioremap() instead
[    0.000000] nvram: Checking bank 0...
[    0.000000] Invalid signature
[    0.000000] Invalid checksum
[    0.000000] nvram: gen0=0, gen1=0
[    0.000000] nvram: Active bank is: 0
[    0.000000] nvram: OF partition at 0xffffffff
[    0.000000] nvram: XP partition at 0xffffffff
[    0.000000] nvram: NR partition at 0xffffffff
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000000000000-0x000000001fffffff]
[    0.000000]   Normal   empty
[    0.000000]   HighMem  empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x000000001fffffff]
[    0.000000] Initmem setup node 0 [mem
0x0000000000000000-0x000000001fffffff]
[    0.000000] percpu: Embedded 22 pages/cpu s59884 r8192 d22036 u90112
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 129920
[    0.000000] Kernel command line: console=ttyPZ0
[    0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144
bytes, linear)
[    0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072
bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:on, heap free:off
[    0.000000] Kernel virtual memory layout:
[    0.000000]   * 0xf7bdf000..0xfffff000  : fixmap
[    0.000000]   * 0xf7400000..0xf7800000  : highmem PTEs
[    0.000000]   * 0xf7338000..0xf7400000  : early ioremap
[    0.000000]   * 0xe1000000..0xf7338000  : vmalloc & ioremap
[    0.000000] Memory: 500988K/524288K available (10912K kernel code, 1444K
rwdata, 2512K rodata, 1420K init, 516K bss, 23300K reserved, 0K
cma-reserved, 0K highmem)
[    0.000000] random: get_random_u32 called from
__kmem_cache_create+0x38/0x57c with crng_init=0
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
[    0.000000] ftrace: allocating 29527 entries in 87 pages
[    0.000000] ftrace: allocated 87 pages with 5 groups
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=2048 to
nr_cpu_ids=4.
[    0.000000]  Trampoline variant of Tasks RCU enabled.
[    0.000000]  Rude variant of Tasks RCU enabled.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is
25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[    0.000000] NR_IRQS: 512, nr_irqs: 512, preallocated irqs: 16
[    0.000000] mpic: Setting up MPIC " MPIC 1   " version 1.2 at 80040000,
max 4 CPUs
[    0.000000] mpic: ISU size: 68, shift: 7, mask: 7f
[    0.000000] mpic: Initializing for 68 sources
[    0.000000] GMT Delta read from XPRAM: 0 minutes, DST: on
[    0.001126] clocksource: timebase: mask: 0xffffffffffffffff max_cycles:
0x5c40939b5, max_idle_ns: 440795202646 ns
[    0.002717] clocksource: timebase mult[28000000] shift[24] registered
[    0.259907] Console: colour dummy device 80x25
[    2.664336] printk: console [ttyPZ0] enabled
[    2.664336] printk: console [ttyPZ0] enabled
[    2.665884] printk: bootconsole [udbg0] disabled
[    2.665884] printk: bootconsole [udbg0] disabled
[    2.668399] pid_max: default: 32768 minimum: 301
[    2.962041] LSM: Security Framework initializing
[    2.964621] Yama: becoming mindful.
[    3.263901] AppArmor: AppArmor initialized
[    3.561829] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes,
linear)
[    3.563098] Mountpoint-cache hash table entries: 1024 (order: 0, 4096
bytes, linear)
smp_core99_probe
[    7.165726] PowerMac SMP probe found 4 cpus
[    7.464725] Processor timebase sync using GPIO 0x73
[    7.465420] mpic: requesting IPIs...
[    7.765010] CPU0: L2CR is 0
[    8.072220] rcu: Hierarchical SRCU implementation.
[    8.375352] smp: Bringing up secondary CPUs ...
smp_core99_kick_cpu
smp_core99_kick_cpu done
QEMU: Terminated

so, progress! Note that mpic  shows correct n. of supported cpus too!

Looks like it reached the point where it tries to start addirional CPUs but probably we need something for it to work. Now it's important to use a kernel that works on real machine because there are some reports of problems with some kernels:

https://lkml.iu.edu/hypermail/linux/kernel/0110.3/1786.html
http://lists.fixstars.com/yellowdog-general/October01/0545.html

You could try to find logs from real machine that shows what should it look like and compare to what you get on QEMU. From the messages above and the source around smp_core99_kick_cpu in Linux kernel I think it might try to reset secondary CPU and get it start running some code. We may be missing two things:

1. Modify QEMU mac_newworld.c to register different reset routine for CPUs
= 1 that puts the CPU in HALT exception so it does not run until Linux
starts it.
2. Find out how resetting secondary CPUs work. The above message talks about some Keylargo GPIO so it may need to be emulated and connected to something to do a reset on the secondary CPU (this may be the reason why more than two CPUs won't work when there's no way to connect them but I don't know how it works just guess the hardware may have some limitations as it wasn't designed for more than 2 CPUs).

Also, i modded my line setting

env->spr_cb[SPR_PIR].default_value  = i + 15;

and "15" showed up in openfirmware startup before I commented it out for my
hack. so, this part of qemu works,
just no idea how to force openfirmware to probe all cpus for this reg in
turn? ofcourse if fw will start with only one active cpu it can't

I think the above is enough information for Mark to find a way to fix it in OpenBIOS so you could go on and try to find out what else is needed in QEMU for it to get further and run the second CPU.

as far as I understand e500 machine driven by uboot, not OpenFirmware ?

Yes, but that does not matter for how the CPUs are init by Linux. The Linux doc said and the logs seems to confirm that it should start running with CPU0 with other CPUs in halt then it will kick the secondary CPU out of halt by a reset after setting the reset vector to code for that CPU. If currently QEMU just starts all CPUs with OpenBIOS and OpenBIOS has nothing to detect that and halt the additional CPUs then it may run the kernel on all CPUs and may also miss the emulation of the mechanism to reset secondaty CPU so it can't get it to start the code intended for it and gets stuck at that point. This is all guessing from the above but I think it's what plausibly happens and there could be several ways to fix it but to test the easiest may be to get QEMU halt secondary CPU the same way it does for e500 and implement the register in Keylargo to reset the secondary CPU. If that works then we can think about if this should be handled by OpenBIOS or by QEMU but that could also be changed later. I would not worry about that too much yet as there could be other problem ahead after this one so let's fix this for now and see what else is there.

Regards,
BALATON Zoltan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]