1/**
2 * \file
3 * \brief internal header of libnuma
4 *
5 * This is derived from:
6 *
7 * Linux man pages "numa"
8 * libnuma from http://oss.sgi.com/projects/libnuma/
9 *
10 */
11
12/*
13 * Copyright (c) 2014, ETH Zurich.
14 * All rights reserved.
15 *
16 * This file is distributed under the terms in the attached LICENSE file.
17 * If you do not find this file, copies can be found by writing to:
18 * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich.
19 * Attn: Systems Group.
20 */
21
22#ifndef NUMA_INTERNAL_H_
23#define NUMA_INTERNAL_H_
24
25#include <barrelfish_kpi/cpu.h>
26
27#include "numa_debug.h"
28
29/*
30 * ----------------------------------------------------------------------------
31 * Library global variable definitions
32 * ----------------------------------------------------------------------------
33 */
34extern uint8_t numa_initialized;
35
36/*
37 * ----------------------------------------------------------------------------
38 * Data structure definitions
39 * ----------------------------------------------------------------------------
40 */
41
42/**
43 * \brief numa topology information of the system
44 */
45struct numa_topology {
46    nodeid_t num_nodes;        ///< number of nodes in the system
47    coreid_t num_cores;        ///< number of cores in the system
48    nodeid_t preferred;        ///< the preferred node of the domain
49    numa_policy_t strict;      ///< numa policy
50    numa_policy_t bind;        ///< memory bind policy
51    size_t pagesize;           ///< numa page size
52    uint32_t *distances;       ///< numa distances
53    struct numa_node *nodes;   ///< nodes in the system
54    struct numa_core **cores;  ///< cores in the system (sorted by core id)
55};
56
57/**
58 * \brief represents a numa node
59 */
60struct numa_node {
61    nodeid_t id;               ///< id of the node
62    uint16_t apicid;           ///< apic id for the node (core 0)
63    coreid_t num_cores;        ///< number of cores within the
64    struct numa_core *cores;   ///< pointer to the cores array
65    struct bitmask *coresbm;   ///< bitmask for the cores
66    lpaddr_t mem_base;         ///< base address of the memory
67    lpaddr_t mem_limit;         ///< size of the memory region
68};
69
70/**
71 * \brief represents a core
72 */
73struct numa_core {
74    coreid_t id;               ///< id of the core
75    uint16_t apicid;           ///< apic id of the core
76    enum cpu_type arch;        ///< architecture
77    struct numa_node *node;    ///< node of the core
78};
79
80///< stores the topology information
81extern struct numa_topology numa_topology;
82
83///< numa interleave mask for allocations
84extern struct bitmap *numa_alloc_interleave_mask;
85
86///< numa bind mask for allocations
87extern struct bitmap *numa_alloc_bind_mask;
88
89/*
90 * ----------------------------------------------------------------------------
91 * Queriying the SKB
92 * ----------------------------------------------------------------------------
93 */
94
95/**
96 * \brief obtains the system topology from the SKB
97 *
98 * \param topology pointer to the topology information structure
99 *
100 * \returns SYS_ERR_OK on SUCCESS
101 *          errval on FAILURE
102 */
103errval_t numa_get_topology_from_skb(struct numa_topology *topology);
104
105/**
106 * \brief frees the numa topology structure
107 *
108 * \param topology pointer to the topology information structure
109 */
110void numa_free_topology(struct numa_topology *topology);
111
112/**
113 * \brief dumps the numa topology structure
114 *
115 * \param topology pointer to the topology to dump
116 */
117void numa_dump_topology(struct numa_topology *topology);
118
119/*
120 * ----------------------------------------------------------------------------
121 * macros for library checks
122 * ----------------------------------------------------------------------------
123 */
124
125#define NUMA_CHECK_STRICT 1
126
127#if NUMA_CHECK_STRICT
128#define numa_check_init() \
129    if (numa_initialized != 0x1) { \
130        USER_PANIC("NUMA library has not been initialized\n"); \
131    }
132
133#define numa_check_node_id(_id) \
134    if (_id >= numa_topology.num_nodes) { \
135        NUMA_WARNING("Node ID exceeds number of available nodes: %" PRIuNODEID "/%" \
136                      PRIuNODEID, _id, numa_topology.num_nodes); \
137        return NUMA_NODE_INVALID; \
138    }
139
140#define numa_check_core_id(_id) \
141    if (_id >= numa_topology.num_cores) { \
142        NUMA_WARNING("Core ID exceeds number of available cores: %"PRIuCOREID \
143                     "/%" PRIuCOREID, _id, numa_topology.num_cores); \
144        return (coreid_t)-1; \
145    }
146
147#else
148#define numa_check_init()
149#define numa_check_node_id(_id)
150#define numa_check_core_id(_id)
151#endif
152
153#endif /* NUMA_INTERNAL_H_ */
154