新千葉 ガーベージ・コレクション

FPGA マガジンやインターフェースで書けなかったこと等をちょぼちょぼ書いてます。@ryos36

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つ。なぞ。