Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Transmeta(TM) Crusoe(TM) CPU #238

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/common/ascii.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,33 @@ struct ascii_logo {
$C1 ################ \
$C1 ####### "

#define ASCII_TRANSMETA \
"$C1 \
$C1 \
$C1 ########### \
$C1 ################### \
$C1 ######## ############ \
$C1 ##### ######## \
$C1 #### ####### \
$C1 #### ########### ###### \
$C1 #### ############## ##### \
$C1 #### ###### ####### #### \
$C1 ### ##### ##### #### \
$C1 #### ###### #### #### \
$C1 #### ###### ##### #### \
$C1 #### ###### #### #### \
$C1 ##### ####### ##### \
$C1 ##### ################## \
$C1 ###### ############# \
$C1 ###### \
$C1 ####### \
$C1 ######## \
$C1 ######## \
$C1 ######### \
$C1 ##################### \
$C1 ################# \
$C1 "

Dr-Noob marked this conversation as resolved.
Show resolved Hide resolved
typedef struct ascii_logo asciiL;

// +-----------------------------------------------------------------------------------------------------------------+
Expand All @@ -516,6 +543,7 @@ asciiL logo_riscv = { ASCII_RISCV, 63, 18, false, {C_FG_CYAN, C_FG_Y
asciiL logo_sifive = { ASCII_SIFIVE, 48, 19, true, {C_BG_WHITE, C_BG_BLACK}, {C_FG_WHITE, C_FG_BLUE} };
asciiL logo_starfive = { ASCII_STARFIVE, 33, 17, false, {C_FG_WHITE}, {C_FG_WHITE, C_FG_BLUE} };
asciiL logo_sipeed = { ASCII_SIPEED, 41, 16, true, {C_BG_RED, C_BG_WHITE}, {C_FG_RED, C_FG_WHITE} };
asciiL logo_transmeta = { ASCII_TRANSMETA, 50, 24, true, {C_BG_GREEN}, {C_FG_WHITE, C_FG_B_GREEN} };

// Long variants | ----------------------------------------------------------------------------------------------------------------|
asciiL logo_amd_l = { ASCII_AMD_L, 62, 19, true, {C_BG_WHITE, C_BG_GREEN}, {C_FG_WHITE, C_FG_GREEN} };
Expand Down
9 changes: 5 additions & 4 deletions src/common/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum {
// ARCH_X86
CPU_VENDOR_INTEL,
CPU_VENDOR_AMD,
CPU_VENDOR_TRANSMETA,
// ARCH_ARM
CPU_VENDOR_ARM,
CPU_VENDOR_APPLE,
Expand Down Expand Up @@ -82,7 +83,7 @@ struct cache {
};

struct topology {
int32_t total_cores;
Dr-Noob marked this conversation as resolved.
Show resolved Hide resolved
int32_t total_cores;
struct cache* cach;
#if defined(ARCH_X86) || defined(ARCH_PPC)
int32_t physical_cores;
Expand All @@ -98,7 +99,7 @@ struct topology {
};

struct features {
bool AES; // Must be the first field of features struct!
Dr-Noob marked this conversation as resolved.
Show resolved Hide resolved
bool AES; // Must be the first field of features struct!
#ifdef ARCH_X86
bool AVX;
bool AVX2;
Expand All @@ -116,11 +117,11 @@ struct features {
#elif ARCH_PPC
bool altivec;
#elif ARCH_ARM
bool NEON;
Dr-Noob marked this conversation as resolved.
Show resolved Hide resolved
bool NEON;
bool SHA1;
bool SHA2;
bool CRC32;
#endif
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Remove space

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

about these 4 nit: remove space comments in cpu.h: My editor removed the existing trailing spaces. I can revert those if you prefer to address them separately,

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, that would be nice. I want to give this a format pass sometime soon.

#endif
};

struct extensions {
Expand Down
3 changes: 3 additions & 0 deletions src/common/printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter
else if(art->vendor == CPU_VENDOR_AMD) {
art->art = choose_ascii_art_aux(&logo_amd_l, &logo_amd, term, lf);
}
else if (art->vendor == CPU_VENDOR_TRANSMETA) {
art->art = &logo_transmeta;
}
else {
art->art = &logo_unknown;
}
Expand Down
38 changes: 36 additions & 2 deletions src/x86/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
#include "uarch.h"
#include "freq/freq.h"

#define CPU_VENDOR_INTEL_STRING "GenuineIntel"
#define CPU_VENDOR_AMD_STRING "AuthenticAMD"
#define CPU_VENDOR_INTEL_STRING "GenuineIntel"
#define CPU_VENDOR_AMD_STRING "AuthenticAMD"
#define CPU_VENDOR_TRANSMETA_STRING "GenuineTMx86"

static const char *hv_vendors_string[] = {
[HV_VENDOR_KVM] = "KVMKVMKVM",
Expand Down Expand Up @@ -468,6 +469,8 @@ struct cpuInfo* get_cpu_info(void) {
cpu->cpu_vendor = CPU_VENDOR_INTEL;
else if (strcmp(CPU_VENDOR_AMD_STRING,name) == 0)
cpu->cpu_vendor = CPU_VENDOR_AMD;
else if (strcmp(CPU_VENDOR_TRANSMETA_STRING,name) == 0)
cpu->cpu_vendor = CPU_VENDOR_TRANSMETA;
else {
cpu->cpu_vendor = CPU_VENDOR_INVALID;
printErr("Unknown CPU vendor: %s", name);
Expand Down Expand Up @@ -692,6 +695,7 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach, int

switch(cpu->cpu_vendor) {
case CPU_VENDOR_INTEL:
case CPU_VENDOR_TRANSMETA:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure of this. From what I recall, get_topology_from_apic is Intel only. It seems like it is getting the right number of cores but this is probably coming from get_topology_from_udev. Can you confirm? Just run with --verbose and it will show us how is it getting this information.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. Any help with finding out how to retrieve topology is appreciated. I believe we could also assume cores=1 on this platform.

[WARNING]: Can't read features information from cpuid (needed level is 0x00000007, max is 0x00000001)
[WARNING]: Can't read frequency information from cpuid (needed level is 0x00000016, max is 0x00000001). Using udev
[WARNING]: Can't read topology information from cpuid (needed level is 0x00000001, max is 0x00000001)

if (cpu->maxLevels >= 0x00000004) {
bool toporet = get_topology_from_apic(cpu, topo);
if(!toporet) {
Expand Down Expand Up @@ -767,6 +771,32 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach, int
return topo;
}

struct cache* get_cache_info_transmeta(struct cache* cach) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we use get_cache_info_general. It does not work?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It failed to retrieve the cache size with that. I have eventually hardcoded the cache size to this CPU model.

uint32_t eax = 0x80000005;
uint32_t ebx = 0;
uint32_t ecx = 0;
uint32_t edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);

cach->L1d->size = (ecx >> 24) * 1024;
cach->L1i->size = (edx >> 24) * 1024;

eax = 0x80000006;
cpuid(&eax, &ebx, &ecx, &edx);

cach->L2->size = (ecx >> 16) * 1024;
cach->L3->size = (edx >> 18) * 512 * 1024;

cach->L1i->exists = cach->L1i->size > 0;
cach->L1d->exists = cach->L1d->size > 0;
cach->L2->exists = cach->L2->size > 0;
cach->L3->exists = 0;

cach->max_cache_level = 3;

return cach;
}

struct cache* get_cache_info_amd_fallback(struct cache* cach) {
uint32_t eax = 0x80000005;
uint32_t ebx = 0;
Expand Down Expand Up @@ -890,6 +920,10 @@ struct cache* get_cache_info(struct cpuInfo* cpu) {
cach = get_cache_info_general(cach, level);
}
}
else if (cpu->cpu_vendor == CPU_VENDOR_TRANSMETA) {
level = 0x00000001;
cach = get_cache_info_transmeta(cach);
}
else {
level = 0x8000001D;
if(cpu->maxExtendedLevels < level || !cpu->topology_extensions) {
Expand Down
22 changes: 22 additions & 0 deletions src/x86/uarch.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ enum {
UARCH_TIGER_LAKE,
UARCH_ALDER_LAKE,
UARCH_RAPTOR_LAKE,
// TRANSMETA //
UARCH_CRUSOE,
// AMD //
UARCH_AM486,
UARCH_AM5X86,
Expand Down Expand Up @@ -267,6 +269,21 @@ struct uarch* get_uarch_from_cpuid_intel(uint32_t ef, uint32_t f, uint32_t em, u
return arch;
}

struct uarch* get_uarch_from_cpuid_transmeta(uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
struct uarch* arch = emalloc(sizeof(struct uarch));
// EF: Extended Family //
// F: Family //
// EM: Extended Model //
// M: Model //
// S: Stepping //
// ------------------------------------------------------------------------------- //
// EF F EM M S //
UARCH_START
CHECK_UARCH(arch, 0, 5, 0, 4, 3, "CRUSOE", UARCH_CRUSOE, 130)
UARCH_END
return arch;
}

// Inspired in Todd Allen's decode_uarch_amd
struct uarch* get_uarch_from_cpuid_amd(uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
struct uarch* arch = emalloc(sizeof(struct uarch));
Expand Down Expand Up @@ -435,6 +452,9 @@ struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t
}
return get_uarch_from_cpuid_intel(ef, f, em, m, s);
}
else if (cpu->cpu_vendor == CPU_VENDOR_TRANSMETA) {
return get_uarch_from_cpuid_transmeta(ef, f, em, m, s);
}
else
return get_uarch_from_cpuid_amd(ef, f, em, m, s);
}
Expand All @@ -453,6 +473,8 @@ char* infer_cpu_name_from_uarch(struct uarch* arch) {

if (arch->uarch == UARCH_P5)
str = "Intel Pentium";
else if (arch->uarch == UARCH_CRUSOE)
str = "Transmeta Crusoe";
else if (arch->uarch == UARCH_P5_MMX)
str = "Intel Pentium MMX";
else if (arch->uarch == UARCH_P6_PENTIUM_II)
Expand Down