| 1 | = Overview = |
| 2 | |
| 3 | == Goals == |
| 4 | |
| 5 | * Abstract the low-level description APIs |
| 6 | * [wiki:FlattenedDeviceTree FlattenedDeviceTrees] |
| 7 | * ACPI |
| 8 | * Enumerate the platform |
| 9 | * Component connection topology |
| 10 | * IRQ routing |
| 11 | * Memory configuration (Cacheability, latency, …) |
| 12 | * Deduce the correct OS mapping |
| 13 | * For memory allocators (region API) |
| 14 | * Scheduler lists repartition |
| 15 | * Shortest-path IRQ routing |
| 16 | * SRL tasks/resources mapping |
| 17 | |
| 18 | == APIs == |
| 19 | |
| 20 | * Explore the topology |
| 21 | * Extract journey costs |
| 22 | * Query the topology: Get nodes by a selector |
| 23 | * Proximity ({{{get all rams that are at less than 3 hops than cpu XX}}}) |
| 24 | * Properties ({{{get all cpus of arch XX}}}) |
| 25 | * Properties ({{{get all devices of type XX}}}) -- maybe redundant with hexo's device_s tree |
| 26 | |
| 27 | = Optional features discussion = |
| 28 | |
| 29 | * Do we need to handle loads accounting (NoC load, CPU, memory, …) here ? |
| 30 | (i.e. something like "Ok, for now on I use an avg 1 MBps of NoC path from X to Y, then report to others) |
| 31 | * NoC is tightly coupled to topology, this could be interesting |
| 32 | * CPU is somewhat highly dynamic, even if we can sometimes predict, is it obvious here ? |
| 33 | * Memory has its own allocators, do not duplicate |
| 34 | * If we do not, we probably need a separate accounting library |
| 35 | * Maybe a-la mem_alloc(), per resource |
| 36 | * So we must duplicate topology for NoC accounting |
| 37 | * We can also put this is model-specific calls |
| 38 | |
| 39 | = libTopology data model = |
| 40 | |
| 41 | == Conceptual == |
| 42 | |
| 43 | It is a graph of nodes. Nodes are associated to an element of the architecture. Some node examples: |
| 44 | * A routing element (DSPIN NoC (as a whole)), a local interconnect |
| 45 | * A CPU+cache |
| 46 | * A memory bank |
| 47 | * An ICU |
| 48 | * A device |
| 49 | |
| 50 | Each node can be associated to a device -- There is at most 1 device per node, some nodes have no associated device (e.g. NoC has no dev) |
| 51 | |
| 52 | == Structures == |
| 53 | |
| 54 | {{{ |
| 55 | struct topo_model_s |
| 56 | { |
| 57 | void (*init)(struct topo_node_s *node, void *param); |
| 58 | void (*cleanup)(struct topo_node_s *node); |
| 59 | |
| 60 | // A bunch of function pointers for operations follows, see below |
| 61 | }; |
| 62 | }}} |
| 63 | |
| 64 | {{{ |
| 65 | struct topo_node_s |
| 66 | { |
| 67 | struct topo_model_s *model; /// model handling this node |
| 68 | void *priv; /// model's private data |
| 69 | struct device_s *dev; /// associated device, if any |
| 70 | }; |
| 71 | }}} |
| 72 | |
| 73 | = Needed APIs = |
| 74 | |
| 75 | == Device to node bijection == |
| 76 | |
| 77 | struct device_s *topo_node_to_device(struct topo_node_s *node); |
| 78 | |
| 79 | struct topo_node_s *topo_device_to_node(struct device_s *dev); |
| 80 | |
| 81 | == Topology exploration == |
| 82 | |
| 83 | There must be a high-level call to explore the path from a node to another. We will assume: |
| 84 | * There is one such path |
| 85 | * We do not cross address spaces during the exploration (route a data packet, cant transform it in an IRQ) |
| 86 | * There is one address type for destination |
| 87 | |
| 88 | High level call which does the routing and accumulates '''round-trip''' metrics: |
| 89 | {{{ |
| 90 | error_t topo_journey_metrics( |
| 91 | struct topo_metrics_s *result, |
| 92 | struct topo_node_s *start, |
| 93 | struct topo_addr_s *dest); |
| 94 | }}} |
| 95 | (round-trip is sufficient as there is roughly the same energy |
| 96 | involved in reads and writes, and also gives the model the choice |
| 97 | of what a round-trip involves (totally different for a noc and a bus)) |
| 98 | |
| 99 | |
| 100 | An address is a destination valid for a type of routing exploration, most of the time it will be a bus address, but may be an IRQ number, an USB device no, … |
| 101 | |
| 102 | {{{ |
| 103 | enum topo_addr_type_e |
| 104 | { |
| 105 | TOPO_ADDR_BUS; |
| 106 | }; |
| 107 | |
| 108 | struct topo_addr_s |
| 109 | { |
| 110 | enum topo_addr_type_e type; |
| 111 | union { |
| 112 | struct { |
| 113 | uintptr_t address; |
| 114 | } bus; |
| 115 | }; |
| 116 | }; |
| 117 | }}} |
| 118 | |
| 119 | Accumulated metrics describe the features of the walked path: |
| 120 | {{{ |
| 121 | struct topo_metrics_s |
| 122 | { |
| 123 | uint32_t hop_count; |
| 124 | uint32_t latency; /// cycles ? us ? |
| 125 | uint32_t max_byte_per_sec; /// capped max on path |
| 126 | uint32_t power_per_byte; /// overall consumption estimation |
| 127 | }; |
| 128 | }}} |
| 129 | |
| 130 | == Needed calls in model-specific functions == |
| 131 | |
| 132 | {{{ |
| 133 | error_t next( |
| 134 | struct topo_node_s *node, /// node of our model where we are coming from |
| 135 | const struct topo_addr_s *dest, /// destination address for the current address space |
| 136 | struct topo_metrics_s *metrics, /// Metrics to update on the go |
| 137 | struct topo_node_s **next_node); /// Next hop |
| 138 | }}} |