Cxbx-Reloaded/import/OpenXDK/include/xusb/boot.h

625 lines
19 KiB
C

#ifndef _Boot_H_
#define _Boot_H_
/***************************************************************************
Includes used by XBox boot code
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/////////////////////////////////
// configuration
#include <stdarg.h>
#include <stdio.h>
#include "consts.h"
// BB
#if 0
#include "jpeglib.h"
#endif
unsigned int cromwell_config;
unsigned int cromwell_retryload;
unsigned int cromwell_loadbank;
unsigned int cromwell_Biostype;
unsigned int xbox_ram;
#define XROMWELL 0
#define CROMWELL 1
#define ICON_WIDTH 64
#define ICON_HEIGH 64
static _inline double min (double a, double b)
{
if (a < b) return a; else return b;
}
static _inline double max (double a, double b)
{
if (a > b) return a; else return b;
}
// filtror is a debugging device designed to make code available over LPC and allow a debug shell
// details are at http://warmcat.com/milksop
// if you don't have one, or are building a final ROM image, keep this at zero
#define INCLUDE_FILTROR 0
// enable logging to serial port. You probably don't have this.
#define INCLUDE_SERIAL 0
// enable trace message printing for debugging - with filtror or serial only
#define PRINT_TRACE 0
#if PRINT_TRACE
#define TRACE bprintf(__FILE__ " :%d\n\r",__LINE__);
#else
#define TRACE
#endif
#define INITRD_POS 0x02000000
/////////////////////////////////
// some typedefs to make for easy sizing
typedef unsigned long ULONG;
typedef unsigned int DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;
#ifndef bool_already_defined_
typedef int bool;
#endif
typedef unsigned long RGBA; // LSB=R -> MSB = A
//typedef long long __int64;
#define guint int
#define guint8 unsigned char
#define true 1
#define false 0
#ifndef NULL
#define NULL ((void *)0)
#endif
#define ASSERT(exp) { if(!(exp)) { bprintf("Assert failed file " __FILE__ " line %d\n", __LINE__); } }
// BB
#if 0
#include "BootFilesystemIso9660.h"
#endif
extern void WATCHDOG(void);
#include "BootVideo.h"
extern volatile CURRENT_VIDEO_MODE_DETAILS currentvideomodedetails;
volatile DWORD VIDEO_CURSOR_POSX;
volatile DWORD VIDEO_CURSOR_POSY;
volatile DWORD VIDEO_ATTR;
volatile DWORD VIDEO_LUMASCALING;
volatile DWORD VIDEO_RSCALING;
volatile DWORD VIDEO_BSCALING;
volatile DWORD VIDEO_VSYNC_COUNT;
volatile DWORD BIOS_TICK_COUNT;
volatile DWORD VIDEO_VSYNC_POSITION;
volatile DWORD VIDEO_VSYNC_DIR;
volatile DWORD DVD_TRAY_STATE;
#define DVD_CLOSED 0
#define DVD_CLOSING 1
#define DVD_OPEN 2
#define DVD_OPENING 3
/////////////////////////////////
// Superfunky i386 internal structures
typedef struct gdt_t {
unsigned short m_wSize __attribute__ ((packed));
unsigned long m_dwBase32 __attribute__ ((packed));
unsigned short m_wDummy __attribute__ ((packed));
} ts_descriptor_pointer;
typedef struct { // inside an 8-byte protected mode interrupt vector
WORD m_wHandlerHighAddressLow16;
WORD m_wSelector;
WORD m_wType;
WORD m_wHandlerLinearAddressHigh16;
} ts_pm_interrupt;
typedef enum {
EDT_UNKNOWN= 0,
EDT_XBOXFS
} enumDriveType;
typedef struct tsHarddiskInfo { // this is the retained knowledge about an IDE device after init
unsigned short m_fwPortBase;
unsigned short m_wCountHeads;
unsigned short m_wCountCylinders;
unsigned short m_wCountSectorsPerTrack;
unsigned long m_dwCountSectorsTotal; /* total */
unsigned char m_bLbaMode; /* am i lba (0x40) or chs (0x00) */
unsigned char m_szIdentityModelNumber[40];
unsigned char term_space_1[2];
unsigned char m_szSerial[20];
unsigned char term_space_2[2];
char m_szFirmware[8];
unsigned char term_space_3[2];
unsigned char m_fDriveExists;
unsigned char m_fAtapi; // true if a CDROM, etc
enumDriveType m_enumDriveType;
unsigned char m_bCableConductors; // valid for device 0 if present
unsigned short m_wAtaRevisionSupported;
unsigned char s_length;
unsigned char m_length;
unsigned char m_fHasMbr;
} tsHarddiskInfo;
/* a retail Xbox has 64 MB of RAM */
#define RAMSIZE (64 * 1024*1024)
/* the size of the framebuffer (defaults to 4 MB) */
#define FRAMEBUFFER_SIZE 0x00400000
/* the start of the framebuffer */
#define FRAMEBUFFER_START (0xf0000000 | (RAMSIZE - FRAMEBUFFER_SIZE))
/* the protected mode part of the kernel has to reside at 1 MB in RAM */
#define PM_KERNEL_DEST 0x100000
/* parameters for the kernel have to be here */
#define KERNEL_SETUP 0x90000
/* the GDT must not be overwritten, so we place it into an unused
area within KERNEL_SETUP */
#define GDT_LOC (KERNEL_SETUP+0x800)
/* same with the command line */
#define CMD_LINE_LOC (KERNEL_SETUP+0x1000)
/* let's reserve 4 MB at the top for the framebuffer */
#define RAMSIZE_USE (RAMSIZE - FRAMEBUFFER_SIZE)
/* the initrd resides at 1 MB from the top of RAM */
#define INITRD_DEST (RAMSIZE_USE - 1024*1024)
//#define LPCFlashadress 0xFFF00000
#define LPCFlashadress 0xFF000000
/////////////////////////////////
// LED-flashing codes
// or these together as argument to I2cSetFrontpanelLed
enum {
I2C_LED_RED0 = 0x80,
I2C_LED_RED1 = 0x40,
I2C_LED_RED2 = 0x20,
I2C_LED_RED3 = 0x10,
I2C_LED_GREEN0 = 0x08,
I2C_LED_GREEN1 = 0x04,
I2C_LED_GREEN2 = 0x02,
I2C_LED_GREEN3 = 0x01
};
///////////////////////////////
/* BIOS-wide error codes all have b31 set */
enum {
ERR_SUCCESS = 0, // completed without error
ERR_I2C_ERROR_TIMEOUT = 0x80000001, // I2C action failed because it did not complete in a reasonable time
ERR_I2C_ERROR_BUS = 0x80000002, // I2C action failed due to non retryable bus error
ERR_BOOT_PIC_ALG_BROKEN = 0x80000101 // PIC algorithm did not pass its self-test
};
/////////////////////////////////
// some Boot API prototypes
//////// BootPerformPicChallengeResponseAction.c
/* ---------------------------- IO primitives -----------------------------------------------------------
*/
static __inline void IoOutputByte(WORD wAds, BYTE bValue) {
// __asm__ (" out %%al,%%dx" : : "edx" (dwAds), "al" (bValue) );
__asm__ __volatile__ ("outb %b0,%w1": :"a" (bValue), "Nd" (wAds));
}
static __inline void IoOutputWord(WORD wAds, WORD wValue) {
// __asm__ (" out %%ax,%%dx " : : "edx" (dwAds), "ax" (wValue) );
__asm__ __volatile__ ("outw %0,%w1": :"a" (wValue), "Nd" (wAds));
}
static __inline void IoOutputDword(WORD wAds, DWORD dwValue) {
// __asm__ (" out %%eax,%%dx " : : "edx" (dwAds), "ax" (wValue) );
__asm__ __volatile__ ("outl %0,%w1": :"a" (dwValue), "Nd" (wAds));
}
static __inline BYTE IoInputByte(WORD wAds) {
unsigned char _v;
__asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
static __inline WORD IoInputWord(WORD wAds) {
WORD _v;
__asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
static __inline DWORD IoInputDword(WORD wAds) {
DWORD _v;
__asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
: "=a" (val1), "=d" (val2) \
: "c" (msr))
#define wrmsr(msr,val1,val2) \
__asm__ __volatile__("wrmsr" \
: /* no outputs */ \
: "c" (msr), "a" (val1), "d" (val2))
void BootPciInterruptEnable(void);
// boot process
int BootPerformPicChallengeResponseAction(void);
// LED control (see associated enum above)
int I2cSetFrontpanelLed(BYTE b);
//////// filtror.c
#if INCLUDE_FILTROR
typedef struct {
DWORD m_dwBlocksFromPc;
DWORD m_dwCountChecksumErrorsSeenFromPc;
DWORD m_dwBlocksToPc;
DWORD m_dwCountTimeoutErrorsSeenToPc; // this member should be incremented by the higher-level protocol when expected response does not happen
} BOOTFILTROR_CHANNEL_QUALITY_STATS;
extern BOOTFILTROR_CHANNEL_QUALITY_STATS bfcqs;
// helpers
int BootFiltrorGetIncomingMessageLength(void);
void BootFiltrorMarkIncomingMessageAsHavingBeenRead(void) ;
bool BootFiltrorDoesPcHaveAMessageWaitingForItToRead(void);
void BootFiltrorSetMessageLengthForPcToRead(WORD wChecksum, WORD wLength) ;
int DumpAddressAndData(DWORD dwAds, const BYTE * baData, DWORD dwCountBytesUsable);
// main functions
int BootFiltrorSendArrayToPc(const BYTE * pba, WORD wLength);
int BootFiltrorGetArrayFromPc( BYTE * pba, WORD wLengthMax);
int BootFiltrorSendArrayToPcModal(const BYTE * pba, WORD wLength);
int BootFiltrorSendStringToPcModal(const char *szFormat, ...);
// alias
#define bprintf BootFiltrorSendStringToPcModal
#else
#if INCLUDE_SERIAL
#define bprintf serialprint
#else
#define bprintf(...)
#endif
#endif
#if INCLUDE_SERIAL
int serialprint(const char *szFormat, ...);
#endif
#define SPAMI2C() __asm__ __volatile__ (\
"retry: ; "\
"movb $0x55, %al ;"\
"movl $0xc004, %edx ;"\
"shl $1, %al ;"\
"out %al, %dx ;"\
\
"movb $0xaa, %al ;"\
"add $4, %edx ;"\
"out %al, %dx ;"\
\
"movb $0xbb, %al ;"\
"sub $0x2, %edx ;"\
"out %al, %dx ;"\
\
"sub $6, %edx ;"\
"in %dx, %ax ;"\
"out %ax, %dx ;"\
"add $2, %edx ;"\
"movb $0xa, %al ;"\
"out %al, %dx ;"\
"sub $0x2, %dx ;"\
"spin: ;"\
"in %dx, %al ;"\
"test $8, %al ;"\
"jnz spin ;"\
"test $8, %al ;"\
"jnz retry ;"\
"test $0x24, %al ;"\
\
"jmp retry"\
);
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *m_plistentryNext;
struct _LIST_ENTRY *m_plistentryPrevious;
} LIST_ENTRY;
void ListEntryInsertAfterCurrent(LIST_ENTRY *plistentryCurrent, LIST_ENTRY *plistentryNew);
void ListEntryRemove(LIST_ENTRY *plistentryCurrent);
////////// BootPerformXCodeActions.c
int BootPerformXCodeActions(void);
#include "BootEEPROM.h"
///////// BootParser.c
#define MAX_LINE 1024
typedef struct _CONFIGENTRY {
int nValid;
char szPath[MAX_LINE];
char szKernel[MAX_LINE];
char szInitrd[MAX_LINE];
char szAppend[MAX_LINE];
int nRivaFB;
int nVesaFB;
} CONFIGENTRY, *LPCONFIGENTRY;
int ParseConfig(char *szBuffer, CONFIGENTRY *entry, EEPROMDATA *eeprom);
////////// BootStartBios.c
void StartBios(CONFIGENTRY *config,int nActivePartition, int nFATXPresent,int bootfrom);
int BootMenue(CONFIGENTRY *config,int nDrive,int nActivePartition, int nFATXPresent);
////////// BootResetActions.c
void ClearIDT (void);
void BootResetAction(void);
void BootCpuCache(bool fEnable) ;
int printk(const char *szFormat, ...);
void BiosCmosWrite(BYTE bAds, BYTE bData);
BYTE BiosCmosRead(BYTE bAds);
///////// BootPciPeripheralInitialization.c
void BootPciPeripheralInitialization(void);
extern void ReadPCIByte(unsigned int bus, unsigned int dev, unsigned intfunc, unsigned int reg_off, unsigned char *pbyteval);
extern void WritePCIByte(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char byteval);
extern void ReadPCIDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int *pdwordval);
extern void WritePCIDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int dwordval);
extern void ReadPCIBlock(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char *buf, unsigned int nbytes);
extern void WritePCIBlock(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned char *buf, unsigned int nbytes);
void PciWriteByte (unsigned int bus, unsigned int dev, unsigned int func,
unsigned int reg_off, unsigned char byteval);
BYTE PciReadByte(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off);
DWORD PciWriteDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, DWORD dw);
DWORD PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off);
///////// BootPerformPicChallengeResponseAction.c
int I2CTransmitWord(BYTE bPicAddressI2cFormat, WORD wDataToWrite);
int I2CTransmitByteGetReturn(BYTE bPicAddressI2cFormat, BYTE bDataToWrite);
bool I2CGetTemperature(int *, int *);
void I2CModifyBits(BYTE bAds, BYTE bReg, BYTE bData, BYTE bMask);
///////// BootIde.c
extern tsHarddiskInfo tsaHarddiskInfo[]; // static struct stores data about attached drives
int BootIdeInit(void);
int BootIdeReadSector(int nDriveIndex, void * pbBuffer, unsigned int block, int byte_offset, int n_bytes);
int BootIdeBootSectorHddOrElTorito(int nDriveIndex, BYTE * pbaResult);
int BootIdeAtapiAdditionalSenseCode(int nDrive, BYTE * pba, int nLengthMaxReturn);
BYTE BootIdeGetTrayState(void);
int BootIdeSetTransferMode(int nIndexDrive, int nMode);
int BootIdeWaitNotBusy(unsigned uIoBase);
bool BootIdeAtapiReportFriendlyError(int nDriveIndex, char * szErrorReturn, int nMaxLengthError);
void BootIdeAtapiPrintkFriendlyError(int nDriveIndex);
///////// BootUSB.c
void BootStopUSB(void);
void BootStartUSB(void);
void USBGetEvents(void);
#include "xpad.h"
extern struct xpad_data XPAD_current[4];
extern struct xpad_data XPAD_last[4];
///////// BootEthernet.c
int BootStartUpEthernet(void);
///////// BootAudio.c
typedef struct {
WORD m_wTimeStartmS;
WORD m_wTimeDurationmS;
DWORD m_dwFrequency;
} SONG_NOTE;
typedef enum {
AET_SINE=0,
AET_NOISE
} AUDIO_ELEMENT_TYPES;
typedef void (*CALLBACK_AFTER_BLOCK)(void * pvoidAc97Device, void * pvoidaudioelement);
typedef struct _AUDIO_ELEMENT { // represents a kind of generated sound, needs a derived object to be usable
struct _AUDIO_ELEMENT * m_paudioelementNext;
short m_sPanZeroIsAllLeft7FFFIsAllRight;
AUDIO_ELEMENT_TYPES m_aetType;
DWORD m_dwVolumeElementMaster7fff0000Max;
DWORD m_dwVolumeAttackRate;
DWORD m_dwVolumeAttackLimit;
DWORD m_dwVolumeSustainRate;
DWORD m_dwVolumeSustainLimit;
DWORD m_dwVolumeDecayRate;
BYTE m_bStageZeroIsAttack;
void * m_pvPayload;
DWORD m_dwPayload2;
CALLBACK_AFTER_BLOCK m_callbackEveryBufferFill;
DWORD m_dwCount48kHzSamplesRendered;
} AUDIO_ELEMENT;
typedef struct _AUDIO_ELEMENT_SINE { // derived object composed from base object AUDIO_ELEMENT represents a sine wave with harmonics
AUDIO_ELEMENT m_paudioelement;
DWORD m_dwComputedFundamentalPhaseIncrementFor48kHzSamples;
short m_saVolumePerHarmonicZeroIsNone7FFFIsFull[5]; // first entry is fundamental, then 2nd harmonic, etc
DWORD m_dwPhaseAccumilator[5];
} AUDIO_ELEMENT_SINE;
typedef struct _AUDIO_ELEMENT_NOISE { // derived object composed from base object AUDIO_ELEMENT represents a whitish noise source
AUDIO_ELEMENT m_paudioelement;
short m_sVolumeZeroIsNone7FFFIsFull;
union {
DWORD m_dwShifter;
short m_saSamples[2];
} shifter;
short m_sLastSample;
} AUDIO_ELEMENT_NOISE;
typedef struct { // descriptor from AC97 specification
DWORD m_dwBufferStartAddress;
WORD m_wBufferLengthInSamples; // 0=no smaples
WORD m_wBufferControl; // b15=1=issue IRQ on completion, b14=1=last in stream
} AC97_DESCRIPTOR __attribute__ ((aligned (8)));
typedef struct {
AC97_DESCRIPTOR m_aac97descriptorPcmSpdif[32];
AC97_DESCRIPTOR m_aac97descriptorPcmOut[32];
volatile DWORD * m_pdwMMIO;
volatile DWORD m_dwCount48kHzSamplesRendered;
volatile DWORD m_dwNextDescriptorMod31;
AUDIO_ELEMENT * m_paudioelementFirst;
} AC97_DEVICE __attribute__ ((aligned (8))) ;
void wait_ms(DWORD ticks);
void wait_smalldelay(void);
void BootAudioInit(volatile AC97_DEVICE * pac97device);
void BootAudioInterrupt(volatile AC97_DEVICE * pac97device);
void BootAudioSilence(volatile AC97_DEVICE * pac97device);
void BootAudioOutBufferToDescriptor(volatile AC97_DEVICE * pac97device, DWORD * pdwBuffer, WORD wLengthInSamples, bool fFinal);
short BootAudioInterpolatedSine(DWORD dwPhase4GIs2PiRadians);
void BootAudioPlayDescriptors(volatile AC97_DEVICE * pac97device);
void BootAudioAttachAudioElement(volatile AC97_DEVICE * pac97device, AUDIO_ELEMENT * paudioelement);
void BootAudioDetachAudioElement(volatile AC97_DEVICE * pac97device, AUDIO_ELEMENT * paudioelement);
void ConstructAUDIO_ELEMENT_SINE(volatile AUDIO_ELEMENT_SINE *, int nFrequencyFundamental);
void DestructAUDIO_ELEMENT_SINE(volatile AC97_DEVICE * pac97device, AUDIO_ELEMENT_SINE * paes);
void ConstructAUDIO_ELEMENT_NOISE(volatile AUDIO_ELEMENT_NOISE *);
void DestructAUDIO_ELEMENT_NOISE(volatile AC97_DEVICE * pac97device, AUDIO_ELEMENT_NOISE * paen);
WORD BootAudioGetMixerSetting(volatile AC97_DEVICE * pac97device, int nSettingIndex);
void BootAudioSetMixerSetting(volatile AC97_DEVICE * pac97device, int nSettingIndex, WORD wValue);
// video helpers
void BootVideoBlit(
DWORD * pdwTopLeftDestination,
DWORD dwCountBytesPerLineDestination,
DWORD * pdwTopLeftSource,
DWORD dwCountBytesPerLineSource,
DWORD dwCountLines
);
void BootVideoVignette(
DWORD * pdwaTopLeftDestination,
DWORD m_dwCountBytesPerLineDestination,
DWORD m_dwCountLines,
RGBA rgbaColour1,
RGBA rgbaColour2,
DWORD dwStartLine,
DWORD dwEndLine
);
typedef struct {
BYTE * m_pBitmapData;
int m_nWidth;
int m_nHeight;
int m_nBytesPerPixel;
} JPEG;
int BootVideoOverlayString(DWORD * pdwaTopLeftDestination, DWORD m_dwCountBytesPerLineDestination, RGBA rgbaOpaqueness, const char * szString);
void BootVideoChunkedPrint(char * szBuffer, WORD wLength);
int VideoDumpAddressAndData(DWORD dwAds, const BYTE * baData, DWORD dwCountBytesUsable);
unsigned int BootVideoGetStringTotalWidth(const char * szc);
void BootVideoClearScreen(JPEG * pJpeg, int nStartLine, int nEndLine);
void BootVideoJpegBlitBlend(
DWORD * pdwTopLeftDestination,
DWORD dwCountBytesPerLineDestination,
JPEG * pJpeg,
DWORD * pdwTopLeftInJpegBitmap,
RGBA m_rgbaTransparent,
DWORD * pdwTopLeftBackground,
DWORD dwCountBytesPerLineBackground,
DWORD dwCountBytesPerPixelBackground,
int x,
int y
);
bool BootVideoJpegUnpackAsRgb(
BYTE *pbaJpegFileImage,
int nFileLength,
JPEG * pJpeg
);
void BootVideoEnableOutput(BYTE bAvPack);
BYTE * BootVideoGetPointerToEffectiveJpegTopLeft(JPEG * pJpeg);
void * memcpy(void *dest, const void *src, size_t size);
void * memset(void *dest, int data, size_t size);
int _memcmp(const BYTE *pb, const BYTE *pb1, int n);
int _strncmp(const char *sz1, const char *sz2, int nMax);
char * strcpy(char *sz, const char *szc);
char * _strncpy(char *sz, const char *szc, int nLenMax);
void MemoryManagementInitialization(void * pvStartAddress, DWORD dwTotalMemoryAllocLength);
void * malloc(size_t size);
void free(void *);
void Sleep(int nMicroseconds);
extern volatile int nCountI2cinterrupts, nCountUnusedInterrupts, nCountUnusedInterruptsPic2, nCountInterruptsSmc, nCountInterruptsIde;
extern volatile bool fSeenPowerdown;
extern BYTE baBackdrop[60*72*4];
extern JPEG jpegBackdrop;
typedef enum {
ETS_OPEN_OR_OPENING=0,
ETS_CLOSING,
ETS_CLOSED
} TRAY_STATE;
extern volatile TRAY_STATE traystate;
extern void BootInterruptsWriteIdt(void);
int copy_swap_trim(unsigned char *dst, unsigned char *src, int len);
void HMAC_SHA1( unsigned char *result,
unsigned char *key, int key_length,
unsigned char *text1, int text1_length,
unsigned char *text2, int text2_length );
char *HelpGetToken(char *ptr,char token);
void HelpGetParm(char *szBuffer, char *szOrig);
char *strrchr0(char *string, char ch);
#endif // _Boot_H_