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 /proc/cpuinfo #1669

Open
wants to merge 1 commit 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
146 changes: 146 additions & 0 deletions fs/proc/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "kernel/calls.h"
#include "fs/proc.h"
#include "platform/platform.h"
#include <sys/param.h> // for MIN and MAX
#include "emu/cpuid.h"

static int proc_show_version(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
struct uname uts;
Expand All @@ -12,6 +14,149 @@ static int proc_show_version(struct proc_entry *UNUSED(entry), struct proc_data
return 0;
}

char * parse_edx_flags(dword_t edx, char *edx_flags) { /* Translate edx bit flags into text */
if(edx & (1<<0))
strcat(edx_flags, "fpu ");
if(edx & (1<<1))
strcat(edx_flags, "vme ");
if(edx & (1<<2))
strcat(edx_flags, "de ");
if(edx & (1<<3))
strcat(edx_flags, "pse ");
if(edx & (1<<4))
strcat(edx_flags, "tsc ");
if(edx & (1<<5))
strcat(edx_flags, "msr ");
if(edx & (1<<6))
strcat(edx_flags, "pae ");
if(edx & (1<<7))
strcat(edx_flags, "mce ");
if(edx & (1<<8))
strcat(edx_flags, "cx8 ");
if(edx & (1<<9))
strcat(edx_flags, "apic ");
if(edx & (1<<10))
strcat(edx_flags, "Reserved ");
if(edx & (1<<11))
strcat(edx_flags, "sep ");
if(edx & (1<<12))
strcat(edx_flags, "mtrr ");
if(edx & (1<<13))
strcat(edx_flags, "pge ");
if(edx & (1<<14))
strcat(edx_flags, "mca ");
if(edx & (1<<15))
strcat(edx_flags, "cmov ");
if(edx & (1<<17))
strcat(edx_flags, "pse-36 ");
if(edx & (1<<18))
strcat(edx_flags, "psn ");
if(edx & (1<<19))
strcat(edx_flags, "clfsh ");
if(edx & (1<<20))
strcat(edx_flags, "Reserved ");
if(edx & (1<<21))
strcat(edx_flags, "ds ");
if(edx & (1<<22))
strcat(edx_flags, "acpi ");
if(edx & (1<<23))
strcat(edx_flags, "mmx ");
if(edx & (1<<24))
strcat(edx_flags, "fxsr ");
if(edx & (1<<25))
strcat(edx_flags, "sse ");
if(edx & (1<<26))
strcat(edx_flags, "sse2 ");
if(edx & (1<<27))
strcat(edx_flags, "ss ");
if(edx & (1<<28))
strcat(edx_flags, "htt ");
if(edx & (1<<29))
strcat(edx_flags, "tm ");
if(edx & (1<<30))
strcat(edx_flags, "Reserved ");
if(edx & (1<<31))
strcat(edx_flags, "pbe ");

strcat(edx_flags, "\0");
return(edx_flags);
}

char * translate_vendor_id(dword_t *ebx, dword_t *ecx, dword_t *edx) {
char *byteArray = calloc(12 + 1, sizeof(char)); // vendor_id is fixed at 12 bytes

// convert from an unsigned long int to a 4-byte array
byteArray[0] = (int)((*ebx & 0XFF));
byteArray[1] = (int)((*ebx >> 8) & 0XFF);
byteArray[2] = (int)((*ebx >> 16) & 0xFF) ;
byteArray[3] = (int)((*ebx >> 24) & 0xFF) ;
byteArray[4] = (int)((*edx & 0XFF));
byteArray[5] = (int)((*edx >> 8) & 0XFF);
byteArray[6] = (int)((*edx >> 16) & 0xFF) ;
byteArray[7] = (int)((*edx >> 24) & 0xFF) ;
byteArray[8] = (int)((*ecx & 0XFF));
byteArray[9] = (int)((*ecx >> 8) & 0XFF);
byteArray[10] = (int)((*ecx >> 16) & 0xFF) ;
byteArray[11] = (int)((*ecx >> 24) & 0xFF) ;
byteArray[12] = 0;
return(byteArray);
}

static int proc_show_cpuinfo(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
dword_t *eax = malloc(sizeof(dword_t));
dword_t *ebx = malloc(sizeof(dword_t));
dword_t *ecx = malloc(sizeof(dword_t));
dword_t *edx = malloc(sizeof(dword_t));

*eax = 0x00; // Get vendor_id. It is returned as four bytes each in ebx, ecx & edx
do_cpuid(eax, ebx, ecx, edx); // Get vendor_id

char *vendor_id = calloc(12 + 1, sizeof(char)); // vendor_id is fixed at 12 bytes

vendor_id = translate_vendor_id(ebx, ecx, edx);

*eax = 1;
do_cpuid(eax, ebx, ecx, edx);

char *edx_flags=calloc(151, sizeof(char)); // Max size if all flags set
parse_edx_flags(*edx, edx_flags);

int cpu_count = get_cpu_count(); // One entry per device processor
int i;

for( i=0; i<cpu_count ; i++ ) {
proc_printf(buf, "processor : %d\n",i);
proc_printf(buf, "vendor_id : %s\n", vendor_id);
proc_printf(buf, "cpu family : %d\n",1);
proc_printf(buf, "model : %d\n",1);
proc_printf(buf, "model name : iSH Virtual i686-compatible CPU @ 1.066GHz\n");
proc_printf(buf, "stepping : %d\n",1);
proc_printf(buf, "CPU MHz : 1066.00\n");
proc_printf(buf, "cache size : %d kb\n",0);
proc_printf(buf, "pysical id : %d\n",0);
proc_printf(buf, "siblings : %d\n",0);
proc_printf(buf, "core id : %d\n",0);
proc_printf(buf, "cpu cores : %d\n",cpu_count);
proc_printf(buf, "apicid : %d\n",0);
proc_printf(buf, "initial apicid : %d\n",0);
proc_printf(buf, "fpu : yes\n");
proc_printf(buf, "fpu_exception : yes\n");
proc_printf(buf, "cpuid level : %d\n",13);
proc_printf(buf, "wp : yes\n");
proc_printf(buf, "flags : %s\n", edx_flags); // Pulled from do_cpuid
proc_printf(buf, "bogomips : 1066.00\n");
proc_printf(buf, "clflush size : %d\n", *ebx);
proc_printf(buf, "cache_alignment : %d\n",64);
proc_printf(buf, "address sizes : 36 bits physical, 32 bits virtual\n");
proc_printf(buf, "power management:\n");
proc_printf(buf, "\n");
}

free(edx_flags);
free(vendor_id);
return 0;
}

static int proc_show_stat(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
struct cpu_usage usage = get_cpu_usage();
proc_printf(buf, "cpu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64"\n", usage.user_ticks, usage.nice_ticks, usage.system_ticks, usage.idle_ticks);
Expand Down Expand Up @@ -97,6 +242,7 @@ static int proc_show_mounts(struct proc_entry *UNUSED(entry), struct proc_data *

// in alphabetical order
struct proc_dir_entry proc_root_entries[] = {
{"cpuinfo", .show = proc_show_cpuinfo},
{"ish", S_IFDIR, .children = &proc_ish_children},
{"meminfo", .show = proc_show_meminfo},
{"mounts", .show = proc_show_mounts},
Expand Down
7 changes: 7 additions & 0 deletions platform/darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ struct cpu_usage get_cpu_usage() {
return usage;
}

int get_cpu_count() {
int ncpu;
size_t size = sizeof(int);
sysctlbyname("hw.ncpu", &ncpu, &size, NULL, 0);
return ncpu;
}

struct mem_usage get_mem_usage() {
host_basic_info_data_t basic = {};
mach_msg_type_number_t fuck = HOST_BASIC_INFO_COUNT;
Expand Down
4 changes: 4 additions & 0 deletions platform/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ struct uptime_info get_uptime() {
};
return uptime;
}

int get_cpu_count() {
return get_nprocs();
}
2 changes: 2 additions & 0 deletions platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ struct uptime_info {
};
struct uptime_info get_uptime(void);

int get_cpu_count(void);

#endif