Commit d92e66f1 authored by Michael Reese's avatar Michael Reese

sdb: first hacky version of static sdb scanner

there are static versions of eb_sdb_find_by_identity and eb_sdb_find_by_identity_msi
the static versions can be selected by environtment variables
also all timeouts can be disabled via another environment variable
parent 7598969a
......@@ -34,6 +34,7 @@
#include "../transport/transport.h"
#include "../memory/memory.h"
#include "../format/bigendian.h"
#include <stdlib.h>
eb_status_t eb_device_open(eb_socket_t socketp, const char* address, eb_width_t proposed_widths, int attempts, eb_device_t* result) {
eb_device_t devicep;
......@@ -45,7 +46,7 @@ eb_status_t eb_device_open(eb_socket_t socketp, const char* address, eb_width_t
struct eb_socket* socket;
struct eb_socket_aux* aux;
eb_status_t status;
devicep = eb_new_device();
if (devicep == EB_NULL) {
*result = EB_NULL;
......@@ -132,7 +133,12 @@ eb_status_t eb_device_open(eb_socket_t socketp, const char* address, eb_width_t
*(uint32_t*)(buf+4) = htobe32((uint32_t)(uintptr_t)devicep);
eb_transports[transport->link_type].send(transport, link, buf, sizeof(buf));
timeout = 3000000; /* 3 seconds */
if (getenv("EB_DISABLE_ALL_TIMEOUTS") != NULL) {
timeout = 30000000;
} else {
timeout = 3000000; /* 3 seconds */
}
while (timeout > 0 && device->link != EB_NULL && device->widths == 0) {
got = eb_socket_run(socketp, timeout); /* Invalidates all pointers */
timeout -= got;
......
......@@ -244,24 +244,78 @@ struct sdb_static_crossbar* sdb_static_crossbar_from_file(const char* filename_p
}
struct sdb_device* sdb_static_find_by_identity(struct sdb_static_crossbar *crossbar, uint64_t vendor_id, uint32_t device_id) {
// struct sdb_device* sdb_static_find_by_identity(struct sdb_static_crossbar *crossbar, uint64_t vendor_id, uint32_t device_id) {
// for (int i = 0; i < crossbar->num_records; ++i) {
// printf("sdb_static_find_by_identity record[%d].type = %x\n", i, crossbar->records[i].device.sdb_component.product.record_type);
// if (crossbar->records[i].device.sdb_component.product.vendor_id == vendor_id &&
// crossbar->records[i].device.sdb_component.product.device_id == device_id &&
// crossbar->records[i].device.sdb_component.product.record_type == 0x01) {
// // correct device found
// struct sdb_device *result = &crossbar->records[i].device;
// return result;
// } else if (crossbar->records[i].device.sdb_component.product.record_type == 0x02) {
// // bridge found
// struct sdb_static_crossbar * child = (struct sdb_static_crossbar*)crossbar->records[i].bridge.sdb_child;
// struct sdb_device *result = sdb_static_find_by_identity(child, vendor_id, device_id);
// if (result) {
// return result;
// }
// }
// }
// return NULL;
// }
eb_status_t sdb_static_find_by_identity(struct sdb_static_crossbar *crossbar, uint64_t vendor_id, uint32_t device_id, struct sdb_device *output, int *devices) {
int capacity = *devices;
*devices = 0;
for (int i = 0; i < crossbar->num_records; ++i) {
printf("sdb_static_find_by_identity record[%d].type = %x\n", i, crossbar->records[i].device.sdb_component.product.record_type);
// printf("sdb_find_by_identity record[%d].type = %x\n", i, crossbar->records[i].device.sdb_component.product.record_type);
if (crossbar->records[i].device.sdb_component.product.vendor_id == vendor_id &&
crossbar->records[i].device.sdb_component.product.device_id == device_id &&
crossbar->records[i].device.sdb_component.product.record_type == 0x01) {
// correct device found
struct sdb_device *result = &crossbar->records[i].device;
return result;
// printf("found device capacity = %d *devices = %d\n", capacity, *devices);
if (capacity > 0) {
*output = crossbar->records[i].device;
// print_sdb_device(crossbar->records[i].device);
++output;
--capacity;
}
++*devices;
} else if (crossbar->records[i].device.sdb_component.product.record_type == 0x02) {
// bridge found
struct sdb_static_crossbar * child = (struct sdb_static_crossbar*)crossbar->records[i].bridge.sdb_child;
struct sdb_device *result = sdb_static_find_by_identity(child, vendor_id, device_id);
if (result) {
return result;
}
struct sdb_static_crossbar * child = (struct sdb_static_crossbar*)crossbar->records[i].bridge.sdb_child;
// call the function with the output pointer moved forward by the number of already found devices
int capacity_recursive = capacity;
sdb_static_find_by_identity(child, vendor_id, device_id, output, &capacity_recursive);
// printf("found %d devices in recursive call\n", capacity_recursive);
// capacity contains number of devices found after function call
*devices += capacity_recursive;
}
}
return NULL;
return EB_OK;
}
eb_status_t sdb_static_find_by_identity_msi(struct sdb_static_crossbar *crossbar, uint64_t vendor_id, uint32_t device_id, struct sdb_device *output, eb_address_t* output_msi_first, eb_address_t* output_msi_last, int *devices) {
int capacity = *devices;
eb_address_t msi_first, msi_last;
sdb_static_find_by_identity(crossbar, vendor_id, device_id, output, devices);
// in order to find msi_first and msi_last, just take sdb_componnen.addr_fist and
// sdb_component.addr_last from the first .msi record found... don't know if that is always correct...
for (int i = 0; i < crossbar->num_records; ++i) {
// printf("sdb_find_by_identity record[%d].type = %x\n", i, crossbar->records[i].device.sdb_component.product.record_type);
if (crossbar->records[i].device.sdb_component.product.record_type == 0x03) {
// correct device found
// printf("found device capacity = %d *devices = %d\n", capacity, *devices);
msi_first = crossbar->records[i].msi.sdb_component.addr_first;
msi_last = crossbar->records[i].msi.sdb_component.addr_last;
break;
}
}
for (int i = 0; i < capacity && i < *devices; ++i ) {
output_msi_first[i] = msi_first;
output_msi_last[i] = msi_last;
}
return EB_OK;
}
\ No newline at end of file
......@@ -40,7 +40,8 @@ struct sdb_static_crossbar {
};
EB_PRIVATE struct sdb_static_crossbar* sdb_static_crossbar_from_file(const char* filename_prefix, uint32_t sdb_addr);
EB_PRIVATE struct sdb_device* sdb_static_find_by_identity(struct sdb_static_crossbar *crossbar, uint64_t vendor_id, uint32_t device_id);
EB_PRIVATE eb_status_t sdb_static_find_by_identity(struct sdb_static_crossbar *crossbar, uint64_t vendor_id, uint32_t device_id, struct sdb_device *output, int *devices);
EB_PRIVATE eb_status_t sdb_static_find_by_identity_msi(struct sdb_static_crossbar *crossbar, uint64_t vendor_id, uint32_t device_id, struct sdb_device *output, eb_address_t* output_msi_first, eb_address_t* output_msi_last, int *devices);
EB_PRIVATE void print_sdb_device(struct sdb_device device);
......
......@@ -33,9 +33,12 @@
#include "version.h"
#include "../format/bigendian.h"
#include "../memory/memory.h"
#include <string.h>
#include "sdb-static.h"
#include <stdlib.h>
#include <stdio.h>
#define SDB_MAGIC 0x5344422D
static eb_data_t eb_sdb_extract(void* data, eb_width_t width, eb_address_t addr) {
......@@ -839,14 +842,43 @@ static eb_status_t eb_sdb_find_by_identity_real(
}
*devices = record.fill_output;
// intercept all timeouts if this environment variable is set
const char *eb_disable_all_timeouts = getenv("EB_DISABLE_ALL_TIMEOUTS");
if (eb_disable_all_timeouts != NULL && record.status == EB_TIMEOUT) {
return EB_OK;
}
return record.status;
}
eb_status_t eb_sdb_find_by_identity_msi(eb_device_t device, uint64_t vendor_id, uint32_t device_id, struct sdb_device* output, eb_address_t* output_msi_first, eb_address_t* output_msi_last, int* devices) {
const char* sdb_static_base_name = getenv("EB_SDB_STATIC_BASE_NAME");
const char* sdb_static_base_addr = getenv("EB_SDB_STATIC_BASE_ADDR");
if (sdb_static_base_name != NULL) {
eb_address_t base_addr = 0;
if (sdb_static_base_addr != NULL) {
sscanf(sdb_static_base_addr, "%lx", &base_addr);
}
// leak!!
struct sdb_static_crossbar *sdb_crossbar = sdb_static_crossbar_from_file(sdb_static_base_name, base_addr);
// call static version of sdb_find_by_identity_msi
return sdb_static_find_by_identity_msi(sdb_crossbar, vendor_id, device_id, output, output_msi_first, output_msi_last, devices);
}
return eb_sdb_find_by_identity_real(device, vendor_id, device_id, 0, 0, 0, output, output_msi_first, output_msi_last, devices, *devices);
}
eb_status_t eb_sdb_find_by_identity(eb_device_t device, uint64_t vendor_id, uint32_t device_id, struct sdb_device* output, int* devices) {
const char* sdb_static_base_name = getenv("EB_SDB_STATIC_BASE_NAME");
const char* sdb_static_base_addr = getenv("EB_SDB_STATIC_BASE_ADDR");
if (sdb_static_base_name != NULL) {
eb_address_t base_addr = 0;
if (sdb_static_base_addr != NULL) {
sscanf(sdb_static_base_addr, "%lx", &base_addr);
}
// leak!!
struct sdb_static_crossbar *sdb_crossbar = sdb_static_crossbar_from_file(sdb_static_base_name, base_addr);
// call static version of sdb_find_by_identity
return sdb_static_find_by_identity(sdb_crossbar, vendor_id, device_id, output, devices);
}
return eb_sdb_find_by_identity_real(device, vendor_id, device_id, 0, 0, 0, output, 0, 0, devices, 0);
}
......
......@@ -37,6 +37,8 @@
#include "../memory/memory.h"
#include "../format/format.h"
#include <stdlib.h>
#ifdef __WIN32
#include <winsock2.h>
#endif
......@@ -384,24 +386,26 @@ int eb_socket_check(eb_socket_t socketp, uint32_t now, eb_user_data_t user, eb_d
completed = 0;
/* Step 1. Kill any expired timeouts */
while (socket->first_response != EB_NULL &&
eb_socket_timeout(socketp) <= now) {
/* Kill first */
responsep = socket->first_response;
response = EB_RESPONSE(responsep);
cyclep = response->cycle;
cycle = EB_CYCLE(cyclep);
socket->first_response = response->next;
(*cycle->callback)(cycle->user_data, cycle->un_link.device, cycle->un_ops.first, EB_TIMEOUT);
socket = EB_SOCKET(socketp); /* Restore pointer */
++completed;
eb_cycle_destroy(cyclep);
eb_free_cycle(cyclep);
eb_free_response(responsep);
if (getenv("EB_DISABLE_ALL_TIMEOUTS") == NULL) {
while (socket->first_response != EB_NULL &&
eb_socket_timeout(socketp) <= now) {
/* Kill first */
responsep = socket->first_response;
response = EB_RESPONSE(responsep);
cyclep = response->cycle;
cycle = EB_CYCLE(cyclep);
socket->first_response = response->next;
(*cycle->callback)(cycle->user_data, cycle->un_link.device, cycle->un_ops.first, EB_TIMEOUT);
socket = EB_SOCKET(socketp); /* Restore pointer */
++completed;
eb_cycle_destroy(cyclep);
eb_free_cycle(cyclep);
eb_free_response(responsep);
}
}
/* Get some memory for accepting connections */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment