On Mon, 8 Aug 2022 at 18:05, BALATON Zoltan <balaton@eik.bme.hu> wrote:
But the handler we register here just calls cpu_reset which seems to just
call the reset method of the CPU object. If we have nothing else to do
here do we need to explicitly call cpi_reset like this? Wouldn't the CPU
object be reset by qdev when resetting the machine or the soc its in? If
we have our own reset method we may call cpu_reset from there to make sure
the CPU is in a known state but is this needed when we don't want to do
anything else? I don't know how reset handling works but some machines
seems to do this and others don't.
You do unfortunately need to manually reset the CPU object. This is
because the 'automatic' qdev reset only works for devices that hang
off a bus (including sysbus devices). This is because it works by
having qdev_machine_creation_done() register a reset function which
does "reset the sysbus". Resetting a bus resets every device on it.
Resetting a device resets every bus it owns. (This means that for
instance PCI devices get reset because the PCI controller is on the
sysbus, so it gets reset, and it owns the PCI bus, so the PCI bus
resets when the controller is reset, and when the PCI bus resets
then all the devices on it are reset.) So reset propagates down
the bus tree, but it won't reach devices which aren't on that bus
tree at all. The most common case of "device which isn't on a bus"
is the CPU objects.
This is, clearly, a complete mess. I would strongly like to sort it
out, but to do that we need (a) a plan for what reset handling ought
to look like and (b) a transition plan for getting from here to there
without breaking everything in the process. I haven't had the time
to focus on that, though it's been nominally on my todo list for years.
In the meantime, it's the responsibility of something in architecture
specific code to arrange for the CPU objects to be reset -- whether
that's done directly by the board, or hidden in some other layer
of code, depends on the target arch. For instance for arm it's
hidden inside arm_load_kernel() and board models must therefore
call that function even if they have no intention of supporting
loading Linux kernels. For sparc it's done directly in the board code.