I did not see your patch until I had already hacked in some code to read the level register just to see if my trace of macio* would log the reads.

It seem to me the state of the level registers should not be zero at boot, that Linux would read the level registers first to we the state of the gpio so it would know what registers to write to when it tries to kick the second cpu?



On Feb 22, 2025, at 9:37 AM, BALATON Zoltan <balaton@eik.bme.hu> wrote:

On Sat, 22 Feb 2025, Jd Lyons wrote:
Ok the level register are read-only but that does not mean their status can not change, writes to the other register can change the status of the level registers because they should reflect the state of the mappings of the gpio, or something like that…

Maybe but probably OS only cares about level for input GPIOs. For GPIOs set to output it probably only writes them. Why would it want to read their state when it just set it and knows what state is it.

I but in a function to read the status of the level registers when the MacIO device resets (via macio_gpio_reset)

I get this logged at boot:

trace_macio_gpio_read: addr=0x0, val=0x0
trace_macio_gpio_read: addr=0x1, val=0x0
trace_macio_gpio_read: addr=0x2, val=0x0
trace_macio_gpio_read: addr=0x3, val=0x0
trace_macio_gpio_read: addr=0x4, val=0x0
trace_macio_gpio_read: addr=0x5, val=0x0
trace_macio_gpio_read: addr=0x6, val=0x0
trace_macio_gpio_read: addr=0x7, val=0x0

How? macio_gpio_reset only calls macio_set_gpio(s, 1, true);

Then when this is written by the linux kernel trying to ‘kick’ CPU1 to start
macio_gpio_write addr: 0xc value: 0x4
macio_gpio_write addr: 0xc value: 0x0

I get this logged:

trace_macio_gpio_read: addr=0x4, val=0x4
trace_macio_gpio_read: addr=0x4, val=0x0

I can't make sense of these log excerpts so I have no idea what you're doing. Either post more meaningful logs showing what the kernel does or you're on your own.

So we know that macio_gpio_reset is called when linux tries to ‘kick’ the second CPU.

No, reset is called when QEMU starts or when the macio device is reset. The part that kicks additional CPUs out of halt only writes the macio gpio regs so you should see trace_macio_gpio_read and trace_macio_gpio_write calls at that point. The problem is that qemu/hw/misc/macio/gpio.c does not seem to emulate what the real chip should do so this should be fixed. For example macio_gpio_read returns s->gpio_levels[addr]; for reading the level regs but nothing ever sets the gpio_levels so it will always read 0. This may not be an issue if there are no input GPIOs involved. macio_gpio_write also does not set any GPIO level so no matter what the guest writes here it won't have any effect. It should set the GPIO level for output GPIOs but then you still won't see it doing anything before also connecting that GPIO line somewhere.

Notice that it no longer tries to write to 0x4, I’m not sure why, my code causes linux to not try and write any values to the status register????

I don't know what your code is. If you see reads now after applying my patch then that just corrected the logs. These were always reads erroneously logged as writes that I was telling you to fix for days so you actually see what is happening and not base theories on wrong logs. You could also read what the Linux source does that I'm also telling you to do for a few days. You won't be able to figure this out without reading the linux/arch/powerpc/platforms/powermac/feature.c::core99_reset_cpu() function and qemu/hw/misc/macio/gpio.c files and understand what they are doing. These aren't too complex so if you can't read and understand these go back and start with some C programming tutorial to be able to understand what these code parts do.

Regards,
BALATON Zoltan