A tale of reusability in coreboot

Furquan Shaikh Table of contents - Introduction to Chrome OS and Chrome OS Platform Model - Objectives - SSDT generation - Baseboard and Variant Structure - Override devicetree - Current challenges Once upon a time…... What is Chrome OS ?

Chrome

Linux kernel

depthcharge Libraries (e.g. blobs, third- vboot) coreboot party f/w, FSP

AARCH64 ARM32 ... What does Chrome OS platform look like ?

Chrome Keyboard

TCPC EC Touchscreen

depthcharge Librarie Trackpad s (e.g. vboot) blobs, third- coreboot party f/w, FSP Camera PMIC TPM AARCH64 ARM32 X86 ... Audio

Controllers Application Processor Peripherals Traditional Chrome OS Platform Model

Google Reference Platform

OEM #1 Lead Device

OEM #2 OEM #3 OEM #4 OEM #5 Follower Device Follower Device Follower Device Follower Device Traditional Chrome OS Platform Model

Google Reference glados Platform

OEM #1 Lead chell Device

OEM #2 OEM #3 OEM #4 OEM #5 Follower Follower Follower Follower caroline cave Device Device Device Device Traditional Chrome OS Platform Model

Google Reference reef Platform

OEM #1 Lead reef Device

OEM #2 OEM #3 OEM #4 OEM #5 Follower Follower Follower Follower nasher pyro sand snappy Device Device Device Device Traditional ‸ Chrome OS Platform Model

Google Reference reef Platform

coral

OEM #1 OEM #2 OEM #3 OEM #4 astronaut robo santa nasher ... Device Device Device Device Traditional ‸ Chrome OS Platform Model

Google Reference octopus Platform

yorp bip

OEM #1 OEM #2 OEM #3 OEM #4 phaser meep fleex bobba ... Device Device Device Device but…... Objectives

- Faster time to market for all OEMs - More flexibility to OEMs w.r.t components - Avoid duplication of work within software stack - Make it manageable for everyone - Make the whole process scalable Glados

2 2 = Board glados 1 1 = Arch/SoC/library

2 chell 1

2 2 caroline cave 1 1

Hardware view Software view mainboard.asl file https://chromium.googlesource.com/chromiumos/third https://chromium.googlesource.com/chromiumos/third https://chromium.googlesource.com/chromiumos/third _party/coreboot/+/firmware-glados- _party/coreboot/+/firmware-glados- _party/coreboot/+/firmware-glados- 7820.B/src/mainboard/google/glados/acpi/mainboard.a 7820.B/src/mainboard/google/chell/acpi/mainboard.asl 7820.B/src/mainboard/google/caroline/acpi/mainboard. sl asl Scope (\_SB.PCI0.I2C0) Scope (\_SB.PCI0.I2C0) Scope (\_SB.PCI0.I2C0) { { { /* Touchscreen */ Name (FMCN, Package () { 72, 160, 30 }) Name (FMCN, Package () { 87, 197, 26 }) Device (ELTS) { /* Touchscreen */ Device (ATSA) Name (_HID, "ELAN0001") Device (ELTS) { Name (_DDN, "Elan Touchscreen") { Name (_HID, "ATML0001") Name (_UID, 1) Name (_HID, "ELAN0001") Name (_DDN, "Atmel Touchscreen") Name (_S0W, 4) Name (_DDN, "Elan Touchscreen") Name (_UID, 1) Name (_UID, 1) Name (_S0W, 4) Name (_CRS, ResourceTemplate () Name (_S0W, 4) { Name (_CRS, ResourceTemplate () I2cSerialBus ( Name (_CRS, ResourceTemplate () { BOARD_TOUCHSCREEN_I2C_ADDR , { I2cSerialBus ( ControllerInitiated, I2cSerialBus ( BOARD_TOUCHSCREEN_I2C_ADDR , 400000, BOARD_TOUCHSCREEN_I2C_ADDR , ControllerInitiated, AddressingMode7Bit, ControllerInitiated, 400000, "\\_SB.PCI0.I2C0", 400000, AddressingMode7Bit, ) AddressingMode7Bit, "\\_SB.PCI0.I2C0", Interrupt (ResourceConsumer, Edge, "\\_SB.PCI0.I2C0", ) ActiveLow) ) Interrupt (ResourceConsumer, Edge, { Interrupt (ResourceConsumer, Edge, ActiveLow) BOARD_TOUCHSCREEN_IRQ ActiveLow) { } { BOARD_TOUCHSCREEN_IRQ }) BOARD_TOUCHSCREEN_IRQ } } }) Method (_STA) }) { Method (_STA) Return (0xF) Method (_STA) { } { Return (0xF) } Return (0xF) } } } } } } } SSDT generation in coreboot

- Runtime addition of device nodes to ACPI SSDT 1 based on device properties. - Relieves developers from the hectic task of defining device nodes in ASL. - Driver in ramstage responsible for generation of the nodes at runtime. - Examples: - src/drivers/i2c/generic - src/drivers/spi/acpi - src/drivers/generic/gpio_keys -… - soc/.../.../chip. -… - git grep “acpi_fill_ssdt_generator”

1. SSDT - Secondary System Description Table (https://www.uefi.org/acpi/specs) SSDT generation in coreboot https://chromium.googlesource.com/chromiumos/third_p https://review.coreboot.org/cgit/coreboot.git/tree/src/mainboard/g arty/coreboot/+/firmware-glados- oogle/glados/variants/glados/devicetree.cb?id=refs/heads/master 7820.B/src/mainboard/google/glados/acpi/mainboard.asl

Scope (\_SB.PCI0.I2C0) device pci 15.0 on { chip drivers/i2c/generic SSDT /* Touchscreen */ register "hid" = ""ELAN0001"" Device (ELTS) register "desc" = ""ELAN Touchscreen"" generator { register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_E7_IRQ)" Name (_HID, "ELAN0001") device i2c 10 on end driver Name (_DDN, "Elan Touchscreen") end Name (_UID, 1) end # I2C #0 Name (_S0W, 4)

Name (_CRS, ResourceTemplate () { I2cSerialBus ( BOARD_TOUCHSCREEN_I2C_ADDR, ControllerInitiated, 400000, AddressingMode7Bit, "\\_SB.PCI0.I2C0", ) Interrupt (ResourceConsumer, Edge, ActiveLow) { BOARD_TOUCHSCREEN_IRQ } })

Method (_STA) { Return (0xF) } } } Reef

2 3 reef 3 = ?? 1 2 = ??

1 = Arch/SoC/library 2 3 reef 1

2 3 2 3 2 3 2 3 nasher pyro sand snappy 1 1 1 1

Hardware view Software view Baseboard and Variant Structure

Glados and followers Reef and followers src/ src/ mainboard/ mainboard/ google/ google/ glados/ reef/ chell/ variants/ caroline/ baseboard/ cave/ nasher/ pyro/ reef/ sand/ snappy/ Baseboard and Variant Structure

3 = Variant 2 3 reef 2 = Baseboard 1 1 = Arch/SoC/library

2 3 reef 1

2 3 2 3 2 3 2 3 nasher pyro sand snappy 1 1 1 1

Hardware view Software view Baseboard and Variant Structure

# wc -l `find variants/baseboard/ -type f` # wc -l `find variants/reef/ -type f` 48 variants/baseboard/nhlt.c 16 variants/reef/include/variant/acpi/dptf.asl 234 variants/baseboard/devicetree.cb 21 variants/reef/include/variant/ec.h 396 variants/baseboard/gpio.c 21 variants/reef/include/variant/gpio.h 54 variants/baseboard/include/baseboard/variants.h 58 total 81 variants/baseboard/include/baseboard/acpi/dptf.asl 80 variants/baseboard/include/baseboard/ec.h # wc -l `find . -not -path "./variants/*" -type f` 53 variants/baseboard/include/baseboard/gpio.h 6 ./board_info.txt 170 variants/baseboard/memory.c 68 ./dsdt.asl 8 variants/baseboard/Makefile.inc 148 ./mainboard.c 1124 total 112 ./Kconfig 61 ./ec.c # wc -l `find variants/nasher/ -type f` # wc -l `find variants/sand/ -type f` 54 ./chromeos.fmd 18 variants/nasher/include/variant/acpi/dptf.asl 230 variants/sand/devicetree.cb 52 ./smihandler.c 17 variants/nasher/include/variant/ec.h 81 variants/sand/include/variant/acpi/dptf.asl 14 ./acpi_tables.c 17 variants/nasher/include/variant/gpio.h 81 variants/sand/include/variant/ec.h 31 ./Kconfig.name 52 total 17 variants/sand/include/variant/gpio.h 32 ./bootblock.c 409 total 50 ./chromeos.c 29 ./romstage.c 17 ./Makefile.inc 674 total

# wc -l `find variants/pyro/ -type f` # wc -l `find variants/snappy/ -type f` 249 variants/pyro/devicetree.cb 123 variants/snappy/mainboard.c 81 variants/pyro/include/variant/acpi/dptf.asl 286 variants/snappy/devicetree.cb 21 variants/pyro/include/variant/ec.h 82 variants/snappy/include/variant/acpi/dptf.asl 21 variants/pyro/include/variant/gpio.h 24 variants/snappy/include/variant/ec.h 114 variants/pyro/memory.c 21 variants/snappy/include/variant/gpio.h 1 variants/pyro/Makefile.inc 1 variants/snappy/Makefile.inc 487 total 537 total Coral

3 = Variant 2 3 2 = Baseboard reef 1 1 = Arch/SoC/library

2 3 coral 1

2 3 2 3 2 3 2 3 astronaut robo santa nasher 1 1 1 1

Hardware view Software view Octopus 3 = Variant

2 2 = Baseboard octopus 1 1 = Arch/SoC/library

2 3 2 3 yorp bip 1 1

2 3 2 3 2 3 2 3 phaser meep fleex bobba 1 1 1 1

Hardware view Software view Devicetree duplication # diff sand/devicetree.cb baseboard/devicetree.cb | # wc -l `find variants/sand/ -type f` wc -l 230 variants/sand/devicetree.cb 16 81 variants/sand/include/variant/acpi/dptf.asl 81 variants/sand/include/variant/ec.h # wc -l sand/devicetree.cb baseboard/devicetree.cb 17 variants/sand/include/variant/gpio.h 409 total 230 sand/devicetree.cb 234 baseboard/devicetree.cb

# diff pyro/devicetree.cb baseboard/devicetree.cb | wc # wc -l `find variants/pyro/ -type f` -l 249 variants/pyro/devicetree.cb 63 81 variants/pyro/include/variant/acpi/dptf.asl 21 variants/pyro/include/variant/ec.h # wc -l pyro/devicetree.cb baseboard/devicetree.cb 21 variants/pyro/include/variant/gpio.h 114 variants/pyro/memory.c 249 pyro/devicetree.cb 1 variants/pyro/Makefile.inc 234 baseboard/devicetree.cb 487 total

# diff snappy/devicetree.cb baseboard/devicetree.cb | # wc -l `find variants/snappy/ -type f` wc -l 123 variants/snappy/mainboard.c 77 286 variants/snappy/devicetree.cb 82 variants/snappy/include/variant/acpi/dptf.asl # wc -l snappy/devicetree.cb baseboard/devicetree.cb 24 variants/snappy/include/variant/ec.h 21 variants/snappy/include/variant/gpio.h 286 snappy/devicetree.cb 1 variants/snappy/Makefile.inc 234 baseboard/devicetree.cb 537 total Override devicetree

- sconfig utility updated to allow variants to specify an override tree. - Applies variant specific overrides on top the properties specified by the base devicetree. - Rules for overriding: - If a property is present only in the override tree, then it takes effect. - If a property is present in base tree as well as override tree, then the value in override tree takes effect. - If a device has a chip associated with it in the override tree, then that device gets added to the appropriate parent in base tree. - If the parent device in base tree already has some children, then the device in override tree is added as a sibling of the children in base tree. Override devicetree

- Enabling override tree is as simple as: - Setting OVERRIDE_DEVICETREE to point to variants tree - Setting properties and device info in variants tree specific to the variant

- sconfig will walk through the base tree and override tree in lockstep fashion applying properties and device nodes as appropriate.

- A good example of override devicetree usage is octopus: https://review.coreboot.org/c/coreboot/+/27219/ Summary

glados reef coral octopus What’s next? Current challenges - GPIO config table duplication

- Baseboard provides one of GPIO configs. - Variant can either: - Use the one provided by the baseboard, or - Supply its own table of GPIO configs. - Pros: - No need to copy the same table over and over if variants have the GPIOs routed the same way in hardware as the baseboard. - Cons: - If even one GPIO is different, then either variant needs to: - Provide a copy of baseboard table and change that one GPIO. - Call GPIO configuration after baseboard configuration is done - None of the above options are optimal Current challenges - GPIO config table duplication

- Current workaround - gpio_configure_pads_with_override - Baseboard provides its default GPIO config table. - Variant provides an override table with only the GPIOs that are different from the baseboard. - gpio_configure_pads_with_override loops through all the GPIOs in base table and checks if there is an override present for it in the override table. - Yes: Applies the configuration from override table. - No: Applies the configuration from base table. - What else can be done? The End Questions?