qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] QEMU and Kconfig


From: Paolo Bonzini
Subject: Re: [Qemu-devel] QEMU and Kconfig
Date: Wed, 26 Sep 2018 15:36:07 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0

On 26/09/2018 10:32, Peter Maydell wrote:
> On 25 September 2018 at 10:26, Paolo Bonzini <address@hidden> wrote:
>> However, the Kconfig language is a good idea.  The idea is that
>> dependencies can be expressed:
>>
>> - as "select" whenever a board requires a device, or whenever a device
>> requires generic subsystem code in order to implement a controller for
>> that subsystem (e.g.: PC selects MC146818RTC, VIRTIO_SCSI selects SCSI)
>>
>> - as "depends on" whenever a device requires a bus (e.g.: SERIAL_PCI
>> depends on ISA)
>>
>> Putting the two things together, AHCI depends on PCI but it selects IDE.
> 
> Could you clarify the distinction you're making here between
> these two kinds of dependency and what the top level user
> interface would be? I'm getting confused about why we need
> two -- I have a vague impression it depends on what the
> top level thing the user is selecting enablement of is,
> but maybe not ?

Yes, exactly.  The user selects enablement of 1) boards 2) non-embedded
devices.  This mimics the level at which configuration is done today in
default-configs (it worked like this in 2013 during GSoC, and it is
still pretty much the same).  The idea is that everything else is
selected automatically by the configuration tool, but two different
paths are available depending on the desired defaults:

- users of something (that is often "default n") use "select" to force
that configuration symbol to y.  Buses are in this family, and they are
"default n" because you don't really need a bus implementation unless
you have a controller device that exposes that bus.  Embedded devices
are in this family too, because the board will just not work if the
embedded device is not present in the QEMU binary.  Embedded device
might be "default y", and then you have an error if the user forces the
device to "n" but does not do the same on the board that embeds it.

- "depends on" is used for something that is (usually) default y, but
becomes n if the dependencies are missing.  In this case you want by
default all PCI devices to be there if you have a PCI controller in your
machine: PCI is "default n", the PCI controller "selects" PCI, the PCI
devices are "default y" and "depend on" PCI.  However, if PCI is
disabled because there is no PCI controller, then all PCI devices must
be excluded from the binary, and there's no possibility of overriding
that because the code would likely not compile at all.

Here is a minimal example:

# hw/scsi/Kconfig
config SCSI

config ESP
    select SCSI

config ESP_PCI
    default y
    select ESP
    depends on PCI

# hw/pci/Kconfig
config PCI

# hw/pci-host/Kconfig
config PCI_GENERIC
    select PCI

# hw/arm/Kconfig
config ARM_VIRT
    select PCI_GENERIC
    default y

# hw/sparc/Kconfig
config SUN4M
    select ESP
    default y

You have:

- SUN4M selects ESP and SCSI.  User cannot force ESP or SCSI to n in
default-configs/sparc-softmmu.mak, doing that causes the configuration
to fail.  The user can only choose to disable SUN4M itself.

- ARM_VIRT selects PCI_GENERIC, which selects PCI, which allows ESP_PCI
to be y, which selects SCSI.  User cannot force PCI_GENERIC or SCSI to
n, as that causes the configuration to fail.  As in the previous case
they can force ARM_VIRT to n.  However they can also force ESP_PCI to n,
and if you do that ESP and SCSI become n as well.

(In case you're interested, I'm also including the debug output from
minikconf.py for the above sample file).

> Why wouldn't we just say "board Foo
> depends on device Bar" and also "Device Bar depends
> on bus Baz", rather than having two separate concepts?

These two cases are indeed the same concept (but it's "select", not
"depends on").

Paolo

--------------------------------------
Input:
# note: the below is how minikconf parses the input
# each "subclause" is flattened, so "config X select Y"
# becomes "select Y if X"
config PCI default n
config SCSI default n
select SCSI if ESP
config ESP default n
config ESP_PCI default y
select ESP if ESP_PCI
config ESP_PCI depends on PCI
config ESP_PCI default n
select PCI if PCI_GENERIC
config PCI_GENERIC default n
select PCI_GENERIC if ARM_VIRT
config ARM_VIRT default y
config ARM_VIRT default n

Dependency graph:
# The processing order is a topological order, independent of the order
# of the clauses in the input.  So we process the list of clauses to
# gather the dependencies.
ARM_VIRT -> ['PCI_GENERIC']
ESP_PCI -> ['ESP']
ESP -> ['SCSI']
PCI -> ['ESP_PCI']
SCSI -> []
PCI_GENERIC -> ['PCI']

# at this point minikconf uses the topological order
# to process "depends on", "select" and "default" clauses
Sorted clauses:
# The default is applied because ARM_VIRT still has no value
config ARM_VIRT default y
=> ARM_VIRT is now True
# select clauses act as "OR" gates, they force variables to true
select PCI_GENERIC if ARM_VIRT
=> PCI_GENERIC is now True
# The default is ignored because a value has been forced already
config PCI_GENERIC default n
select PCI if PCI_GENERIC
=> PCI is now True
config PCI default n
# "depends on" clauses act as "AND" gates, they force variables to false
# (but not in this case, so there is no "=>" line)
config ESP_PCI depends on PCI
# ... and thus the default is applied
config ESP_PCI default y
=> ESP_PCI is now True
select ESP if ESP_PCI
=> ESP is now True
config ESP default n
select SCSI if ESP
=> SCSI is now True
config SCSI default n

# and the output is...
CONFIG_ARM_VIRT=y
CONFIG_ESP=y
CONFIG_ESP_PCI=y
CONFIG_PCI=y
CONFIG_PCI_GENERIC=y
CONFIG_SCSI=y



reply via email to

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