Discovery-migration prerequisites (M19.0)
The host bridge now carries MMIO apertures derived from the boot memory map's gaps below 4 GiB (largest three, sort-merged; a single after-the- last-region hole dies on OVMF's flash at the top) plus one aperture above the described space — so a user-space device_register of PCI functions with BAR resources can pass containment. The discovery test asserts every PCI memory resource lies inside a bridge window and names any escapee. device_register is idempotent on exact (parent, class, identity, resources) match — a restarted registering bus cannot duplicate its children; proven directly against the broker in the bus test. ChildAdded gains device_id so a report can carry the registered kernel id a matched driver needs as its assignment.
This commit is contained in:
@@ -73,8 +73,13 @@ pub const ChildAdded = extern struct {
|
||||
parent: u64,
|
||||
/// Where on the bus (for USB: the root port number, 1-based).
|
||||
bus_address: u64,
|
||||
/// Bus-specific identity (for USB: the PORTSC port-speed class).
|
||||
/// Bus-specific identity (for USB: the PORTSC port-speed class; for PCI:
|
||||
/// the class triple).
|
||||
identity: u64,
|
||||
/// The kernel device id this child was `device_register`ed as — what the
|
||||
/// manager hands a matched driver as its argv assignment — or `no_device`
|
||||
/// for an unregistered leaf (a USB port before the descriptor track).
|
||||
device_id: u64 = no_device,
|
||||
};
|
||||
|
||||
pub const child_added_size = @sizeOf(ChildAdded);
|
||||
|
||||
@@ -136,6 +136,8 @@ const Child = struct {
|
||||
parent: u64 = 0,
|
||||
bus_address: u64 = 0,
|
||||
identity: u64 = 0,
|
||||
// The kernel device id (registered by the reporter), or protocol.no_device.
|
||||
device_id: u64 = 0,
|
||||
reporter: u32 = 0, // the reporting driver instance's process id
|
||||
};
|
||||
|
||||
@@ -145,18 +147,19 @@ var children: [maximum_children]Child = .{Child{}} ** maximum_children;
|
||||
/// Record (or refresh) a reported child. Refreshing matters: a restarted bus
|
||||
/// driver re-reports what it rediscovers, and the same (parent, port) must not
|
||||
/// duplicate.
|
||||
fn addChild(parent: u64, bus_address: u64, identity: u64, reporter: u32) bool {
|
||||
fn addChild(parent: u64, bus_address: u64, identity: u64, device_id: u64, reporter: u32) bool {
|
||||
var free: ?*Child = null;
|
||||
for (&children) |*child| {
|
||||
if (child.used and child.parent == parent and child.bus_address == bus_address) {
|
||||
child.identity = identity;
|
||||
child.device_id = device_id;
|
||||
child.reporter = reporter;
|
||||
return true;
|
||||
}
|
||||
if (!child.used and free == null) free = child;
|
||||
}
|
||||
const slot = free orelse return false;
|
||||
slot.* = .{ .used = true, .parent = parent, .bus_address = bus_address, .identity = identity, .reporter = reporter };
|
||||
slot.* = .{ .used = true, .parent = parent, .bus_address = bus_address, .identity = identity, .device_id = device_id, .reporter = reporter };
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -382,7 +385,7 @@ fn onChildAdded(message: []const u8, reply: []u8, sender: u32) usize {
|
||||
const report = std.mem.bytesToValue(protocol.ChildAdded, message[0..protocol.child_added_size]);
|
||||
var status: i32 = 0;
|
||||
if (driverByProcess(sender)) |driver| {
|
||||
if (!addChild(report.parent, report.bus_address, report.identity, sender)) status = -1;
|
||||
if (!addChild(report.parent, report.bus_address, report.identity, report.device_id, sender)) status = -1;
|
||||
writeLine("device-manager: child added (device {d} port {d}, identity {d}) by {s}\n", .{ report.parent, report.bus_address, report.identity, driver.name() });
|
||||
if (status == 0) publishEvent(message[0..protocol.child_added_size]);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user