FROM_SYSBUS
state = FROM_SYSBUS(sign_gpio_state, sys_bus_dev); // 先頭が SysBusDevice であるという前提があります。 // FROM_SYSBUS を使っていますが、単純なキャストの方がわかりやすい。 // FROM_SYSBUS は sysdev をキーワードに container_of を使いますが // busdev が最初にあるという前提があるため // あまり container_of を使う意味がありません。 // busdev が途中にあっても FROM_SYSBUS は動きますが、 // 違うアドレスを指すはずです。ひどいな、、、
FROM_SYSBUS というマクロがあって container_of を使っているが、、、QEMU はどうやらある構造体が先頭にあることを前提にしているケースがある。暗黙すぎる。例えば、自分の State は SysBusDevice が先頭にあることが前提。
typedef struct sign_gpio_state { SysBusDevice busdev; qemu_irq irq; } sign_gpio_state;
ひどいのは SysBusDeviceInfo 。先頭にDeviceInfo qdevがあることが前提。で、サイズを入れる時は
info->qdev.size = size;
とかしているが、使っている個所では DeviceInfo でアクセスするので
dev = qemu_mallocz(info->size);
こんなんですよ。ついでに書くと初期化ルーチンは
rc = dev->info->init(dev, dev->info);
で第2引数があるが、多くの(すべて?)関数では
unin_pci.c:static int pci_unin_main_init_device(SysBusDevice *dev)
てな具合に一個目しか宣言していない!!
cpu_register_io_memory に渡す関数群はなぜか3つ。なぞ。