blob: b29cc58d5dc1c39fccd297a633a1e5af37c01aba [file] [log] [blame]
/*
* Copyright (c) 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <newgemm_lib.hpp>
unsigned int get_cpu_impl()
{
#ifndef BARE_METAL
int fd = open("/proc/cpuinfo", 0);
char buff[3000];
char *pos;
char *end;
int foundid = 0;
int variant = 0;
int cpu = sched_getcpu();
if(!fd)
{
return 0;
}
int charsread = read(fd, buff, 3000);
pos = buff;
end = buff + charsread;
close(fd);
/* So, to date I've encountered two formats for /proc/cpuinfo.
*
* One of them just lists processor : n for each processor (with no
* other info), then at the end lists part information for the current
* CPU.
*
* The other has an entire clause (including part number info) for each
* CPU in the system, with "processor : n" headers.
*
* We can cope with either of these formats by waiting to see
* "processor: n" (where n = our CPU ID), and then looking for the next
* "CPU part" field.
*/
while(pos < end)
{
if(foundid && !strncmp(pos, "CPU variant", 11))
{
pos += 13;
char *resume = end; // Need to continue scanning after this
for(char *ch = pos; ch < end; ch++)
{
if(*ch == '\n')
{
*ch = '\0';
resume = ch + 1;
break;
}
}
variant = strtoul(pos, NULL, 0);
pos = resume;
}
if(foundid && !strncmp(pos, "CPU part", 8))
{
/* Found part number */
pos += 11;
unsigned int num;
for(char *ch = pos; ch < end; ch++)
{
if(*ch == '\n')
{
*ch = '\0';
break;
}
}
num = strtoul(pos, NULL, 0);
return (num << 4) | (variant << 20);
}
if(!strncmp(pos, "processor", 9))
{
/* Found processor ID, see if it's ours. */
pos += 11;
int num;
for(char *ch = pos; ch < end; ch++)
{
if(*ch == '\n')
{
*ch = '\0';
break;
}
}
num = strtol(pos, NULL, 0);
if(num == cpu)
{
foundid = 1;
}
}
while(pos < end)
{
char ch = *pos++;
if(ch == '\n' || ch == '\0')
{
break;
}
}
}
#endif
return 0;
}
CPUInfo *get_CPUInfo()
{
static CPUInfo ci;
return &ci;
}