On 26/09/2018 10:32, Peter Maydell wrote: > On 25 September 2018 at 10:26, Paolo Bonzini <pbonz...@redhat.com> 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