diff --git a/kernel-src/arch/x86-64/cpu.c b/kernel-src/arch/x86-64/cpu.c index 25bfecb5..6c8848d7 100644 --- a/kernel-src/arch/x86-64/cpu.c +++ b/kernel-src/arch/x86-64/cpu.c @@ -3,6 +3,7 @@ #include #include #include +#include #define EFER_SYSCALLENABLE 1 @@ -213,4 +214,13 @@ void cpu_initstate() { done += snprintf(str_buf + done, 128 - done, "%d%c", topology_ids[i], i == topology_depth - 1 ? 0 : ':'); str_buf[done] = '\n'; printf("%s\n", str_buf); + + // insert it into the topology tree + topology_node_t *topology_nodes[topology_depth]; + for (int i = 0; i < topology_depth; ++i) { + topology_nodes[i] = topology_create_node(); + __assert(topology_nodes[i]); + + topology_insert(topology_nodes[i], i == 0 ? topology_get_root() : topology_nodes[i - 1], TOPOLOGY_MAKE_ID(topology_types[i], topology_ids[i]), current_cpu()); + } } diff --git a/kernel-src/include/kernel/topology.h b/kernel-src/include/kernel/topology.h new file mode 100644 index 00000000..2e026723 --- /dev/null +++ b/kernel-src/include/kernel/topology.h @@ -0,0 +1,25 @@ +#ifndef _TOPOLOGY_H +#define _TOPOLOGY_H + +#define TOPOLOGY_MAKE_ID(depth, id) ((depth << 16) | id) + +#include + +typedef struct topology_node_t { + int id; + struct topology_node_t *parent; + struct topology_node_t *sibling; + struct topology_node_t *children; + cpu_t *cpu; +} topology_node_t; + +extern topology_node_t topology_root; + +topology_node_t *topology_create_node(void); +void topology_insert(topology_node_t *node, topology_node_t *parent, int id, cpu_t *cpu); + +static inline topology_node_t *topology_get_root(void) { + return &topology_root; +} + +#endif diff --git a/kernel-src/sys/topology.c b/kernel-src/sys/topology.c new file mode 100644 index 00000000..1e503838 --- /dev/null +++ b/kernel-src/sys/topology.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include +#include + +static scache_t *slab_cache; +topology_node_t topology_root; +static MUTEX_DEFINE(allocate_mutex); +static SPINLOCK_DEFINE(tree_lock); + +topology_node_t *topology_create_node(void) { + MUTEX_ACQUIRE(&allocate_mutex, false); + if (unlikely(slab_cache == NULL)) { + slab_cache = slab_newcache(sizeof(topology_node_t), 0, NULL, NULL); + __assert(slab_cache); + } + + topology_node_t *node = slab_allocate(slab_cache); + MUTEX_RELEASE(&allocate_mutex); + return node; +} + +void topology_insert(topology_node_t *node, topology_node_t *parent, int id, cpu_t *cpu) { + long old_ipl = spinlock_acquireraiseipl(&tree_lock, IPL_MAX); + + node->id = id; + node->cpu = cpu; + + node->parent = parent; + node->sibling = node->parent->children; + node->parent->children = node; + + spinlock_releaseloweripl(&tree_lock, old_ipl); +}