Sigrid Haflínudóttirfirst dirty version of the portd7ad0686 years agoHistory
442 lines · 9.5 KB · C
RawDownload
/*	PMUEMDEV.c 	Copyright (C) 2008 Paul C. Pratt 	You can redistribute this file and/or modify it under the terms	of version 2 of the GNU General Public License as published by	the Free Software Foundation.  You should have received a copy	of the license along with this file; see the file COPYING. 	This file is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	license for more details.*/ /*	Power Management Unit EMulated DEVice*/ #ifndef AllFiles#include "SYSDEPNS.h"#include "MYOSGLUE.h"#include "EMCONFIG.h"#include "GLOBGLUE.h"#include "VIAEMDEV.h"#endif #include "PMUEMDEV.h" /*	ReportAbnormalID unused 0x0E0E - 0x0EFF*/ enum {	kPMUStateReadyForCommand,	kPMUStateRecievingLength,	kPMUStateRecievingBuffer,	kPMUStateRecievedCommand,	kPMUStateSendLength,	kPMUStateSendBuffer, 	kPMUStates}; #define PMU_BuffSz 8LOCALVAR ui3b PMU_BuffA[PMU_BuffSz];LOCALVAR ui3p PMU_p;LOCALVAR ui3r PMU_rem;LOCALVAR ui3r PMU_i; LOCALVAR int PMUState = kPMUStateReadyForCommand; LOCALVAR ui3r PMU_CurCommand;LOCALVAR ui3r PMU_SendNext;LOCALVAR ui3r PMU_BuffL; LOCALPROC PmuStartSendResult(ui3r ResultCode, ui3r L){	PMU_SendNext = ResultCode;	PMU_BuffL = L;	PMUState = kPMUStateSendLength;} LOCALVAR ui3b PARAMRAM[128]; LOCALPROC PmuCheckCommandOp(void){	switch (PMU_CurCommand) {		case 0x10: /* kPMUpowerCntl - power plane/clock control */			break;		case 0x32: /* kPMUxPramWrite - write extended PRAM byte(s) */			if (kPMUStateRecievingBuffer == PMUState) {				if (0 == PMU_i) {					if (PMU_BuffL >= 2) {						PMU_p = PMU_BuffA;						PMU_rem = 2;					} else {						ReportAbnormalID(0x0E01,							"PMU_BuffL too small for kPMUxPramWrite");					}				} else if (2 == PMU_i) {					if ((PMU_BuffA[1] + 2 == PMU_BuffL)						&& (PMU_BuffA[0] + PMU_BuffA[1] <= 0x80))					{						PMU_p = &PARAMRAM[PMU_BuffA[0]];						PMU_rem = PMU_BuffA[1];					} else {						ReportAbnormalID(0x0E02,							"bad range for kPMUxPramWrite");					}				} else {					ReportAbnormalID(0x0E03,						"Wrong PMU_i for kPMUpramWrite");				}			} else if (kPMUStateRecievedCommand == PMUState) {				/* already done */			}			break;#if 0		case 0xE2: /* kPMUdownloadStatus - PRAM status */			break;#endif		case 0xE0: /* kPMUwritePmgrRAM - write to internal PMGR RAM */			break;		case 0x21: /* kPMUpMgrADBoff - turn ADB auto-poll off */			if (kPMUStateRecievedCommand == PMUState) {				if (0 != PMU_BuffL) {					ReportAbnormalID(0x0E04,						"kPMUpMgrADBoff nonzero length");				}			}			break;		case 0xEC: /* kPMUPmgrSelfTest - run the PMGR selftest */			if (kPMUStateRecievedCommand == PMUState) {				PmuStartSendResult(0, 0);			}			break;		case 0x78:			/* kPMUreadINT - get PMGR interrupt data */		case 0x68:			/*				kPMUbatteryRead - read battery/charger level and status			*/		case 0x7F:			/*				kPMUsleepReq - put the system to sleep (sleepSig='MATT')			*/			if (kPMUStateRecievedCommand == PMUState) {				PMU_BuffA[0] = 0;				PmuStartSendResult(0, 1);			}			break;		case 0xE8: /* kPMUreadPmgrRAM - read from internal PMGR RAM */			if (kPMUStateRecievedCommand == PMUState) {				if ((3 == PMU_BuffL)					&& (0 == PMU_BuffA[0])					&& (0xEE == PMU_BuffA[1])					&& (1 == PMU_BuffA[2]))				{					PMU_BuffA[0] = 1 << 5;					PmuStartSendResult(0, 1);				} else {					PMU_BuffA[0] = 0;					PmuStartSendResult(0, 1);					/* ReportAbnormal("Unknown kPMUreadPmgrRAM op"); */				}			}			break;		case 0x3A: /* kPMUxPramRead - read extended PRAM byte(s) */			if (kPMUStateRecievedCommand == PMUState) {				if ((2 == PMU_BuffL)					&& (PMU_BuffA[0] + PMU_BuffA[1] <= 0x80))				{					PMU_p = &PARAMRAM[PMU_BuffA[0]];					PMU_rem = PMU_BuffA[1];					PmuStartSendResult(0, PMU_rem);				} else {					ReportAbnormalID(0x0E05,						"Unknown kPMUxPramRead op");				}			}			break;		case 0x38:			/* kPMUtimeRead - read the time from the clock chip */			if (kPMUStateRecievedCommand == PMUState) {				if (0 == PMU_BuffL) {					PMU_BuffA[0] = 0;					PMU_BuffA[1] = 0;					PMU_BuffA[2] = 0;					PMU_BuffA[3] = 0;					PmuStartSendResult(0, 4);				} else {					ReportAbnormalID(0x0E06, "Unknown kPMUtimeRead op");				}			}			break;		case 0x31:			/*				kPMUpramWrite - write the original 20 bytes of PRAM				(Portable only)			*/			if (kPMUStateRecievedCommand == PMUState) {				if (20 == PMU_BuffL) {					/* done */				} else {					ReportAbnormalID(0x0E07,						"Unknown kPMUpramWrite op");				}			} else if (kPMUStateRecievingBuffer == PMUState) {				if (20 == PMU_BuffL) {					if (0 == PMU_i) {						PMU_p = &PARAMRAM[16];						PMU_rem = 16;					} else if (16 == PMU_i) {						PMU_p = &PARAMRAM[8];						PMU_rem = 4;					} else {						ReportAbnormalID(0x0E08,							"Wrong PMU_i for kPMUpramWrite");					}				}			}			break;		case 0x39:			/*				kPMUpramRead - read the original 20 bytes of PRAM				(Portable only)			*/			if (kPMUStateRecievedCommand == PMUState) {				if (0 == PMU_BuffL) {					PmuStartSendResult(0, 20);				} else {					ReportAbnormalID(0x0E09, "Unknown kPMUpramRead op");				}			} else if (kPMUStateSendBuffer == PMUState) {#if 0				{					int i; 					for (i = 0; i < PMU_BuffSz; ++i) {						PMU_BuffA[i] = 0;					}				}#endif				if (0 == PMU_i) {					PMU_p = &PARAMRAM[16];					PMU_rem = 16;				} else if (16 == PMU_i) {					PMU_p = &PARAMRAM[8];					PMU_rem = 4;				} else {					ReportAbnormalID(0x0E0A,						"Wrong PMU_i for kPMUpramRead");				}			}			break;		default:			if (kPMUStateRecievedCommand == PMUState) {				ReportAbnormalID(0x0E0B, "Unknown PMU op");#if dbglog_HAVE				dbglog_writeCStr("Unknown PMU op ");				dbglog_writeHex(PMU_CurCommand);				dbglog_writeReturn();				dbglog_writeCStr("PMU_BuffL = ");				dbglog_writeHex(PMU_BuffL);				dbglog_writeReturn();				if (PMU_BuffL <= PMU_BuffSz) {					int i; 					for (i = 0; i < PMU_BuffL; ++i) {						dbglog_writeCStr("PMU_BuffA[");						dbglog_writeNum(i);						dbglog_writeCStr("] = ");						dbglog_writeHex(PMU_BuffA[i]);						dbglog_writeReturn();					}				}#endif			}			break;	}} LOCALPROC LocBuffSetUpNextChunk(void){	PMU_p = PMU_BuffA;	PMU_rem = PMU_BuffL - PMU_i;	if (PMU_rem >= PMU_BuffSz) {		PMU_rem = PMU_BuffSz;	}} LOCALFUNC ui3r GetPMUbus(void){	ui3r v; 	v = VIA1_iA7;	v <<= 1;	v |= VIA1_iA6;	v <<= 1;	v |= VIA1_iA5;	v <<= 1;	v |= VIA1_iA4;	v <<= 1;	v |= VIA1_iA3;	v <<= 1;	v |= VIA1_iA2;	v <<= 1;	v |= VIA1_iA1;	v <<= 1;	v |= VIA1_iA0; 	return v;} LOCALPROC SetPMUbus(ui3r v){	VIA1_iA0 = v & 0x01;	v >>= 1;	VIA1_iA1 = v & 0x01;	v >>= 1;	VIA1_iA2 = v & 0x01;	v >>= 1;	VIA1_iA3 = v & 0x01;	v >>= 1;	VIA1_iA4 = v & 0x01;	v >>= 1;	VIA1_iA5 = v & 0x01;	v >>= 1;	VIA1_iA6 = v & 0x01;	v >>= 1;	VIA1_iA7 = v & 0x01;} LOCALVAR blnr PMU_Sending = falseblnr; LOCALPROC PmuCheckCommandCompletion(void){	if (PMU_i == PMU_BuffL) {		PMUState = kPMUStateRecievedCommand;		PmuCheckCommandOp();		if ((PMU_CurCommand & 0x08) == 0) {			PMUState = kPMUStateReadyForCommand;			SetPMUbus(0xFF);		} else {			if (PMUState != kPMUStateSendLength) {				PmuStartSendResult(0xFF, 0);				PMUState = kPMUStateSendLength;			}			PMU_i = 0;			PMU_Sending = trueblnr;			ICT_add(kICT_PMU_Task,				20400UL * kCycleScale / 64 * kMyClockMult);		}	}} GLOBALPROC PmuToReady_ChangeNtfy(void){	if (PMU_Sending) {		PMU_Sending = falseblnr;		ReportAbnormalID(0x0E0C,			"PmuToReady_ChangeNtfy while PMU_Sending");		PmuFromReady = 0;	}	switch (PMUState) {		case kPMUStateReadyForCommand:			if (! PmuToReady) {				PmuFromReady = 0;			} else {				PMU_CurCommand = GetPMUbus();				PMUState = kPMUStateRecievingLength;				PmuFromReady = 1;			}			break;		case kPMUStateRecievingLength:			if (! PmuToReady) {				PmuFromReady = 0;			} else {				PMU_BuffL = GetPMUbus();				PMU_i = 0;				PMU_rem = 0;				PMUState = kPMUStateRecievingBuffer;				PmuCheckCommandCompletion();				PmuFromReady = 1;			}			break;		case kPMUStateRecievingBuffer:			if (! PmuToReady) {				PmuFromReady = 0;			} else {				ui3r v = GetPMUbus();				if (0 == PMU_rem) {					PMU_p = nullpr;					PmuCheckCommandOp();					if (nullpr == PMU_p) {						/* default handler */						LocBuffSetUpNextChunk();					}				}				if (nullpr == PMU_p) {					/* mini vmac bug if ever happens */					ReportAbnormalID(0x0E0D,						"PMU_p null while kPMUStateRecievingBuffer");				}				*PMU_p++ = v;				--PMU_rem;				++PMU_i;				PmuCheckCommandCompletion();				PmuFromReady = 1;			}			break;		case kPMUStateSendLength:			if (! PmuToReady) {				/* receiving */				PmuFromReady = 1;			} else {				PMU_SendNext = PMU_BuffL;				PMUState = kPMUStateSendBuffer;				PMU_Sending = trueblnr;				ICT_add(kICT_PMU_Task,					20400UL * kCycleScale / 64 * kMyClockMult);			}			break;		case kPMUStateSendBuffer:			if (! PmuToReady) {				/* receiving */				PmuFromReady = 1;			} else {				if (PMU_i == PMU_BuffL) {					PMUState = kPMUStateReadyForCommand;					SetPMUbus(0xFF);				} else {					if (0 == PMU_rem) {						PMU_p = nullpr;						PmuCheckCommandOp();						if (nullpr == PMU_p) {							/* default handler */							LocBuffSetUpNextChunk();						}					}					PMU_SendNext = *PMU_p++;					--PMU_rem;					++PMU_i;					PMU_Sending = trueblnr;					ICT_add(kICT_PMU_Task,						20400UL * kCycleScale / 64 * kMyClockMult);				}			}			break;	}} GLOBALPROC PMU_DoTask(void){	if (PMU_Sending) {		PMU_Sending = falseblnr;		SetPMUbus(PMU_SendNext);		PmuFromReady = 0;	}}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t