/* $Id: proc.c,v 1.2 2005/06/16 13:46:21 cgoh Exp $
 *
 * proc.c: functions used for /proc filesystem
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) Equator Technologies
 */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/delay.h>

#include <eti/mm.h>
#include <libdev/etiProcessor.h>

#define ETI_CPUID_FAMILY_MASK 0x00ff0000
#define ETI_CPUID_MAJOR_MASK  0x0000ff00
#define ETI_CPUID_MINOR_MASK  0x000000ff
#define ETI_CPUID_FAMILY_SHIFT 16
#define ETI_CPUID_MAJOR_SHIFT  8
#define ETI_CPUID_MINOR_SHIFT  0

int get_cpuinfo(char *buf)
{
	int len = 0;
	u32 cpuid = hmpv_read_cpuid_cl0();

	procCapabilities_t  caps;
	procGetCapabilities(&caps);

	len += sprintf(buf+len, "CPU\t\t: ");

	/* CPU ID */
	if (cpuid) {
		char family[32];
		int major, minor;

		/* family */
		switch((cpuid & ETI_CPUID_FAMILY_MASK)) {
		case 0x000000:
			strcpy(family, "MAP-1000[a]");
			break;
		case 0x010000:
			strcpy(family, "MAP-CA");
			break;
		case 0x020000:
			strcpy(family, "BSP");
			break;
		default:
			strcpy(family, "unknown");
			break;
		} /* switch */

	  
		/* major */
		major = (cpuid & ETI_CPUID_MAJOR_MASK) >> ETI_CPUID_MAJOR_SHIFT;
		major += 1; /* zero was skipped */

		/* minor */
		minor = (cpuid & ETI_CPUID_MINOR_MASK);

		len += sprintf(buf+len, "%s %d.%d (0x%x)\n", 
			       family, major, minor, cpuid);
	}
	else {
		len += sprintf(buf+len, "unknown\n");
	}

	/* CPU frequency */
	len += sprintf(buf+len, "cpu MHz\t\t: %lu.%03lu\n",
		       caps.cpuFrequency / 1000000,
		       caps.cpuFrequency % 1000000);

        /* memory speed */
        len += sprintf(buf+len, "mem MHz\t\t: %lu.%03lu\n",
		       caps.memFrequency / 1000000,
		       caps.memFrequency % 1000000);

	/* BogoMIPS */
	len += sprintf(buf+len, "BogoMIPS\t: %lu.%02lu\n",
		       loops_per_jiffy/(500000/HZ),
		       (loops_per_jiffy/(5000/HZ)) % 100);

	return len;
}


/* -------------------------------------------------------------------------- */

#include <etilib/etiTypes.h>
#include <linux/proc_fs.h>
#include <stdarg.h>
#include <libdev/etiDevReg.h>
#include <kernelLib/etiDriverOsal.h>

#include "etilib/etiLocal.h"
#include "etilib/etiMempool.h"

static int read_eti_devices(char *buf, char **start, off_t offset, int len, int unused)
{
    devReg_t      deviceHandle = Null;
    devRegInfo_t  * deviceInfo;
    etiVersion_t boardVersion;
    UInt *boardId;
    UInt dBoardId;
    etiVersion_t dBoardVersion;
    
    __identifyBoard( &boardId,  &boardVersion, &dBoardId, &dBoardVersion);
    
    len = sprintf(buf,"Board Name '%s'\n",brdGetBoardName(boardId) );
    if (dBoardId !=0)  len += sprintf(buf+len,"Daughter Board Name '%s'\n",brdGetDaughterBoardName(dBoardId) );
    
    len += sprintf(buf+len,"List of eti devices registered :\n");
    
    do {    
        
        devRegGetListInfo( &deviceHandle, &deviceInfo );
             
        if( deviceInfo ) {
            len += sprintf(buf+len, "Device Name: %-25s ", deviceInfo->name);
            len += sprintf(buf+len, "Type: %-20s Flags: 0x%-7x inUse: %-5d\n", devRegGetTypeName(deviceInfo->type), deviceInfo->flags, deviceInfo->inUse);
        
        }
    
    } while( deviceHandle );

    return len;
}


static int read_osal_mempoolInfo(char *buf, char **start, off_t offset, int len, int unused)
{
    etiMempoolInfo_t info;
    
    etiMempoolGetInfo( etiSystemMemPool, &info );
    
    len = sprintf(buf,"Osal System Mempool information \n" );
    len += sprintf(buf+len,"incrementSize :       %d\n", info.incrementSize );
    len += sprintf(buf+len,"Nb chunks     :       %d \n", info.nbChunks );
    len += sprintf(buf+len,"Totol Chunk Size :    %d \n", info.totalChunksSize );
    
    len += sprintf(buf+len,"Total free memory :   %d \n", info.totalFreeBlocksSize );
    len += sprintf(buf+len,"Total Nb free blocks :%d \n", info.nbFreeBlocks );   
    len += sprintf(buf+len,"Biggest Free Block size: %d \n", info.maxFreeBlockSize );     
     
    len += sprintf(buf+len,"Total used memory :   %d \n", info.totalUsedBlocksSize ); 
    len += sprintf(buf+len,"Total Nb Used Blocks: %d \n", info.nbUsedBlocks );  
    len += sprintf(buf+len,"Biggest Used Block size: %d \n", info.maxUsedBlockSize );          
    return len;
}



static struct proc_dir_entry proc_entry_devices = {
        0,
        10, "etidevices",
        S_IFREG | S_IRUGO,
        1,0,0,
        0,
        NULL,
        &read_eti_devices,
    };

static struct proc_dir_entry proc_entry_mem = {
        0,
        14, "etiOsalMempool",
        S_IFREG | S_IRUGO,
        1,0,0,
        0,
        NULL,
        &read_osal_mempoolInfo,
    };


static UInt proc_eti_init()
{
    proc_register( &proc_root, &proc_entry_devices);
    proc_register( &proc_root, &proc_entry_mem);
    return 0;
}



/*
 * Add it to etiDriverOsal's autoinit list:
 */
drosDefineDriverInit(proc_eti_init)


