mirror of
https://github.com/anrieff/libcpuid
synced 2025-07-02 14:04:15 +00:00
Adding correct recognition for Mobile Sempron 64s, added some additional sanity checking in check-consistency
git-svn-id: https://svn.code.sf.net/p/libcpuid/code/HEAD/libcpuid@41 3b4be424-7ac5-41d7-8526-f4ddcb85d872
This commit is contained in:
parent
f986629b65
commit
32425d7937
3 changed files with 273 additions and 11 deletions
|
@ -60,6 +60,7 @@ for fn in glob.glob("%s/*.c" % sys.argv[1]):
|
|||
if rexp.match(s):
|
||||
entry = rexp.findall(s)[0]
|
||||
files_code[fn].append(entry)
|
||||
f.close()
|
||||
|
||||
for feature in allf:
|
||||
matching_files = []
|
||||
|
@ -70,3 +71,38 @@ for feature in allf:
|
|||
print "No detection code for %s" % feature
|
||||
if len(matching_files) > 1:
|
||||
print "Conflicting detection code for %s in files %s" % (feature, " and ".join(matching_files))
|
||||
|
||||
cache_exp = re.compile(".*([\(/ ][0-9]+K).*")
|
||||
# Check whether CPU codenames for consistency:
|
||||
# - Codenames should not exceed 31 characters
|
||||
# - Check for common typos
|
||||
common_cache_sizes = ["8", "16", "32", "64", "128", "256", "512", "1024", "2048", "3072", "4096", "6144", "8192", "12288", "16384"]
|
||||
for fn in glob.glob("%s/*.c" % sys.argv[1]):
|
||||
nline = 0
|
||||
f = open(fn, "rt")
|
||||
has_matchtable = False
|
||||
for line in f.readlines():
|
||||
nline += 1
|
||||
if line.find("struct match_entry_t") != -1:
|
||||
has_matchtable = True
|
||||
if not has_matchtable:
|
||||
continue
|
||||
i = line.find("{")
|
||||
j = line.find("}")
|
||||
if i == -1 or j == -1 or i > j:
|
||||
continue
|
||||
inner = line[i+1:j]
|
||||
parts = inner.split(",")
|
||||
if len(parts) == 10: #this number needs to change if the definition of match_entry_t ever changes
|
||||
s = parts[9].strip()
|
||||
if s[0] != '"' or s[-1] != '"':
|
||||
print "Warning, %s:%d - cannot correctly handle the cpu codename" % (fn, nline)
|
||||
continue
|
||||
s = s[1:-1]
|
||||
if len(s) > 31:
|
||||
print "%s:%d - codename (%s) is longer than 31 characters!" %(fn, nline, s)
|
||||
if cache_exp.match(s):
|
||||
cache_size = cache_exp.findall(s)[0][1:-1]
|
||||
if not cache_size in common_cache_sizes:
|
||||
print "Warning, %s:%d - suspicious cache size in codename [%s] (%s)" % (fn, nline, s, cache_size)
|
||||
f.close()
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "libcpuid.h"
|
||||
#include "recog_amd.h"
|
||||
#include "libcpuid_util.h"
|
||||
|
@ -172,18 +173,41 @@ const struct match_entry_t cpudb_amd[] = {
|
|||
{ 15, -1, -1, 15, 0x23, 2, 1024, ATHLON_64_X2 , 0, "Athlon 64 X2 (Toledo/1024K)" },
|
||||
{ 15, -1, -1, 15, 0x43, 2, 1024, ATHLON_64_X2 , 0, "Athlon 64 X2 (Windsor/1024K)" },
|
||||
|
||||
{ 15, -1, -1, 15, 0x08, 1, 128, M_SEMPRON , 0, "Mobile Sempron 64 (Dublin/128K)"},
|
||||
{ 15, -1, -1, 15, 0x08, 1, 256, M_SEMPRON , 0, "Mobile Sempron 64 (Dublin/256K)"},
|
||||
{ 15, -1, -1, 15, 0x0c, 1, 256, SEMPRON , 0, "Sempron 64 (Paris)" },
|
||||
{ 15, -1, -1, 15, 0x1c, 1, 128, SEMPRON , 0, "Sempron 64 (Palermo/128K)" },
|
||||
{ 15, -1, -1, 15, 0x1c, 1, 256, SEMPRON , 0, "Sempron 64 (Palermo/256K)" },
|
||||
{ 15, -1, -1, 15, 0x1c, 1, 128, M_SEMPRON , 0, "Mobile Sempron 64 (Sonora/128K)"},
|
||||
{ 15, -1, -1, 15, 0x1c, 1, 256, M_SEMPRON , 0, "Mobile Sempron 64 (Sonora/256K)"},
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 128, SEMPRON , 0, "Sempron 64 (Palermo/128K)" },
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 256, SEMPRON , 0, "Sempron 64 (Palermo/256K)" },
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 128, M_SEMPRON , 0, "Mobile Sempron 64 (Albany/128K)"},
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 256, M_SEMPRON , 0, "Mobile Sempron 64 (Albany/256K)"},
|
||||
{ 15, -1, -1, 15, 0x2f, 1, 128, SEMPRON , 0, "Sempron 64 (Palermo/128K)" },
|
||||
{ 15, -1, -1, 15, 0x2f, 1, 256, SEMPRON , 0, "Sempron 64 (Palermo/256K)" },
|
||||
{ 15, -1, -1, 15, 0x4f, 1, 128, SEMPRON , 0, "Sempron 64 (Manila/128K)" },
|
||||
{ 15, -1, -1, 15, 0x4f, 1, 256, SEMPRON , 0, "Sempron 64 (Manila/256K)" },
|
||||
{ 15, -1, -1, 15, 0x5f, 1, 128, SEMPRON , 0, "Sempron 64 (Manila/128K)" },
|
||||
{ 15, -1, -1, 15, 0x5f, 1, 256, SEMPRON , 0, "Sempron 64 (Manila/256K)" },
|
||||
{ 15, -1, -1, 15, 0x6b, 2, 256, SEMPRON , 0, "Sempron 64 Dual (Sherman/256K)"},
|
||||
{ 15, -1, -1, 15, 0x6b, 2, 512, SEMPRON , 0, "Sempron 64 Dual (Sherman/512K)"},
|
||||
{ 15, -1, -1, 15, 0x7f, 1, 256, SEMPRON , 0, "Sempron 64 (Sparta/256K)" },
|
||||
{ 15, -1, -1, 15, 0x7f, 1, 512, SEMPRON , 0, "Sempron 64 (Sparta/512K)" },
|
||||
{ 15, -1, -1, 15, -1, 1, 256, M_SEMPRON , 0, "Mobile Sempron 64 (Keene/256K)"},
|
||||
{ 15, -1, -1, 15, -1, 1, 512, M_SEMPRON , 0, "Mobile Sempron 64 (Keene/512K)"},
|
||||
{ 15, -1, -1, 15, 0x4c, 1, 256, M_SEMPRON , 0, "Mobile Sempron 64 (Keene/256K)"},
|
||||
{ 15, -1, -1, 15, 0x4c, 1, 512, M_SEMPRON , 0, "Mobile Sempron 64 (Keene/512K)"},
|
||||
{ 15, -1, -1, 15, -1, 2, -1, SEMPRON_DUALCORE , 0, "Sempron Dual Core" },
|
||||
|
||||
{ 15, -1, -1, 15, 0x24, 1, 512, TURION_64 , 0, "Turion 64 (Lancaster/512K)" },
|
||||
{ 15, -1, -1, 15, 0x24, 1, 1024, TURION_64 , 0, "Turion 64 (Lancaster/1024K)" },
|
||||
{ 15, -1, -1, 15, 0x48, 2, 256, TURION_X2 , 0, "Turion X2 (Taylor)" },
|
||||
{ 15, -1, -1, 15, 0x48, 2, 512, TURION_X2 , 0, "Turion X2 (Trinidad)" },
|
||||
{ 15, -1, -1, 15, 0x4c, 1, 512, TURION_64 , 0, "Turion 64 (Richmond)" },
|
||||
{ 15, -1, -1, 15, 0x68, 2, 256, TURION_X2 , 0, "Turion X2 (Tyler/256K)" },
|
||||
{ 15, -1, -1, 15, 0x68, 2, 512, TURION_X2 , 0, "Turion X2 (Tyler/512K)" },
|
||||
{ 15, -1, -1, 23, 3, 2, 512, TURION_X2 , 0, "Turion X2 (Griffin/512K)" },
|
||||
{ 15, -1, -1, 23, 3, 2, 1024, TURION_X2 , 0, "Turion X2 (Griffin/1024K)" },
|
||||
|
||||
/* K9 Architecture */
|
||||
{ 15, -1, -1, 16, -1, 1, -1, PHENOM , 0, "Unknown AMD Phenom" },
|
||||
{ 15, 2, -1, 16, -1, 1, -1, PHENOM , 0, "Phenom" },
|
||||
|
@ -289,29 +313,53 @@ static void decode_amd_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id
|
|||
}
|
||||
}
|
||||
|
||||
static int amd_has_turion_modelname(const char *bs)
|
||||
{
|
||||
/* We search for something like TL-60. Ahh, I miss regexes...*/
|
||||
int i, l, k;
|
||||
char code[3] = {0};
|
||||
const char* codes[] = { "ML", "MT", "MK", "TK", "TL", "RM", "ZM", "" };
|
||||
l = (int) strlen(bs);
|
||||
for (i = 3; i < l - 2; i++) {
|
||||
if (bs[i] == '-' &&
|
||||
isupper(bs[i-1]) && isupper(bs[i-2]) && !isupper(bs[i-3]) &&
|
||||
isdigit(bs[i+1]) && isdigit(bs[i+2]) && !isdigit(bs[i+3]))
|
||||
{
|
||||
code[0] = bs[i-2];
|
||||
code[1] = bs[i-1];
|
||||
for (k = 0; codes[k][0]; k++)
|
||||
if (!strcmp(codes[k], code)) return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static amd_code_t decode_amd_codename_part1(const char *bs)
|
||||
{
|
||||
int is_dual = 0;
|
||||
if (strstr(bs, "Dual Core") ||
|
||||
strstr(bs, "Dual-Core") ||
|
||||
strstr(bs, " X2 "))
|
||||
is_dual = 1;
|
||||
if (strstr(bs, "Opteron")) {
|
||||
if (strstr(bs, "Dual Core")) return OPTERON_DUALCORE;
|
||||
return OPTERON_SINGLE;
|
||||
return is_dual ? OPTERON_DUALCORE : OPTERON_SINGLE;
|
||||
}
|
||||
if (strstr(bs, "Phenom")) {
|
||||
return PHENOM;
|
||||
}
|
||||
if (amd_has_turion_modelname(bs)) {
|
||||
return is_dual ? TURION_X2 : TURION_64;
|
||||
}
|
||||
if (strstr(bs, "Athlon(tm) 64 FX")) return ATHLON_64_FX;
|
||||
if (strstr(bs, "Athlon(tm) FX")) return ATHLON_FX;
|
||||
if (strstr(bs, "Athlon(tm) 64")) {
|
||||
if (strstr(bs, "Dual Core")) return ATHLON_64_X2;
|
||||
return ATHLON_64;
|
||||
return is_dual ? ATHLON_64_X2 : ATHLON_64;
|
||||
}
|
||||
if (strstr(bs, "Athlon(tm) X2")) {
|
||||
return ATHLON_64_X2;
|
||||
}
|
||||
if (strstr(bs, "Turion(tm)")) {
|
||||
if (strstr(bs, "X2"))
|
||||
return TURION_X2;
|
||||
else
|
||||
return TURION_64;
|
||||
if (strstr(bs, "Turion")) {
|
||||
return is_dual ? TURION_X2 : TURION_64;
|
||||
}
|
||||
|
||||
if (strstr(bs, "mobile") || strstr(bs, "Mobile")) {
|
||||
|
|
|
@ -2668,3 +2668,181 @@ intel_fn4[3]=00000000 00000000 00000000 00000000
|
|||
Sempron (Barton)
|
||||
fpu vme de pse tsc msr pae mce cx8 apic mtrr sep pge mca cmov pat pse36 mmx fxsr sse syscall mmxext 3dnow 3dnowext ts fid vid
|
||||
--------------------------------------------------------------------------------
|
||||
basic_cpuid[0]=00000001 68747541 444d4163 69746e65
|
||||
basic_cpuid[1]=00020f42 00000800 00000001 078bfbff
|
||||
basic_cpuid[2]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[3]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[4]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[5]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[6]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[7]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[8]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[9]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[10]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[11]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[12]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[13]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[14]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[15]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[16]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[17]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[18]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[19]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[20]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[21]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[22]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[23]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[24]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[25]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[26]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[27]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[28]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[29]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[30]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[31]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[0]=80000018 68747541 444d4163 69746e65
|
||||
ext_cpuid[1]=00020f42 0000028c 00000001 e3d3fbff
|
||||
ext_cpuid[2]=20444d41 69727554 74286e6f 3620296d
|
||||
ext_cpuid[3]=6f4d2034 656c6962 63655420 6c6f6e68
|
||||
ext_cpuid[4]=2079676f 332d4c4d 00000034 00000000
|
||||
ext_cpuid[5]=ff08ff08 ff20ff20 40020140 40020140
|
||||
ext_cpuid[6]=00000000 42004200 04008140 00000000
|
||||
ext_cpuid[7]=00000000 00000000 00000000 0000003f
|
||||
ext_cpuid[8]=00003028 00000000 00000000 00000000
|
||||
ext_cpuid[9]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[10]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[11]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[12]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[13]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[14]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[15]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[16]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[17]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[18]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[19]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[20]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[21]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[22]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[23]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[24]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[25]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[26]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[27]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[28]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[29]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[30]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[31]=00000000 00000000 00000000 00000000
|
||||
intel_fn4[0]=00000000 00000000 00000000 00000000
|
||||
intel_fn4[1]=00000000 00000000 00000000 00000000
|
||||
intel_fn4[2]=00000000 00000000 00000000 00000000
|
||||
intel_fn4[3]=00000000 00000000 00000000 00000000
|
||||
--------------------------------------------------------------------------------
|
||||
15
|
||||
4
|
||||
2
|
||||
15
|
||||
36
|
||||
1
|
||||
1
|
||||
64
|
||||
64
|
||||
1024
|
||||
0
|
||||
2
|
||||
16
|
||||
-1
|
||||
64
|
||||
64
|
||||
-1
|
||||
Turion 64 (Lancaster/1024K)
|
||||
fpu vme de pse tsc msr pae mce cx8 apic mtrr sep pge mca cmov pat pse36 clflush mmx fxsr sse sse2 pni syscall mmxext 3dnow 3dnowext nx fxsr_opt lm lahf_lm ts fid vid ttp tm_amd stc
|
||||
--------------------------------------------------------------------------------
|
||||
basic_cpuid[0]=00000001 68747541 444d4163 69746e65
|
||||
basic_cpuid[1]=00010fc0 00000800 00000000 078bfbff
|
||||
basic_cpuid[2]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[3]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[4]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[5]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[6]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[7]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[8]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[9]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[10]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[11]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[12]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[13]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[14]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[15]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[16]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[17]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[18]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[19]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[20]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[21]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[22]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[23]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[24]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[25]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[26]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[27]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[28]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[29]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[30]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[31]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[0]=80000018 68747541 444d4163 69746e65
|
||||
ext_cpuid[1]=00010fc0 00000849 00000001 c3d3fbff
|
||||
ext_cpuid[2]=69626f4d 4120656c 5320444d 72706d65
|
||||
ext_cpuid[3]=74286e6f 5020296d 65636f72 726f7373
|
||||
ext_cpuid[4]=30333320 00002b30 00000000 00000000
|
||||
ext_cpuid[5]=ff08ff08 ff20ff20 40020140 40020140
|
||||
ext_cpuid[6]=00000000 42004200 00808140 00000000
|
||||
ext_cpuid[7]=00000000 00000000 00000000 0000000f
|
||||
ext_cpuid[8]=00002028 00000000 00000000 00000000
|
||||
ext_cpuid[9]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[10]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[11]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[12]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[13]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[14]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[15]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[16]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[17]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[18]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[19]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[20]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[21]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[22]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[23]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[24]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[25]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[26]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[27]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[28]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[29]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[30]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[31]=00000000 00000000 00000000 00000000
|
||||
intel_fn4[0]=00000000 00000000 00000000 00000000
|
||||
intel_fn4[1]=00000000 00000000 00000000 00000000
|
||||
intel_fn4[2]=00000000 00000000 00000000 00000000
|
||||
intel_fn4[3]=00000000 00000000 00000000 00000000
|
||||
--------------------------------------------------------------------------------
|
||||
15
|
||||
12
|
||||
0
|
||||
15
|
||||
28
|
||||
1
|
||||
1
|
||||
64
|
||||
64
|
||||
128
|
||||
0
|
||||
2
|
||||
16
|
||||
-1
|
||||
64
|
||||
64
|
||||
-1
|
||||
Mobile Sempron 64 (Sonora/128K)
|
||||
fpu vme de pse tsc msr pae mce cx8 apic mtrr sep pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall mmxext 3dnow 3dnowext nx fxsr_opt lahf_lm ts fid vid ttp
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue