1/*
2 * Copyright (c) 2015 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#ifndef LIBCPUID_INTERNAL_H_
11#define LIBCPUID_INTERNAL_H_ 1
12
13#include <barrelfish/barrelfish.h>
14#include <cpuid/cpuid.h>
15
16
17/**
18 * \brief executes the cpuid instruction and stores the result in the struct
19 *
20 * \param reg   cpuid_regs struct to store the result value
21 *
22 * the reg parameter is used to supply the function & argument information and
23 * returning the values
24 */
25static inline void cpuid_exec(struct cpuid_regs *reg)
26{
27    if (reg == NULL) {
28        return;
29    }
30
31    __asm volatile("cpuid"
32                   : "=a" (reg->eax), "=b" (reg->ebx),
33                     "=c" (reg->ecx), "=d" (reg->edx)
34                   : "a" (reg->eax), "c" (reg->ecx)
35                  );
36}
37
38
39/*
40 * ===============================================================================
41 * library configuration
42 * ===============================================================================
43 */
44///< enables verbose output of library operations
45#define CPUID_VERBOSE_OUTPUT 0
46
47
48/*
49 * ===============================================================================
50 * declarations
51 * ===============================================================================
52 */
53
54///< function table for vendor specific handlers
55struct cpuid_functions
56{
57    errval_t (*proc_family)(struct cpuid_proc_family *fmly);
58    errval_t (*proc_name)(char *buf, size_t len);
59    uint32_t (*proc_max_input_basic)(void);
60    uint32_t (*proc_max_input_extended)(void);
61    errval_t (*frequency_info)(struct cpuid_freqinfo *fi);
62
63    uint16_t (*cache_line_size)(void);
64    errval_t (*cache_info)(struct cpuid_cacheinfo *ci, uint32_t idx);
65
66    errval_t (*tlb_info)(struct cpuid_tlbinfo *ti, uint32_t idx);
67
68    errval_t (*thread_info)(struct cpuid_threadinfo *ti);
69    errval_t (*topology_info)(struct cpuid_topologyinfo *topo, uint8_t idx);
70
71    errval_t (*feature_info)(struct cpuid_featureinfo *fi);
72
73    errval_t (*address_space_info)(struct cpuid_adressspaceinfo *ai);
74};
75
76
77///< maximum input value for basic CPUID information
78extern uint32_t cpuid_g_max_input_basic;
79
80///< maximum input value for extended CPUID information
81extern uint32_t cpuid_g_max_input_extended;
82
83///< the vendor of the core this code is executed
84extern cpuid_vendor_t cpuid_g_vendor;
85
86///< function pointer table for vendor specific handlers
87extern struct cpuid_functions cpuid_fn;
88
89///< cpu cache names in readable representation
90extern char *cpuid_cache_names[4][4];
91
92/*
93 * ===============================================================================
94 * macros
95 * ===============================================================================
96 */
97
98#if CPUID_VERBOSE_OUTPUT
99#define CPUID_PRINTF(x...) debug_printf("libcpuid: " x)
100#else
101#define CPUID_PRINTF(x...)
102#endif
103
104///< masks the extended value
105#define CPUID_EXTENDED_INPUT_MASK(x) (x & 0x7fffffff)
106
107/*
108 * ===============================================================================
109 * functions
110 * ===============================================================================
111 */
112
113static inline uint8_t cpuid_bits_needed(uint8_t count)
114{
115    uint8_t mask = 0x80;
116    uint8_t cnt = 8;
117
118    while ((cnt > 0) && ((mask & count) != mask)) {
119        mask >>= 1;
120        cnt--;
121    }
122    return (cnt);
123}
124
125#include "cpuid_amd.h"
126#include "cpuid_intel.h"
127
128#endif /* CPUID_INTERNAL_H_ */
129