From 10aa5ebf03707376729dda70e0131de613e53ae2 Mon Sep 17 00:00:00 2001
From: Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
Date: Fri, 18 Nov 2022 13:59:10 +0100
Subject: [PATCH] pci_decode: report devices from ACPI info

Although we do not have the full ACPI information parsed yet, to
announce non-PCI devices derived from the ACPI tables, the device
description of the assumed devices is now integral-part of pci_decode.
Formerly, the information was gained separatedly as boot-module, whereby
we lost synchronization in between ACPI/PCI parsing, BIOS handover, and
PS/2 emulation code already acting.
---
 .../recipes/pkg/drivers_managed-pc/archives   |   1 -
 repos/gems/sculpt/drivers/pc                  |  24 +---
 repos/libports/run/acpica.run                 |  29 +---
 .../pkg/drivers_interactive-pc/archives       |   1 -
 .../raw/drivers_interactive-pc/drivers.config |  28 +---
 repos/os/src/app/pci_decode/main.cc           | 128 ++++++++++++------
 repos/pc/recipes/raw/pc-devices/content.mk    |   4 -
 repos/pc/recipes/raw/pc-devices/hash          |   1 -
 8 files changed, 97 insertions(+), 119 deletions(-)
 delete mode 100644 repos/pc/recipes/raw/pc-devices/content.mk
 delete mode 100644 repos/pc/recipes/raw/pc-devices/hash

diff --git a/repos/gems/recipes/pkg/drivers_managed-pc/archives b/repos/gems/recipes/pkg/drivers_managed-pc/archives
index 8a7135141d..23edcacd3b 100644
--- a/repos/gems/recipes/pkg/drivers_managed-pc/archives
+++ b/repos/gems/recipes/pkg/drivers_managed-pc/archives
@@ -18,4 +18,3 @@ _/src/driver_manager
 _/src/rom_filter
 _/src/rom_reporter
 _/raw/drivers_managed-pc
-_/raw/pc-devices
diff --git a/repos/gems/sculpt/drivers/pc b/repos/gems/sculpt/drivers/pc
index 937d982e1d..5f525a132c 100644
--- a/repos/gems/sculpt/drivers/pc
+++ b/repos/gems/sculpt/drivers/pc
@@ -41,7 +41,7 @@
 		<config verbose="no">
 			<policy label="pci_decode -> system"            report="acpi_drv -> acpi"/>
 			<policy label="platform_drv -> acpi"            report="acpi_drv -> acpi"/>
-			<policy label="rom_filter -> pci_devices"       report="pci_decode -> devices"/>
+			<policy label="platform_drv -> devices"         report="pci_decode -> devices"/>
 			<policy label="usb_drv -> config"               report="driver_manager -> usb_drv.config"/>
 			<policy label="dynamic -> config"               report="driver_manager -> init.config"/>
 			<policy label="driver_manager -> devices"       report="platform_drv -> devices"/>
@@ -115,33 +115,13 @@
 		</route>
 	</start>
 
-	<start name="rom_filter" caps="70">
-		<resource name="RAM" quantum="1M"/>
-		<provides> <service name="ROM" /> </provides>
-		<config buffer="32K">
-			<input name="devices"/>
-			<input name="pci_devices"/>
-			<output node="devices">
-				<input name="devices"     skip_toplevel="yes"/>
-				<input name="pci_devices" skip_toplevel="yes"/>
-			</output>
-		</config>
-		<route>
-			<service name="ROM" label="pci_devices"> <child name="report_rom"/> </service>
-			<service name="LOG"> <parent/> </service>
-			<service name="PD">  <parent/> </service>
-			<service name="CPU"> <parent/> </service>
-			<service name="ROM"> <parent/> </service>
-		</route>
-	</start>
-
 	<start name="platform_drv" caps="400" managing_system="yes">
 		<binary name="pc_platform_drv"/>
 		<resource name="RAM" quantum="4M"/>
 		<provides> <service name="Platform"/> </provides>
 		<route>
 			<service name="ROM" label="system">  <parent label="system"/> </service>
-			<service name="ROM" label="devices"> <child name="rom_filter"/> </service>
+			<service name="ROM" label="devices"> <child name="report_rom"/> </service>
 			<service name="ROM" label="acpi">    <child name="report_rom"/> </service>
 			<service name="Report" label="devices"> <child name="report_rom"/> </service>
 			<service name="IRQ">     <parent/> </service>
diff --git a/repos/libports/run/acpica.run b/repos/libports/run/acpica.run
index 8055927ecf..2a4ed38e2f 100644
--- a/repos/libports/run/acpica.run
+++ b/repos/libports/run/acpica.run
@@ -24,7 +24,6 @@ import_from_depot [depot_user]/src/dynamic_rom \
                   [depot_user]/src/event_filter \
                   [depot_user]/src/pc_usb_host_drv \
                   [depot_user]/src/ps2_drv \
-                  [depot_user]/src/rom_filter \
                   [depot_user]/src/report_rom \
                   [depot_user]/src/usb_hid_drv
 
@@ -57,9 +56,9 @@ set config {
 				<service name="ROM"/>
 			</provides>
 			<config verbose="no">
-				<policy label="pci_decode -> system" report="acpi_drv -> acpi"/>
-				<policy label="rom_filter -> pci_devices" report="pci_decode -> devices"/>
-				<policy label="usb_hid_drv -> report" report="usb_drv -> devices"/>
+				<policy label="pci_decode -> system"    report="acpi_drv -> acpi"/>
+				<policy label="platform_drv -> devices" report="pci_decode -> devices"/>
+				<policy label="usb_hid_drv -> report"   report="usb_drv -> devices"/>
 			</config>
 		</start>
 
@@ -80,26 +79,6 @@ set config {
 			</route>
 		</start>
 
-		<start name="rom_filter" caps="70">
-			<resource name="RAM" quantum="1M"/>
-			<provides> <service name="ROM"/> </provides>
-			<config buffer="32K">
-				<input name="devices"/>
-				<input name="pci_devices"/>
-				<output node="devices">
-					<input name="devices"     skip_toplevel="yes"/>
-					<input name="pci_devices" skip_toplevel="yes"/>
-				</output>
-			</config>
-			<route>
-				<service name="ROM" label="pci_devices"> <child name="drivers_reports"/> </service>
-				<service name="LOG"> <parent/> </service>
-				<service name="PD">  <parent/> </service>
-				<service name="CPU"> <parent/> </service>
-				<service name="ROM"> <parent/> </service>
-			</route>
-		</start>
-
 		<start name="platform_drv" caps="400" managing_system="yes">
 			<resource name="RAM" quantum="4M"/>
 			<provides>
@@ -111,7 +90,7 @@ set config {
 				<policy label_prefix="acpica"/>
 			</config>
 			<route>
-				<service name="ROM" label="devices"> <child name="rom_filter"/> </service>
+				<service name="ROM" label="devices"> <child name="report_rom"/> </service>
 				<any-service> <parent/> <any-child/> </any-service>
 			</route>
 		</start>
diff --git a/repos/os/recipes/pkg/drivers_interactive-pc/archives b/repos/os/recipes/pkg/drivers_interactive-pc/archives
index 3749d1bf72..8d02ed1cd6 100644
--- a/repos/os/recipes/pkg/drivers_interactive-pc/archives
+++ b/repos/os/recipes/pkg/drivers_interactive-pc/archives
@@ -9,4 +9,3 @@ _/src/rom_filter
 _/src/event_filter
 _/src/pci_decode
 _/raw/drivers_interactive-pc
-_/raw/pc-devices
diff --git a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config
index 6e8093a435..6ee7c45faa 100644
--- a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config
+++ b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config
@@ -36,9 +36,9 @@
 			<service name="Report" />
 		</provides>
 		<config>
-			<policy label="pci_decode -> system" report="acpi_drv -> acpi"/>
-			<policy label="rom_filter -> pci_devices" report="pci_decode -> devices"/>
-			<policy label="usb_hid_drv -> report" report="usb_drv -> devices"/>
+			<policy label="pci_decode -> system"    report="acpi_drv -> acpi"/>
+			<policy label="platform_drv -> devices" report="pci_decode -> devices"/>
+			<policy label="usb_hid_drv -> report"   report="usb_drv -> devices"/>
 		</config>
 		<route>
 			<service name="LOG"> <parent/> </service>
@@ -48,26 +48,6 @@
 		</route>
 	</start>
 
-	<start name="rom_filter" caps="70">
-		<resource name="RAM" quantum="1M"/>
-		<provides> <service name="ROM" /> </provides>
-		<config buffer="32K">
-			<input name="devices"/>
-			<input name="pci_devices"/>
-			<output node="devices">
-				<input name="devices"     skip_toplevel="yes"/>
-				<input name="pci_devices" skip_toplevel="yes"/>
-			</output>
-		</config>
-		<route>
-			<service name="ROM" label="pci_devices"> <child name="report_rom"/> </service>
-			<service name="LOG"> <parent/> </service>
-			<service name="PD">  <parent/> </service>
-			<service name="CPU"> <parent/> </service>
-			<service name="ROM"> <parent/> </service>
-		</route>
-	</start>
-
 	<start name="pci_decode" caps="100">
 		<resource name="RAM" quantum="1M"/>
 		<route>
@@ -88,7 +68,7 @@
 			<service name="Platform"/>
 		</provides>
 		<route>
-			<service name="ROM" label="devices"> <child name="rom_filter"/> </service>
+			<service name="ROM" label="devices"> <child name="report_rom"/> </service>
 			<service name="Report">  <child name="report_rom"/> </service>
 			<service name="IRQ">     <parent/> </service>
 			<service name="IO_MEM">  <parent/> </service>
diff --git a/repos/os/src/app/pci_decode/main.cc b/repos/os/src/app/pci_decode/main.cc
index 2216c7af46..3384b281ac 100644
--- a/repos/os/src/app/pci_decode/main.cc
+++ b/repos/os/src/app/pci_decode/main.cc
@@ -53,7 +53,8 @@ struct Main
 	                   Xml_generator & generator, unsigned & msi);
 
 	void parse_irq_override_rules(Xml_node & xml);
-	void parse_pci_config_spaces(Xml_node & xml);
+	void parse_pci_config_spaces(Xml_node & xml, Xml_generator & generator);
+	void parse_acpi_device_info(Xml_generator & generator);
 	void sys_rom_update();
 
 	template <typename FN>
@@ -261,49 +262,90 @@ void Main::parse_pci_bus(bus_t           bus,
 }
 
 
-void Main::parse_pci_config_spaces(Xml_node & xml)
+/*
+ * By now, we do not have the necessary information about non-PCI devices
+ * available from the ACPI tables, therefore we hard-code typical devices
+ * we assume to be found in this function. In the future, this function
+ * shall interpret ACPI tables information.
+ */
+void Main::parse_acpi_device_info(Xml_generator & gen)
 {
-	pci_reporter.generate([&] (Xml_generator & generator)
+	/*
+	 * PS/2 device
+	 */
+	gen.node("device", [&]
 	{
-		/*
-		 * We count beginning from 1 not 0, because some clients (Linux drivers)
-		 * do not ignore the pseudo MSI number announced, but interpret zero as
-		 * invalid.
-		 */
-		unsigned msi_number      = 1;
-		unsigned host_bridge_num = 0;
-
-		xml.for_each_sub_node("bdf", [&] (Xml_node & xml)
+		gen.attribute("name", "ps2");
+		gen.node("irq", [&] { gen.attribute("number", 1U); });
+		gen.node("irq", [&] { gen.attribute("number", 12U); });
+		gen.node("io_port_range", [&]
 		{
-			addr_t const start = xml.attribute_value("start",  0UL);
-			addr_t const base  = xml.attribute_value("base",   0UL);
-			size_t const count = xml.attribute_value("count",  0UL);
-
-			bus_t const bus_off  = (bus_t) (start / FUNCTION_PER_BUS_MAX);
-			bus_t const last_bus = (bus_t)
-				(max(1UL, (count / FUNCTION_PER_BUS_MAX)) - 1);
-
-			if (host_bridge_num++) {
-				error("We do not support multiple host bridges by now!");
-				return;
-			}
-
-			new (heap) Bridge(bridge_registry, { bus_off, 0, 0 },
-			                  bus_off, last_bus);
-
-			bus_t bus = 0;
-			do {
-				enum { BUS_SIZE = DEVICES_PER_BUS_MAX * FUNCTION_PER_DEVICE_MAX
-				                  * FUNCTION_CONFIG_SPACE_SIZE };
-				addr_t offset = base + bus * BUS_SIZE;
-				pci_config_ds.construct(env, offset, BUS_SIZE);
-				parse_pci_bus((bus_t)bus + bus_off,
-				              (addr_t)pci_config_ds->local_addr<void>(),
-				              offset, generator, msi_number);
-			} while (bus++ < last_bus);
-
-			pci_config_ds.destruct();
+			gen.attribute("address", "0x60");
+			gen.attribute("size", 1U);
 		});
+		gen.node("io_port_range", [&]
+		{
+			gen.attribute("address", "0x64");
+			gen.attribute("size", 1U);
+		});
+	});
+
+	/*
+	 * PIT device
+	 */
+	gen.node("device", [&]
+	{
+		gen.attribute("name", "pit");
+		gen.node("irq", [&] { gen.attribute("number", 0U); });
+		gen.node("io_port_range", [&]
+		{
+			gen.attribute("address", "0x40");
+			gen.attribute("size", 4U);
+		});
+	});
+}
+
+
+void Main::parse_pci_config_spaces(Xml_node & xml, Xml_generator & generator)
+{
+	/*
+	 * We count beginning from 1 not 0, because some clients (Linux drivers)
+	 * do not ignore the pseudo MSI number announced, but interpret zero as
+	 * invalid.
+	 */
+	unsigned msi_number      = 1;
+	unsigned host_bridge_num = 0;
+
+	xml.for_each_sub_node("bdf", [&] (Xml_node & xml)
+	{
+		addr_t const start = xml.attribute_value("start",  0UL);
+		addr_t const base  = xml.attribute_value("base",   0UL);
+		size_t const count = xml.attribute_value("count",  0UL);
+
+		bus_t const bus_off  = (bus_t) (start / FUNCTION_PER_BUS_MAX);
+		bus_t const last_bus = (bus_t)
+			(max(1UL, (count / FUNCTION_PER_BUS_MAX)) - 1);
+
+		if (host_bridge_num++) {
+			error("We do not support multiple host bridges by now!");
+			return;
+		}
+
+		new (heap) Bridge(bridge_registry, { bus_off, 0, 0 },
+		                  bus_off, last_bus);
+
+		bus_t bus = 0;
+		do {
+			enum { BUS_SIZE = DEVICES_PER_BUS_MAX * FUNCTION_PER_DEVICE_MAX
+			                  * FUNCTION_CONFIG_SPACE_SIZE };
+			addr_t offset = base + bus * BUS_SIZE;
+			pci_config_ds.construct(env, offset, BUS_SIZE);
+			parse_pci_bus((bus_t)bus + bus_off,
+			              (addr_t)pci_config_ds->local_addr<void>(),
+			              offset, generator, msi_number);
+		} while (bus++ < last_bus);
+
+		pci_config_ds.destruct();
 	});
 }
 
@@ -332,7 +374,11 @@ void Main::sys_rom_update()
 		reserved_memory_list.update_from_xml(policy, xml);
 	}
 
-	parse_pci_config_spaces(xml);
+	pci_reporter.generate([&] (Xml_generator & generator)
+	{
+		parse_acpi_device_info(generator);
+		parse_pci_config_spaces(xml, generator);
+	});
 }
 
 
diff --git a/repos/pc/recipes/raw/pc-devices/content.mk b/repos/pc/recipes/raw/pc-devices/content.mk
deleted file mode 100644
index b9b79df7c4..0000000000
--- a/repos/pc/recipes/raw/pc-devices/content.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-content: devices
-
-devices:
-	cp $(GENODE_DIR)/repos/base/board/pc/$@ $@
diff --git a/repos/pc/recipes/raw/pc-devices/hash b/repos/pc/recipes/raw/pc-devices/hash
deleted file mode 100644
index b744230dec..0000000000
--- a/repos/pc/recipes/raw/pc-devices/hash
+++ /dev/null
@@ -1 +0,0 @@
-2022-09-15 184a930a9bf6fa8dc67582adbd3f940bf815a767