Skip to content

Commit 5ca8ae1

Browse files
committed
Recognize Unisoc UMS, disable neon dot for UMS312
1 parent b3a2db0 commit 5ca8ae1

File tree

4 files changed

+84
-0
lines changed

4 files changed

+84
-0
lines changed

src/arm/api.h

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ enum cpuinfo_arm_chipset_series {
6464
cpuinfo_arm_chipset_series_telechips_tcc,
6565
cpuinfo_arm_chipset_series_texas_instruments_omap,
6666
cpuinfo_arm_chipset_series_unisoc_t,
67+
cpuinfo_arm_chipset_series_unisoc_ums,
6768
cpuinfo_arm_chipset_series_wondermedia_wm,
6869
cpuinfo_arm_chipset_series_max,
6970
};

src/arm/linux/aarch32-isa.c

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
147147
"VDOT instructions disabled: cause occasional SIGILL on Spreadtrum SC9863A");
148148
} else if (chipset->series == cpuinfo_arm_chipset_series_unisoc_t && chipset->model == 310) {
149149
cpuinfo_log_warning("VDOT instructions disabled: cause occasional SIGILL on Unisoc T310");
150+
} else if (chipset->series == cpuinfo_arm_chipset_series_unisoc_ums && chipset->model == 312) {
151+
cpuinfo_log_warning("VDOT instructions disabled: cause occasional SIGILL on Unisoc UMS312");
150152
} else {
151153
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
152154
case UINT32_C(0x4100D0B0): /* Cortex-A76 */

src/arm/linux/chipset.c

+76
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static enum cpuinfo_arm_chipset_vendor chipset_series_vendor[cpuinfo_arm_chipset
8585
[cpuinfo_arm_chipset_series_telechips_tcc] = cpuinfo_arm_chipset_vendor_telechips,
8686
[cpuinfo_arm_chipset_series_texas_instruments_omap] = cpuinfo_arm_chipset_vendor_texas_instruments,
8787
[cpuinfo_arm_chipset_series_unisoc_t] = cpuinfo_arm_chipset_vendor_unisoc,
88+
[cpuinfo_arm_chipset_series_unisoc_ums] = cpuinfo_arm_chipset_vendor_unisoc,
8889
[cpuinfo_arm_chipset_series_wondermedia_wm] = cpuinfo_arm_chipset_vendor_wondermedia,
8990
};
9091

@@ -959,6 +960,70 @@ static bool match_t(const char* start, const char* end, struct cpuinfo_arm_chips
959960
return true;
960961
}
961962

963+
/**
964+
* Tries to match, case-sentitively, /Unisoc UMS\d{3,4}/ signature for Unisoc UMS
965+
* chipset. If match successful, extracts model information into \p chipset
966+
* argument.
967+
*
968+
* @param start - start of the platform identifier (/proc/cpuinfo Hardware
969+
* string, ro.product.board, ro.board.platform, or ro.chipname) to match.
970+
* @param end - end of the platform identifier (/proc/cpuinfo Hardware string,
971+
* ro.product.board, ro.board.platform, or ro.chipname) to match.
972+
* @param[out] chipset - location where chipset information will be stored upon
973+
* a successful match.
974+
*
975+
* @returns true if signature matched, false otherwise.
976+
*/
977+
static bool match_ums(const char* start, const char* end, struct cpuinfo_arm_chipset chipset[restrict static 1]) {
978+
/* Expect 13-14 symbols: "Unisoc UMS" (10 symbols) + 3-4-digit model number
979+
*/
980+
const size_t length = end - start;
981+
switch (length) {
982+
case 13:
983+
case 14:
984+
break;
985+
default:
986+
return false;
987+
}
988+
989+
/* Check that string starts with "Unisoc UMS". The first four characters
990+
* are loaded as 32-bit little endian word */
991+
const uint32_t expected_unis = load_u32le(start);
992+
if (expected_unis != UINT32_C(0x73696E55) /* "sinU" = reverse("Unis") */) {
993+
return false;
994+
}
995+
996+
/* The next four characters are loaded as 32-bit little endian word */
997+
const uint32_t expected_oc_u = load_u32le(start + 4);
998+
if (expected_oc_u != UINT32_C(0x5520636F) /* "U co" = reverse("oc U") */) {
999+
return false;
1000+
}
1001+
1002+
/* The next four characters are loaded as 16-bit little endian word */
1003+
const uint16_t expected_ms = load_u16le(start + 8);
1004+
if (expected_ms != UINT16_C(0x534D) /* "SM" = reverse("MS") */) {
1005+
return false;
1006+
}
1007+
1008+
/* Validate and parse 3-4 digit model number */
1009+
uint32_t model = 0;
1010+
for (uint32_t i = 10; i < length; i++) {
1011+
const uint32_t digit = (uint32_t)(uint8_t)start[i] - '0';
1012+
if (digit >= 10) {
1013+
/* Not really a digit */
1014+
return false;
1015+
}
1016+
model = model * 10 + digit;
1017+
}
1018+
1019+
*chipset = (struct cpuinfo_arm_chipset){
1020+
.vendor = cpuinfo_arm_chipset_vendor_unisoc,
1021+
.series = cpuinfo_arm_chipset_series_unisoc_ums,
1022+
.model = model,
1023+
};
1024+
return true;
1025+
}
1026+
9621027
/**
9631028
* Tries to match /lc\d{4}[a-z]?$/ signature for Leadcore LC chipsets.
9641029
* If match successful, extracts model information into \p chipset argument.
@@ -2508,6 +2573,16 @@ struct cpuinfo_arm_chipset cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_ha
25082573
return chipset;
25092574
}
25102575

2576+
/* Check Unisoc UMS signature */
2577+
if (match_ums(hardware, hardware_end, &chipset)) {
2578+
cpuinfo_log_debug(
2579+
"matched Unisoc UMS signature in /proc/cpuinfo Hardware string \"%.*s\"",
2580+
(int)hardware_length,
2581+
hardware);
2582+
2583+
return chipset;
2584+
}
2585+
25112586
#if CPUINFO_ARCH_ARM
25122587
/* Check Marvell PXA signature */
25132588
if (match_pxa(hardware, hardware_end, &chipset)) {
@@ -3726,6 +3801,7 @@ static const char* chipset_series_string[cpuinfo_arm_chipset_series_max] = {
37263801
[cpuinfo_arm_chipset_series_telechips_tcc] = "TCC",
37273802
[cpuinfo_arm_chipset_series_texas_instruments_omap] = "OMAP",
37283803
[cpuinfo_arm_chipset_series_unisoc_t] = "T",
3804+
[cpuinfo_arm_chipset_series_unisoc_ums] = "UMS",
37293805
[cpuinfo_arm_chipset_series_wondermedia_wm] = "WM",
37303806
};
37313807

test/name/proc-cpuinfo-hardware.cc

+5
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,11 @@ TEST(PROC_CPUINFO_HARDWARE, telechips) {
458458
EXPECT_EQ("Telechips TCC893X", parse_proc_cpuinfo_hardware("tcc893x"));
459459
}
460460

461+
TEST(PROC_CPUINFO_HARDWARE, unisoc) {
462+
EXPECT_EQ("Unisoc T301", parse_proc_cpuinfo_hardware("Unisoc T301", 4, 1800000));
463+
EXPECT_EQ("Unisoc UMS312", parse_proc_cpuinfo_hardware("Unisoc UMS312", 4, 1800000));
464+
}
465+
461466
#if CPUINFO_ARCH_ARM
462467
TEST(PROC_CPUINFO_HARDWARE, texas_instruments_omap) {
463468
EXPECT_EQ("Texas Instruments OMAP4430", parse_proc_cpuinfo_hardware("OMAP4430"));

0 commit comments

Comments
 (0)