cLK/lk/target/htcleo/oem_cmd.c
2011-03-25 23:39:33 +02:00

149 lines
3.4 KiB
C

/*
* License: GPL
* Author: cedesmith
*/
#include <debug.h>
#include <string.h>
#include <stdlib.h>
#include <reg.h>
void fastboot_okay(const char *info);
void fastboot_fail(const char *reason);
int fastboot_write(void *buf, unsigned len);
void fastboot_register(const char *prefix, void (*handle)(const char *arg, void *data, unsigned sz));
static char charVal(char c)
{
c&=0xf;
if(c<=9) return '0'+c;
return 'A'+(c-10);
}
static void send_mem(char* start, int len)
{
char response[64];
while(len>0)
{
int slen = len > 29 ? 29 : len;
memcpy(response, "INFO", 4);
response[4]=slen;
for(int i=0; i<slen; i++)
{
response[5+i*2] = charVal(start[i]>>4);
response[5+i*2+1]= charVal(start[i]);
}
response[5+slen*2+1]=0;
fastboot_write(response, 5+slen*2);
start+=slen;
len-=slen;
}
}
static void cmd_oem_smesg()
{
send_mem((char*)0x1fe00018, MIN(0x200000, readl(0x1fe00000)));
fastboot_okay("");
}
static void cmd_oem_dmesg()
{
if(*((unsigned*)0x2FFC0000) == 0x43474244 /* DBGC */ ) //see ram_console_buffer in kernel ram_console.c
{
send_mem((char*)0x2FFC000C, *((unsigned*)0x2FFC0008));
}
fastboot_okay("");
}
static int str2u(const char *x)
{
while(*x==' ')x++;
unsigned base=10;
int sign=1;
unsigned n = 0;
if(strstr(x,"-")==x) { sign=-1; x++;};
if(strstr(x,"0x")==x) {base=16; x+=2;}
while(*x) {
char d=0;
switch(*x) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
d = *x - '0';
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
d = (*x - 'a' + 10);
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
d = (*x - 'A' + 10);
break;
default:
return sign*n;
}
if(d>=base) return sign*n;
n*=base;n+=d;
x++;
}
return sign*n;
}
static void cmd_oem_dumpmem(const char *arg)
{
char *sStart = strtok((char*)arg, " ");
char *sLen = strtok(NULL, " ");
if(sStart==NULL || sLen==NULL)
{
fastboot_fail("usage:oem dump start len");
return;
}
send_mem((char*)str2u(sStart), str2u(sLen));
fastboot_okay("");
}
static void cmd_oem_set(const char *arg)
{
char type=*arg; arg++;
char *sAddr = strtok((char*) arg, " ");
char *sVal = strtok(NULL, "\0");
if(sAddr==NULL || sVal==NULL)
{
fastboot_fail("usage:oem set[s,c,w] address value");
return;
}
char buff[64];
switch(type)
{
case 's':
memcpy((void*)str2u(sAddr), sVal, strlen(sVal));
send_mem((char*)str2u(sAddr), strlen(sVal));
break;
case 'c':
*((char*)str2u(sAddr)) = (char)str2u(sVal);
sprintf(buff, "%x", *((char*)str2u(sAddr)));
send_mem(buff, strlen(buff));
break;
case 'w':
default:
*((int*)str2u(sAddr)) = str2u(sVal);
sprintf(buff, "%x", *((int*)str2u(sAddr)));
send_mem(buff, strlen(buff));
}
fastboot_okay("");
}
static void cmd_oem(const char *arg, void *data, unsigned sz)
{
while(*arg==' ') arg++;
if(memcmp(arg, "dmesg", 5)==0) cmd_oem_dmesg();
if(memcmp(arg, "smesg", 5)==0) cmd_oem_smesg();
if(memcmp(arg, "pwf ", 4)==0) cmd_oem_dumpmem(arg+4);
if(memcmp(arg, "set", 3)==0) cmd_oem_set(arg+3);
}
void cmd_oem_register()
{
fastboot_register("oem", cmd_oem);
}