Skip to content

Commit

Permalink
Support Galaxy Nexus, Nexus 4/5/9
Browse files Browse the repository at this point in the history
  • Loading branch information
Maratyszcza committed May 8, 2017
1 parent 419a819 commit ac57632
Show file tree
Hide file tree
Showing 8 changed files with 1,355 additions and 34 deletions.
4 changes: 4 additions & 0 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ def main(args):
build.unittest("jetson-tx1-test", build.cxx("jetson-tx1.cc"))

build.unittest("nexus-s-test", build.cxx("nexus-s.cc"))
build.unittest("galaxy-nexus-test", build.cxx("galaxy-nexus.cc"))
build.unittest("nexus4-test", build.cxx("nexus4.cc"))
build.unittest("nexus5-test", build.cxx("nexus5.cc"))
build.unittest("nexus9-test", build.cxx("nexus9.cc"))

return build

Expand Down
26 changes: 26 additions & 0 deletions src/arm/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,32 @@ void cpuinfo_arm_decode_cache(
.line_size = 64 /* assume same as Krait */
};
break;
case cpuinfo_uarch_denver:
/*
* The Denver chip includes a 128KB, 4-way level 1 instruction cache, a 64KB, 4-way level 2 data cache,
* and a 2MB, 16-way level 2 cache, all of which can service both cores. [1]
*
* All the caches have 64-byte lines. [2]
*
* [1] http://www.pcworld.com/article/2463900/nvidia-reveals-pc-like-performance-for-denver-tegra-k1.html
* [2] http://linleygroup.com/newsletters/newsletter_detail.php?num=5205&year=2014
*/
*l1i = (struct cpuinfo_cache) {
.size = 128 * 1024,
.associativity = 4,
.line_size = 64
};
*l1d = (struct cpuinfo_cache) {
.size = 64 * 1024,
.associativity = 4,
.line_size = 64
};
*l2 = (struct cpuinfo_cache) {
.size = 2 * 1024 * 1024,
.associativity = 16,
.line_size = 64
};
break;
case cpuinfo_uarch_mongoose:
/*
* - "Moving past branch prediction we can see some elements of how the cache is set up for the L1 I$,
Expand Down
85 changes: 51 additions & 34 deletions src/arm/linux/cpuinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ static void parse_cpu_architecture(
struct proc_cpuinfo proc_cpuinfo[restrict static 1])
{
const size_t cpu_architecture_length = (size_t) (cpu_architecture_end - cpu_architecture_start);
/* Early AArch64 kernels report "CPU architecture: AArch64" instead of a numeric value 8 */
if (cpu_architecture_length == 7) {
if (memcmp(cpu_architecture_start, "AArch64", cpu_architecture_length) == 0) {
proc_cpuinfo->architecture.version = 8;
proc_cpuinfo->valid_mask |= PROC_CPUINFO_VALID_ARCHITECTURE;
return;
}
}


uint32_t architecture = 0;
const char* cpu_architecture_ptr = cpu_architecture_start;
Expand All @@ -259,31 +268,39 @@ static void parse_cpu_architecture(
architecture = architecture * 10 + digit;
}

if (architecture != 0) {
proc_cpuinfo->architecture.version = architecture;
proc_cpuinfo->valid_mask |= PROC_CPUINFO_VALID_ARCHITECTURE;

for (; cpu_architecture_ptr != cpu_architecture_end; cpu_architecture_ptr++) {
const char feature = *cpu_architecture_ptr;
switch (feature) {
case 'T':
proc_cpuinfo->architecture.flags |= PROC_CPUINFO_ARCH_T;
break;
case 'E':
proc_cpuinfo->architecture.flags |= PROC_CPUINFO_ARCH_E;
break;
case 'J':
proc_cpuinfo->architecture.flags |= PROC_CPUINFO_ARCH_J;
break;
case ' ':
case '\t':
/* Ignore whitespace at the end */
break;
default:
cpuinfo_log_warning("skipped unknown architectural feature '%c' for ARMv%"PRIu32,
feature, architecture);
break;
if (cpu_architecture_ptr == cpu_architecture_start) {
cpuinfo_log_warning("CPU architecture %.*s in /proc/cpuinfo is ignored due to non-digit at the beginning of the string",
(int) cpu_architecture_length, cpu_architecture_start);
} else {
if (architecture != 0) {
proc_cpuinfo->architecture.version = architecture;
proc_cpuinfo->valid_mask |= PROC_CPUINFO_VALID_ARCHITECTURE;

for (; cpu_architecture_ptr != cpu_architecture_end; cpu_architecture_ptr++) {
const char feature = *cpu_architecture_ptr;
switch (feature) {
case 'T':
proc_cpuinfo->architecture.flags |= PROC_CPUINFO_ARCH_T;
break;
case 'E':
proc_cpuinfo->architecture.flags |= PROC_CPUINFO_ARCH_E;
break;
case 'J':
proc_cpuinfo->architecture.flags |= PROC_CPUINFO_ARCH_J;
break;
case ' ':
case '\t':
/* Ignore whitespace at the end */
break;
default:
cpuinfo_log_warning("skipped unknown architectural feature '%c' for ARMv%"PRIu32,
feature, architecture);
break;
}
}
} else {
cpuinfo_log_warning("CPU architecture %.*s in /proc/cpuinfo is ignored due to invalid value (0)",
(int) cpu_architecture_length, cpu_architecture_start);
}
}
}
Expand Down Expand Up @@ -543,12 +560,12 @@ static void parse_cache_number(
static uint32_t parse_line(
const char* line_start,
const char* line_end,
uint32_t processor_number,
uint32_t processor_count,
struct proc_cpuinfo* proc_cpuinfo)
{
/* Empty line. Skip. */
if (line_start == line_end) {
return processor_number;
return processor_count;
}

/* Search for ':' on the line. */
Expand All @@ -562,7 +579,7 @@ static uint32_t parse_line(
if (separator == line_end) {
cpuinfo_log_warning("Line %.*s in /proc/cpuinfo is ignored: key/value separator ':' not found",
(int) (line_end - line_start), line_start);
return processor_number;
return processor_count;
}

/* Skip trailing spaces in key part. */
Expand All @@ -576,7 +593,7 @@ static uint32_t parse_line(
if (key_end == line_start) {
cpuinfo_log_warning("Line %.*s in /proc/cpuinfo is ignored: key contains only spaces",
(int) (line_end - line_start), line_start);
return processor_number;
return processor_count;
}

/* Skip leading spaces in value part. */
Expand All @@ -590,7 +607,7 @@ static uint32_t parse_line(
if (value_start == line_end) {
cpuinfo_log_warning("Line %.*s in /proc/cpuinfo is ignored: value contains only spaces",
(int) (line_end - line_start), line_start);
return processor_number;
return processor_count;
}

/* Skip trailing spaces in value part (if any) */
Expand Down Expand Up @@ -659,13 +676,13 @@ static uint32_t parse_line(
const uint32_t new_processor_number =
parse_processor_number(value_start, value_end, proc_cpuinfo);
const uint32_t new_processors_count = new_processor_number + 1;
if (new_processors_count <= processor_number && processor_number != 0) {
if (new_processor_number < processor_count && new_processor_number != 0) {
cpuinfo_log_warning("ignored unexpectedly low processor number %"PRIu32" following processor %"PRIu32" in /proc/cpuinfo",
new_processor_number, processor_number);
new_processor_number, processor_count - 1);
} else {
if (new_processors_count > processor_number + 1) {
if (new_processor_number > processor_count) {
cpuinfo_log_info("unexpectedly high processor number %"PRIu32" following processor %"PRIu32" in /proc/cpuinfo",
new_processor_number, processor_number);
new_processor_number, processor_count - 1);
return new_processors_count;
}
return new_processors_count;
Expand Down Expand Up @@ -724,7 +741,7 @@ static uint32_t parse_line(
cpuinfo_log_debug("unknown /proc/cpuinfo key: %.*s", (int) key_length, line_start);

}
return processor_number;
return processor_count;
}

struct proc_cpuinfo* cpuinfo_arm_linux_parse_proc_cpuinfo(uint32_t processors_count_ptr[restrict static 1]) {
Expand Down
10 changes: 10 additions & 0 deletions src/arm/linux/isa.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,17 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(

if ((features & PROC_CPUINFO_FEATURE_IDIV) == PROC_CPUINFO_FEATURE_IDIV) {
cpuinfo_isa.idiv = true;
} else {
/* Qualcomm Krait may have buggy kernel configuration that doesn't report IDIV */
if (cpu_implementer == 'Q') {
switch (cpu_part) {
case 0x04D: /* Dual-core Krait */
case 0x06F: /* Quad-core Krait */
cpuinfo_isa.idiv = true;
}
}
}

const uint32_t vfp_mask = \
PROC_CPUINFO_FEATURE_VFP | PROC_CPUINFO_FEATURE_VFPV3 | PROC_CPUINFO_FEATURE_VFPV3D16 | \
PROC_CPUINFO_FEATURE_VFPD32 | PROC_CPUINFO_FEATURE_VFPV4 | PROC_CPUINFO_FEATURE_NEON;
Expand Down
Loading

0 comments on commit ac57632

Please sign in to comment.