1993 lines
65 KiB
C++
1993 lines
65 KiB
C++
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// SArmBoot.cpp - Singularity ARM Boot Loader
|
||
|
//
|
||
|
// Copyright Microsoft Corporation.
|
||
|
//
|
||
|
typedef int INT;
|
||
|
typedef char INT8, *PINT8;
|
||
|
typedef short INT16, *PINT16;
|
||
|
typedef long INT32, *PINT32;
|
||
|
typedef __int64 INT64, *PINT64;
|
||
|
typedef long LARGEST;
|
||
|
typedef char CHAR, *PCHAR;
|
||
|
typedef unsigned int UINT;
|
||
|
typedef unsigned char UINT8, *PUINT8;
|
||
|
typedef unsigned short UINT16, *PUINT16;
|
||
|
typedef unsigned long UINT32, *PUINT32;
|
||
|
typedef unsigned __int64 UINT64, *PUINT64;
|
||
|
typedef unsigned long ULARGEST;
|
||
|
typedef unsigned short WCHAR;
|
||
|
typedef unsigned char UCHAR;
|
||
|
typedef int BOOL;
|
||
|
typedef void *PVOID;
|
||
|
typedef UINT32 ULONG_PTR;
|
||
|
typedef UINT32 UINTPTR;
|
||
|
|
||
|
#define NULL 0
|
||
|
#define arrayof(a) (sizeof(a)/sizeof(a[0]))
|
||
|
#define offsetof(s,m) (size_t)&(((s *)0)->m)
|
||
|
|
||
|
//#define DEBUG 1
|
||
|
|
||
|
/////////////////////////////////////////// Core types used by runtime system.
|
||
|
//
|
||
|
|
||
|
extern "C" ULONG_PTR _security_cookie = 0;
|
||
|
|
||
|
typedef __wchar_t bartok_char;
|
||
|
|
||
|
typedef signed char int8;
|
||
|
typedef signed short int16;
|
||
|
typedef signed int int32;
|
||
|
typedef __int64 int64;
|
||
|
|
||
|
typedef unsigned int uint;
|
||
|
typedef unsigned char uint8;
|
||
|
typedef unsigned short uint16;
|
||
|
typedef unsigned int uint32;
|
||
|
typedef unsigned __int64 uint64;
|
||
|
|
||
|
typedef float float32;
|
||
|
typedef double float64;
|
||
|
|
||
|
typedef int intptr;
|
||
|
typedef unsigned int uintptr;
|
||
|
|
||
|
struct uintPtr
|
||
|
{
|
||
|
uintptr value;
|
||
|
};
|
||
|
|
||
|
struct intPtr
|
||
|
{
|
||
|
intptr value;
|
||
|
};
|
||
|
|
||
|
typedef struct uintPtr *UIntPtr;
|
||
|
typedef struct intPtr *IntPtr;
|
||
|
|
||
|
//
|
||
|
// This saves the MiniDumpBase first time through since it gets
|
||
|
// updated by the kernel.
|
||
|
//
|
||
|
static uintptr DumpAddr32 = 0;
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
|
||
|
/////////////////////////////////////////////////////////////// Static Assert.
|
||
|
//
|
||
|
// Compile-time (not run-time) assertion. Code will not compile if
|
||
|
// expr is false. Note: there is no non-debug version of this; we
|
||
|
// want this for all builds. The compiler optimizes the code away.
|
||
|
//
|
||
|
template <bool x> struct STATIC_ASSERT_FAILURE;
|
||
|
template <> struct STATIC_ASSERT_FAILURE<true> { };
|
||
|
template <int x> struct static_assert_test { };
|
||
|
|
||
|
#define STATIC_CAT_INNER(x,y) x##y
|
||
|
#define STATIC_CAT(x,y) STATIC_CAT_INNER(x,y)
|
||
|
|
||
|
#define STATIC_ASSERT(condition) \
|
||
|
typedef static_assert_test< \
|
||
|
sizeof(STATIC_ASSERT_FAILURE<(bool)(condition)>)> \
|
||
|
STATIC_CAT(__static_assert_typedef_, __COUNTER__)
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
#define OFFSETOF(s,m) ((uintptr)&(((s *)0)->m))
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
#pragma warning(disable: 4103)
|
||
|
#include "halclass.h"
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#define OMAP_CORE_CM_BASE (0x48004A00)
|
||
|
|
||
|
#define CM_CLKSEL_CORE 0x40
|
||
|
#define CM_CLKSEL_CORE_GPT1 0x01
|
||
|
#define CM_CLKSEL_CORE_GPT1_SYS32K 0x00
|
||
|
|
||
|
#define CM_CORE_EN_MMC1 (1 << 24)
|
||
|
#define CM_CORE_EN_MMC2 (1 << 25)
|
||
|
#define CM_CORE_EN_I2C1 (1 << 15)
|
||
|
#define CM_CORE_EN_UART2 (1 << 14)
|
||
|
#define CM_CORE_EN_UART1 (1 << 13)
|
||
|
#define CM_CORE_EN_GPT10 (1 << 11)
|
||
|
|
||
|
#define CM_FCLKEN1_CORE (0)
|
||
|
#define CM_ICLKEN1_CORE (0x10)
|
||
|
#define CM_ICLKEN2_CORE (0x14)
|
||
|
#define CM_IDLEST_CORE (0x20)
|
||
|
|
||
|
#define OMAP_DSS_CM_BASE (0x48004E00)
|
||
|
|
||
|
#define CM_FCLKEN_DSS (0)
|
||
|
#define CM_ICLKEN_DSS (0x10)
|
||
|
|
||
|
#define CM_DSS_EN_DSS1 (1 << 0)
|
||
|
#define CM_DSS_EN_DSS2 (1 << 1)
|
||
|
#define CM_DSS_EN_TV (1 << 2)
|
||
|
|
||
|
#define OMAP_WKUP_CM_BASE (0x48004C00)
|
||
|
|
||
|
#define CM_CLKSEL_WKUP 0x40
|
||
|
#define CM_CLKSEL_WKUP_GPT1 0x01
|
||
|
#define CM_CLKSEL_WKUP_GPT1_SYS32K 0x00
|
||
|
|
||
|
#define CM_WKUP_EN_GPT1 0x01
|
||
|
#define CM_WKUP_EN_GPIO1 (1 << 3)
|
||
|
#define CM_FCLKEN_WKUP (0)
|
||
|
#define CM_ICLKEN_WKUP (0x10)
|
||
|
#define CM_IDLEST_WKUP (0x20)
|
||
|
|
||
|
#define OMAP_PER_CM_BASE (0x48005000)
|
||
|
|
||
|
#define CM_CLKSEL_PER 0x40
|
||
|
#define CM_CLKSEL_PER_GPT2 0x01
|
||
|
#define CM_CLKSEL_PER_GPT2_SYS32K 0x00
|
||
|
|
||
|
#define CM_PER_EN_GPT2 0x08
|
||
|
#define CM_FCLKEN_PER (0)
|
||
|
#define CM_ICLKEN_PER (0x10)
|
||
|
#define CM_IDLEST_PER (0x20)
|
||
|
|
||
|
//
|
||
|
// Registers to configure external pins for I2C, SD/MMC1, and SD/MMC2
|
||
|
//
|
||
|
|
||
|
#define OMAP_SCM_BASE (0x48002000)
|
||
|
|
||
|
#define OMAP_PADCONF_MASK (0xffff)
|
||
|
#define OMAP_PADCONF_SHIFT 0x10
|
||
|
|
||
|
#define OMAP_PADCONF_MUXMODE_MASK (0xfff8)
|
||
|
#define OMAP_PADCONF_MUXMODE_0 (0x0000)
|
||
|
#define OMAP_PADCONF_MUXMODE_1 (0x0001)
|
||
|
#define OMAP_PADCONF_MUXMODE_2 (0x0002)
|
||
|
#define OMAP_PADCONF_MUXMODE_3 (0x0003)
|
||
|
#define OMAP_PADCONF_MUXMODE_4 (0x0004)
|
||
|
#define OMAP_PADCONF_MUXMODE_5 (0x0005)
|
||
|
#define OMAP_PADCONF_MUXMODE_SAFE (0x0007)
|
||
|
#define OMAP_PADCONF_PULLUDENABLE (0x0008)
|
||
|
#define OMAP_PADCONF_PULLTYPESELECT (0x0010)
|
||
|
#define OMAP_PADCONF_INPUTENABLE (0x0100)
|
||
|
#define OMAP_PADCONF_OFFENABLE (0x0200)
|
||
|
#define OMAP_PADCONF_OFFOUTENABLE (0x0400)
|
||
|
#define OMAP_PADCONF_OFFOUTVALUE (0x0800)
|
||
|
#define OMAP_PADCONF_OFFPULLUDENABLE (0x1000)
|
||
|
#define OMAP_PADCONF_OFFPULLTYPESELECT (0x2000)
|
||
|
#define OMAP_PADCONF_WAKEUPENABLE (0x4000)
|
||
|
#define OMAP_PADCONF_WAKEUPEVENT (0x8000)
|
||
|
|
||
|
#define OMAP_PADCONF_HSUSB0_DAT7 (0x1B8)
|
||
|
#define OMAP_PADCONF_I2C1_SDA (0x1BC)
|
||
|
#define OMAP_PADCONF_SYS_NIRQ (0x1E0)
|
||
|
|
||
|
#define OMAP_PADCONF_DSS_PCLK (0x0D4)
|
||
|
#define OMAP_PADCONF_DSS_DAT18 (0x0FC)
|
||
|
#define OMAP_PADCONF_ETK_D10 (0xA40)
|
||
|
#define OMAP_PADCONF_ETK_D14 (0xA48)
|
||
|
|
||
|
|
||
|
#define OMAP_GPIO1_BASE (0x48310000)
|
||
|
#define OMAP_GPIO_OE (0x34)
|
||
|
#define OMAP_GPIO_SETDATAOUT (0x94)
|
||
|
#define OMAP_GPIO_CLEARDATAOUT (0x90)
|
||
|
#define OMAP_GPIO_PIN_24 (1 << 24)
|
||
|
#define OMAP_GPIO_PIN_28 (1 << 28)
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
inline uint32 ReadReg32(volatile void * addr)
|
||
|
{
|
||
|
return ((volatile uint32 *)addr)[0];
|
||
|
}
|
||
|
|
||
|
inline void WriteReg32(volatile void * addr, uint32 value)
|
||
|
{
|
||
|
((volatile uint32 *)addr)[0] = value;
|
||
|
}
|
||
|
|
||
|
inline void WriteReg16(volatile void * addr, uint16 value)
|
||
|
{
|
||
|
((volatile uint16 *)addr)[0] = value;
|
||
|
}
|
||
|
|
||
|
inline uint16 ReadReg16(volatile void * addr)
|
||
|
{
|
||
|
return ((volatile uint16 *)addr)[0];
|
||
|
}
|
||
|
|
||
|
inline void WriteReg8(volatile void * addr, uint8 value)
|
||
|
{
|
||
|
((volatile uint8 *)addr)[0] = value;
|
||
|
}
|
||
|
|
||
|
inline uint8 ReadReg8(volatile void * addr)
|
||
|
{
|
||
|
return ((volatile uint8 *)addr)[0];
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
|
||
|
typedef unsigned int uint;
|
||
|
typedef unsigned int UINT;
|
||
|
typedef signed long LARGEST;
|
||
|
typedef unsigned long ULARGEST;
|
||
|
|
||
|
#include "strformat.cpp"
|
||
|
#include "printf.cpp"
|
||
|
#include "debuguart.cpp"
|
||
|
#include "debug.cpp"
|
||
|
#include "expandpe.cpp"
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
void Halt(void);
|
||
|
|
||
|
#define ASSERT(b) if (!(b)) { AssertFailed(#b);} else
|
||
|
void AssertFailed(const char *string)
|
||
|
{
|
||
|
printf("Assert Failed [%s]\n", string);
|
||
|
Halt();
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////// Memory.
|
||
|
//
|
||
|
// OMAP 3430 Memory Map:
|
||
|
//
|
||
|
#define ON_OMAP3430_RESERVE_ADDR 0x80000000
|
||
|
#define ON_OMAP3430_RESERVE_SIZE 0x00050000
|
||
|
|
||
|
#define ON_OMAP3430_LOADER_ADDR 0x80000000 // SArmBoot code.
|
||
|
#define ON_OMAP3430_LOADER_SIZE 0x0000fff0 // was 0x10000.
|
||
|
|
||
|
#define ON_OMAP3430_CPU_ARGS_ADDR 0x8000fff0 //
|
||
|
#define ON_OMAP3430_CPU_ARGS_SIZE 0x80000010 //
|
||
|
|
||
|
#define ON_OMAP3430_VIDEO_ADDR 0x80010000 // LCD Video.
|
||
|
#define ON_OMAP3430_VIDEO_SIZE 0x00025800
|
||
|
|
||
|
#define ON_OMAP3430_ALLOC_ADDR 0x80035800 // Boot "alloc()" heap.
|
||
|
#define ON_OMAP3430_ALLOC_SIZE 0x0000A800
|
||
|
|
||
|
#define ON_OMAP3430_LOGBUF_ADDR 0x80040000 // Logging record buffer.
|
||
|
#define ON_OMAP3430_LOGBUF_SIZE 0x00008000
|
||
|
|
||
|
#define ON_OMAP3430_LOGTXT_ADDR 0x80048000 // Logging text buffer.
|
||
|
#define ON_OMAP3430_LOGTXT_SIZE 0x00008000
|
||
|
|
||
|
#define ON_OMAP3430_STACK_ADDR 0x80050000 // Kernel stack.
|
||
|
#define ON_OMAP3430_STACK_SIZE 0x00010000
|
||
|
|
||
|
#define ON_OMAP3430_KERNEL_ADDR 0x80100000 // Base address of kernel.
|
||
|
//#define ON_OMAP3430_KERNEL_SIZE 0xFFFFFFFF // Determined at runtime.
|
||
|
|
||
|
#define ON_OMAP3430_MEMORY_ADDR 0x80000000 // Base general memory.
|
||
|
#define ON_OMAP3430_MEMORY_SIZE 0x08000000
|
||
|
|
||
|
#define ON_OMAP3430_IFLASH_ADDR 0x84000000 // Memory to scan for flash image.
|
||
|
#define ON_OMAP3430_IFLASH_SIZE 0x04000000
|
||
|
|
||
|
//
|
||
|
// These should be in a general memory layout file
|
||
|
// rather than buried deeply in code
|
||
|
//
|
||
|
static uintptr heapTop = ON_OMAP3430_ALLOC_ADDR;
|
||
|
static uintptr heapMax = ON_OMAP3430_ALLOC_ADDR + ON_OMAP3430_ALLOC_SIZE;
|
||
|
|
||
|
extern "C" void * memset(void *dest, uint8 c, uint count);
|
||
|
extern "C" void * memmove(void *dest, const void *src, uint count);
|
||
|
|
||
|
void * alloc(uint cbSize, uint cbPad)
|
||
|
{
|
||
|
cbPad = (cbPad != 0) ? ((cbPad + 0xf) & ~0xf) : 0x10; // 16-byte pad minimum.
|
||
|
uintptr newTop = (heapTop + (cbPad - 1)) & ~(cbPad - 1);
|
||
|
void *pvData = (void *)newTop;
|
||
|
|
||
|
cbSize = (cbSize != 0) ? ((cbSize + 0xf) & ~0xf) : 0x10; //16-byte pad minimum.
|
||
|
newTop += cbSize;
|
||
|
if (newTop > heapMax) {
|
||
|
// Failure, no one checks this call
|
||
|
printf("alloc failure req %d\n", cbSize);
|
||
|
Halt();
|
||
|
return NULL;
|
||
|
}
|
||
|
heapTop = newTop;
|
||
|
memset(pvData, 0, cbSize);
|
||
|
return pvData;
|
||
|
}
|
||
|
|
||
|
void * alloc(uint cbSize)
|
||
|
{
|
||
|
return alloc(cbSize, 0x10);
|
||
|
}
|
||
|
|
||
|
void * allocpages(uint cPages)
|
||
|
{
|
||
|
return alloc(Class_Microsoft_Singularity_Hal_Platform_PAGE_SIZE * cPages,
|
||
|
Class_Microsoft_Singularity_Hal_Platform_PAGE_SIZE);
|
||
|
}
|
||
|
|
||
|
void * operator new(uint cbSize)
|
||
|
{
|
||
|
return alloc(cbSize, 0);
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////// Screen Routines.
|
||
|
//
|
||
|
|
||
|
#define DISPC_REVISION 0x00
|
||
|
#define DISPC_SYSCONFIG 0x10
|
||
|
#define DISPC_SYSSTATUS 0x14
|
||
|
#define DISPC_IRQSTATUS 0x18
|
||
|
#define DISPC_IRQENABLE 0x1C
|
||
|
#define DISPC_CONTROL 0x40
|
||
|
#define DISPC_CONFIG 0x44
|
||
|
#define DISPC_CAPABLE 0x48
|
||
|
#define DISPC_DEFAULT_COLOR0 0x4C
|
||
|
#define DISPC_DEFAULT_COLOR1 0x50
|
||
|
#define DISPC_TRANS_COLOR0 0x54
|
||
|
#define DISPC_TRANS_COLOR1 0x58
|
||
|
#define DISPC_LINE_STATUS 0x5C
|
||
|
#define DISPC_LINE_NUMBER 0x60
|
||
|
#define DISPC_TIMING_H 0x64
|
||
|
#define DISPC_TIMING_V 0x68
|
||
|
#define DISPC_POL_FREQ 0x6C
|
||
|
#define DISPC_DIVISOR 0x70
|
||
|
#define DISPC_SIZE_DIG 0x78
|
||
|
#define DISPC_SIZE_LCD 0x7C
|
||
|
#define DISPC_GFX_BA0 0x80
|
||
|
#define DISPC_GFX_BA1 0x84
|
||
|
#define DISPC_GFX_POSITION 0x88
|
||
|
#define DISPC_GFX_SIZE 0x8C
|
||
|
#define DISPC_GFX_ATTRIBUTES 0xA0
|
||
|
#define DISPC_GFX_FIFO_THRESHOLD 0xA4
|
||
|
#define DISPC_GFX_FIFO_SIZE_STATUS 0xA8
|
||
|
#define DISPC_GFX_ROW_INC 0xAC
|
||
|
#define DISPC_GFX_PIXEL_INC 0xB0
|
||
|
#define DISPC_GFX_WINDOW_SKIP 0xB4
|
||
|
#define DISPC_GFX_TABLE_BA 0xB8
|
||
|
#define DISPC_VID1_BA0 0xBC
|
||
|
#define DISPC_VID1_BA1 0xC0
|
||
|
#define DISPC_VID1_POSITION 0xC4
|
||
|
#define DISPC_VID1_SIZE 0xC8
|
||
|
#define DISPC_VID1_ATTRIBUTES 0xCC
|
||
|
#define DISPC_VID1_FIFO_THRESHOLD 0xD0
|
||
|
#define DISPC_VID1_FIFO_SIZE_STATUS 0xD4
|
||
|
#define DISPC_VID1_ROW_INC 0xD8
|
||
|
#define DISPC_VID1_PIXEL_INC 0xDC
|
||
|
#define DISPC_VID1_FIR 0xE0
|
||
|
#define DISPC_VID1_PICTURE_SIZE 0xE4
|
||
|
#define DISPC_VID1_ACCU0 0xE8
|
||
|
#define DISPC_VID1_ACCU1 0xEC
|
||
|
#define DISPC_VID1_CONV_COEF0 0x130
|
||
|
#define DISPC_VID1_CONV_COEF1 0x134
|
||
|
#define DISPC_VID1_CONV_COEF2 0x138
|
||
|
#define DISPC_VID1_CONV_COEF3 0x13C
|
||
|
#define DISPC_VID1_CONV_COEF4 0x140
|
||
|
#define DISPC_VID2_BA0 0x14C
|
||
|
#define DISPC_VID2_BA1 0x150
|
||
|
#define DISPC_VID2_POSITION 0x154
|
||
|
#define DISPC_VID2_SIZE 0x158
|
||
|
#define DISPC_VID2_ATTRIBUTES 0x15C
|
||
|
#define DISPC_VID2_FIFO_THRESHOLD 0x160
|
||
|
#define DISPC_VID2_FIFO_SIZE_STATUS 0x164
|
||
|
#define DISPC_VID2_ROW_INC 0x168
|
||
|
#define DISPC_VID2_PIXEL_INC 0x16C
|
||
|
#define DISPC_VID2_FIR 0x170
|
||
|
#define DISPC_VID2_PICTURE_SIZE 0x174
|
||
|
#define DISPC_VID2_ACCU0 0x178
|
||
|
#define DISPC_VID2_ACCU1 0x17C
|
||
|
#define DISPC_VID2_CONV_COEF0 0x1C0
|
||
|
#define DISPC_VID2_CONV_COEF1 0x1C4
|
||
|
#define DISPC_VID2_CONV_COEF2 0x1C8
|
||
|
#define DISPC_VID2_CONV_COEF3 0x1CC
|
||
|
#define DISPC_VID2_CONV_COEF4 0x1D0
|
||
|
#define DISPC_DATA_CYCLE1 0x1D4
|
||
|
#define DISPC_DATA_CYCLE2 0x1D8
|
||
|
#define DISPC_DATA_CYCLE3 0x1DC
|
||
|
#define DISPC_CPR_COEF_R 0x220
|
||
|
#define DISPC_CPR_COEF_G 0x224
|
||
|
#define DISPC_CPR_COEF_B 0x228
|
||
|
#define DISPC_GFX_PRELOAD 0x22C
|
||
|
#define DISPC_VID1_PRELOAD 0x230
|
||
|
#define DISPC_VID2_PRELOAD 0x234
|
||
|
|
||
|
#define DISPC_CONFIG_LOADMODE_FRDATLEF (2 << 1) // XXX maybe
|
||
|
|
||
|
#define DISPC_CONTROL_DIGITALENABLE (1 << 1)
|
||
|
#define DISPC_CONTROL_GOLCD (1 << 5)
|
||
|
#define DISPC_CONTROL_GPOUT0 (1 << 15)
|
||
|
#define DISPC_CONTROL_GPOUT1 (1 << 16)
|
||
|
#define DISPC_CONTROL_LCDENABLE (1 << 0)
|
||
|
#define DISPC_CONTROL_RFBIMODE (1 << 11)
|
||
|
#define DISPC_CONTROL_STNTFT (1 << 3)
|
||
|
#define DISPC_CONTROL_TFTDATALINES_OALSB16B (1 << 8)
|
||
|
|
||
|
#define DISPC_DIVISOR_LCD_SHIFT 16
|
||
|
#define DISPC_DIVISOR_PCD_SHIFT 0
|
||
|
|
||
|
#define DISPC_GFX_ATTRIBUTES_ENABLE 1
|
||
|
#define DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGB16 (6 << 1)
|
||
|
|
||
|
#define DISPC_GFX_FIFO_THRESHOLD_HIGH_SHIFT 16
|
||
|
#define DISPC_GFX_FIFO_THRESHOLD_LOW_SHIFT 0
|
||
|
|
||
|
#define DISPC_SYSCONFIG_MIDLEMODE_NSTANDBY (1 << 12)
|
||
|
#define DISPC_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3)
|
||
|
#define DISPC_SYSCONFIG_SOFTRESET (1 << 1)
|
||
|
|
||
|
#define DISPC_SYSSTATUS_RESETDONE (1)
|
||
|
|
||
|
#define DISPC_TIMING_H_HBP_SHIFT 20
|
||
|
#define DISPC_TIMING_H_HFP_SHIFT 8
|
||
|
#define DISPC_TIMING_H_HSW_SHIFT 0
|
||
|
|
||
|
#define DISPC_TIMING_V_VBP_SHIFT 20
|
||
|
#define DISPC_TIMING_V_VFP_SHIFT 8
|
||
|
#define DISPC_TIMING_V_VSW_SHIFT 0
|
||
|
|
||
|
#define DISPC_SIZE_LCD_QVGA_PORTRAIT (((320 - 1) << 16) | (240 - 1))
|
||
|
#define DISPC_SIZE_QVGA_PORTRAIT DISPC_SIZE_LCD_QVGA_PORTRAIT
|
||
|
|
||
|
#define GPIO_LCD_BACKLIGHT 24
|
||
|
#define GPIO_LCD_POWER 28
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// I2C interface (used here to control power to SD/MMC cards via the 4030)
|
||
|
//
|
||
|
|
||
|
#define OMAP_I2C1_BASE (0x48070000)
|
||
|
|
||
|
#define I2C_STAT (0x8)
|
||
|
#define I2C_STAT_XDR (1 << 14)
|
||
|
#define I2C_STAT_RDR (1 << 13)
|
||
|
#define I2C_STAT_BUSY (1 << 12)
|
||
|
#define I2C_STAT_XRDY (1 << 4)
|
||
|
#define I2C_STAT_RRDY (1 << 3)
|
||
|
#define I2C_STAT_ARDY (1 << 2)
|
||
|
#define I2C_STAT_NACK (1 << 1)
|
||
|
#define I2C_STAT_AL (1 << 0)
|
||
|
|
||
|
#define I2C_BUF (0x14)
|
||
|
#define I2C_CNT (0x18)
|
||
|
#define I2C_DATA (0x1C)
|
||
|
|
||
|
#define I2C_CON (0x24)
|
||
|
#define I2C_CON_EN (1 << 15)
|
||
|
#define I2C_CON_STB (1 << 11) // XXX REVIEW
|
||
|
#define I2C_CON_MASTER (1 << 10)
|
||
|
#define I2C_CON_DIR_MASK (1 << 9)
|
||
|
#define I2C_CON_XMIT I2C_CON_DIR_MASK
|
||
|
#define I2C_CON_RECV (0)
|
||
|
#define I2C_CON_STP (1 << 1) // XXX REVIEW
|
||
|
#define I2C_CON_STT (1 << 0) // XXX REVIEW
|
||
|
|
||
|
#define I2C_PSC (0x30)
|
||
|
#define I2C_SCLL (0x34)
|
||
|
#define I2C_SCLH (0x38)
|
||
|
#define I2C_OA0 (0x28)
|
||
|
#define I2C_SA (0x2C)
|
||
|
#define I2C_BUFSTAT (0x40)
|
||
|
|
||
|
#define OMAP_PM_RECEIVER (0x4B)
|
||
|
|
||
|
void HalpClocksInitialize()
|
||
|
{
|
||
|
uint32 Value;
|
||
|
|
||
|
// Clock manager domain control registers
|
||
|
uint8 * HalpWKUP_CM = (uint8 *)OMAP_WKUP_CM_BASE;
|
||
|
uint8 * HalpCORE_CM = (uint8 *)OMAP_CORE_CM_BASE;
|
||
|
uint8 * HalpDSS_CM = (uint8 *)OMAP_DSS_CM_BASE;
|
||
|
|
||
|
// Enable interface and function clocks for WKUP (power management)
|
||
|
Value = ReadReg32(HalpWKUP_CM + CM_FCLKEN_WKUP);
|
||
|
Value |= CM_WKUP_EN_GPIO1;
|
||
|
WriteReg32(HalpWKUP_CM + CM_FCLKEN_WKUP, Value);
|
||
|
|
||
|
Value = ReadReg32(HalpWKUP_CM + CM_ICLKEN_WKUP);
|
||
|
Value |= CM_WKUP_EN_GPIO1;
|
||
|
WriteReg32(HalpWKUP_CM + CM_ICLKEN_WKUP, Value);
|
||
|
|
||
|
// Enable interface and function clocks for CORE (peripherals)
|
||
|
Value = ReadReg32(HalpCORE_CM + CM_FCLKEN1_CORE);
|
||
|
Value |= CM_CORE_EN_I2C1;
|
||
|
WriteReg32(HalpCORE_CM + CM_FCLKEN1_CORE, Value);
|
||
|
|
||
|
Value = ReadReg32(HalpCORE_CM + CM_ICLKEN1_CORE);
|
||
|
Value |= CM_CORE_EN_I2C1;
|
||
|
WriteReg32(HalpCORE_CM + CM_ICLKEN1_CORE,Value);
|
||
|
|
||
|
// Enable interface and function clocks for DSS (display)
|
||
|
Value = ReadReg32(HalpDSS_CM + CM_FCLKEN_DSS);
|
||
|
Value |= CM_DSS_EN_DSS1 | CM_DSS_EN_DSS2 | CM_DSS_EN_TV;
|
||
|
WriteReg32(HalpDSS_CM + CM_FCLKEN_DSS, Value);
|
||
|
|
||
|
Value = ReadReg32(HalpDSS_CM + CM_ICLKEN_DSS);
|
||
|
Value |= CM_DSS_EN_DSS1;
|
||
|
WriteReg32(HalpDSS_CM + CM_ICLKEN_DSS, Value);
|
||
|
}
|
||
|
|
||
|
void HalpGpioInitialize()
|
||
|
{
|
||
|
uint32 Value;
|
||
|
uint8 * HalpSCM = (uint8 *)OMAP_SCM_BASE;
|
||
|
|
||
|
//
|
||
|
// Configure GPIO pads
|
||
|
//
|
||
|
// NB: mode 7 is 'safe' mode - GPIO as input with
|
||
|
// no function selected from multiplexer
|
||
|
//
|
||
|
|
||
|
// Enable i2c1_scl
|
||
|
|
||
|
// OMAP_PADCONF_HSUSB0_DAT7[15:0] is hsusb0_data7 (mode 0),
|
||
|
// OMAP_PADCONF_HSUSB0_DAT7[31:16] is i2c1_scl (mode 0)
|
||
|
Value = ReadReg32(HalpSCM + OMAP_PADCONF_HSUSB0_DAT7);
|
||
|
// i2c1_scl mux mode 7 (reset) -> mode 0
|
||
|
Value &= ((OMAP_PADCONF_MUXMODE_MASK << OMAP_PADCONF_SHIFT) | OMAP_PADCONF_MASK);
|
||
|
WriteReg32(HalpSCM + OMAP_PADCONF_HSUSB0_DAT7,Value);
|
||
|
|
||
|
// Enable i2c1_sda
|
||
|
|
||
|
// OMAP_PADCONF_I2C1_SDA[15:0] is i2c1_sda (mode 0),
|
||
|
// OMAP_PADCONF_I2C1_SDA[31:16] is i2c2_scl (mode 0)
|
||
|
Value = ReadReg32(HalpSCM + OMAP_PADCONF_I2C1_SDA);
|
||
|
// i2c1_sda mux mode 7 (reset) -> mode 0 */
|
||
|
Value &= ((OMAP_PADCONF_MASK << OMAP_PADCONF_SHIFT) | OMAP_PADCONF_MUXMODE_MASK);
|
||
|
WriteReg32(HalpSCM + OMAP_PADCONF_I2C1_SDA,Value);
|
||
|
|
||
|
// Enable sys_nirq
|
||
|
// - connected to int1_n on TWL4030
|
||
|
|
||
|
// OMAP_PADCONF_SYS_NIRQ[15:0] is sys_nirq (mode 0),
|
||
|
// OMAP_PADCONF_SYS_NIRQ[31:16] is sys_clkout2 (mode 0)
|
||
|
Value = ReadReg32(HalpSCM + OMAP_PADCONF_SYS_NIRQ);
|
||
|
// sys_nirq mux mode 7 (reset) -> mode 0
|
||
|
Value &= ((OMAP_PADCONF_MASK << OMAP_PADCONF_SHIFT) | OMAP_PADCONF_MUXMODE_MASK);
|
||
|
WriteReg32(HalpSCM + OMAP_PADCONF_I2C1_SDA,Value);
|
||
|
|
||
|
// Enable dss_* for LCD; configure these as:
|
||
|
// PULLTYPESELECT = 0, PULLUDENABLE = 0, output
|
||
|
uint8 * LcdGpioConfigRegister = (uint8 *)OMAP_SCM_BASE + OMAP_PADCONF_DSS_PCLK;
|
||
|
uint8* const LcdGpioConfigRegisterEnd = (uint8 *)OMAP_SCM_BASE + OMAP_PADCONF_DSS_DAT18;
|
||
|
|
||
|
// OMAP_PADCONF_DSS_PCLK[15:0] is dss_pclk (mode 0),
|
||
|
// OMAP_PADCONF_DSS_PCLK[31:16] is dss_hsync (mode 0),
|
||
|
// OMAP_PADCONF_DSS_VSYNC[15:0] is dss_vsync (mode 0),
|
||
|
// OMAP_PADCONF_DSS_VSYNC[31:16] is dss_acbias (mode 0),
|
||
|
// OMAP_PADCONF_DSS_DATn[15:0] is dss_data(n) (mode 0),
|
||
|
// OMAP_PADCONF_DSS_DATn[31:16] is dss_data(n+1) (mode 0)
|
||
|
for (; LcdGpioConfigRegister <= LcdGpioConfigRegisterEnd; LcdGpioConfigRegister += 4) {
|
||
|
WriteReg32(LcdGpioConfigRegister, (OMAP_PADCONF_MUXMODE_0 << OMAP_PADCONF_SHIFT) | OMAP_PADCONF_MUXMODE_0);
|
||
|
}
|
||
|
|
||
|
// [arog - Do we need to configure etk_d15/11 as well as gpio_24/28?]
|
||
|
|
||
|
// OMAP_PADCONF_ETK_D14[15:0] is gpio_28 (mode 4),
|
||
|
// OMAP_PADCONF_ETK_D14[31:16] is etk_d15 (mode 0) */
|
||
|
WriteReg32(HalpSCM + OMAP_PADCONF_ETK_D14, (OMAP_PADCONF_MUXMODE_0 << OMAP_PADCONF_SHIFT) | OMAP_PADCONF_MUXMODE_4);
|
||
|
|
||
|
// OMAP_PADCONF_ETK_D10[15:0] is gpio_24 (mode 4),
|
||
|
// OMAP_PADCONF_ETK_D10[31:16] is etk_d11 (mode 0)
|
||
|
WriteReg32(HalpSCM + OMAP_PADCONF_ETK_D10, (OMAP_PADCONF_MUXMODE_0 << OMAP_PADCONF_SHIFT) | OMAP_PADCONF_MUXMODE_4);
|
||
|
}
|
||
|
|
||
|
void HalpI2CMasterInitialize()
|
||
|
{
|
||
|
uint16 ShortValue;
|
||
|
uint8 * HalpI2C1 = (uint8 *)OMAP_I2C1_BASE;
|
||
|
|
||
|
// Setup I2C1 controller
|
||
|
// _ARM_WORKAROUND_ i2c code is erroring out
|
||
|
if ((ReadReg16(HalpI2C1 + I2C_CON) & I2C_CON_EN) != 0) {
|
||
|
ShortValue = ReadReg16(HalpI2C1 + I2C_CON);
|
||
|
ShortValue &= I2C_CON_EN;
|
||
|
WriteReg16(HalpI2C1 + I2C_CON, ShortValue);
|
||
|
ReadReg16(HalpI2C1 + I2C_CON);
|
||
|
}
|
||
|
|
||
|
ASSERT((ReadReg16(HalpI2C1 + I2C_CON) & I2C_CON_EN) == 0);
|
||
|
// We should handle the case where it was already enabled.
|
||
|
|
||
|
// Configure internal sampling frequency for 12Mhz.
|
||
|
WriteReg8(HalpI2C1 + I2C_PSC, 7);
|
||
|
|
||
|
// Configure for 100 kb/s
|
||
|
WriteReg8(HalpI2C1 + I2C_SCLL, 54);
|
||
|
WriteReg8(HalpI2C1 + I2C_SCLH, 56);
|
||
|
|
||
|
// Set own address address register
|
||
|
WriteReg16(HalpI2C1 + I2C_OA0, 0x21);
|
||
|
|
||
|
// Take I2C controller out of reset
|
||
|
ShortValue = ReadReg16(HalpI2C1 + I2C_CON);
|
||
|
ShortValue |= I2C_CON_EN;
|
||
|
WriteReg16(HalpI2C1 + I2C_CON,ShortValue);
|
||
|
}
|
||
|
|
||
|
void HalpI2CMasterSetup(
|
||
|
bool Xmit,
|
||
|
uint8 SlaveAddress,
|
||
|
uint16 Length,
|
||
|
bool GenerateStart,
|
||
|
bool GenerateStop
|
||
|
)
|
||
|
{
|
||
|
uint16 ShortValue;
|
||
|
uint8 * HalpI2C1 = (uint8 *)OMAP_I2C1_BASE;
|
||
|
|
||
|
WriteReg16(HalpI2C1 + I2C_CON,I2C_CON_EN);
|
||
|
|
||
|
// Set slave address
|
||
|
WriteReg16(HalpI2C1 + I2C_SA,SlaveAddress);
|
||
|
|
||
|
// Set transfer length
|
||
|
WriteReg16(HalpI2C1 + I2C_CNT,Length);
|
||
|
|
||
|
// Clear status
|
||
|
WriteReg16(HalpI2C1 + I2C_STAT,
|
||
|
I2C_STAT_ARDY | I2C_STAT_NACK | I2C_STAT_AL);
|
||
|
|
||
|
// wait for free bus?
|
||
|
// while ReadReg16(HalpI2C1 + I2C_STAT)) & I2C_STAT_BUSY);
|
||
|
|
||
|
ShortValue = I2C_CON_EN | I2C_CON_MASTER;
|
||
|
ShortValue |= Xmit ? I2C_CON_XMIT : I2C_CON_RECV;
|
||
|
ShortValue |= GenerateStart ? I2C_CON_STT : 0;
|
||
|
ShortValue |= GenerateStop ? I2C_CON_STP : 0;
|
||
|
|
||
|
WriteReg16(HalpI2C1 + I2C_CON,ShortValue);
|
||
|
}
|
||
|
|
||
|
bool HalpI2CMasterTransfer(bool Xmit, uint16 Length, uint8 * Data)
|
||
|
{
|
||
|
uint16 Stat;
|
||
|
uint16 Room;
|
||
|
uint8 * HalpI2C1 = (uint8 *)OMAP_I2C1_BASE;
|
||
|
|
||
|
for (;;) {
|
||
|
|
||
|
Stat = ReadReg16(HalpI2C1 + I2C_STAT);
|
||
|
|
||
|
if (Stat & (I2C_STAT_NACK|I2C_STAT_AL)) {
|
||
|
ASSERT(Stat == 0);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (Stat & (I2C_STAT_ARDY)) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (Xmit) {
|
||
|
if (Stat & I2C_STAT_XDR) {
|
||
|
Room = ReadReg16(HalpI2C1 + I2C_BUFSTAT) & 0x3F;
|
||
|
while (Room--) {
|
||
|
WriteReg8(HalpI2C1 + I2C_DATA, *Data);
|
||
|
Data++;
|
||
|
Length--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Stat & I2C_STAT_XRDY) {
|
||
|
Room = ReadReg16(HalpI2C1 + I2C_BUF) & 0x3F;
|
||
|
Room += 1;
|
||
|
|
||
|
while (Room--) {
|
||
|
WriteReg8(HalpI2C1 + I2C_DATA, *Data);
|
||
|
Data++;
|
||
|
Length--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if (Stat & I2C_STAT_RDR) {
|
||
|
Room = (ReadReg16(HalpI2C1 + I2C_BUFSTAT) >> 8) & 0x3F;
|
||
|
|
||
|
while (Room--) {
|
||
|
*Data = ReadReg8(HalpI2C1 + I2C_DATA);
|
||
|
Data++;
|
||
|
Length--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Stat & I2C_STAT_RRDY) {
|
||
|
Room = (ReadReg16(HalpI2C1 + I2C_BUF) >> 8) & 0x3F;
|
||
|
Room += 1;
|
||
|
|
||
|
while (Room--) {
|
||
|
*Data = ReadReg8(HalpI2C1 + I2C_DATA);
|
||
|
Data++;
|
||
|
Length--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WriteReg16(HalpI2C1 + I2C_STAT,Stat);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
HalpI2CMasterCommon(
|
||
|
bool Xmit,
|
||
|
uint8 SlaveAddress,
|
||
|
uint16 Length,
|
||
|
uint8 * Data,
|
||
|
bool GenerateStart,
|
||
|
bool GenerateStop
|
||
|
)
|
||
|
{
|
||
|
int retry = 10;
|
||
|
|
||
|
while (retry--) {
|
||
|
|
||
|
HalpI2CMasterSetup(Xmit, OMAP_PM_RECEIVER, Length, GenerateStart, GenerateStop);
|
||
|
|
||
|
if (HalpI2CMasterTransfer(Xmit, Length, Data)) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
HalpI2CMasterReceive(
|
||
|
uint8 SlaveAddress,
|
||
|
uint16 Length,
|
||
|
uint8 * Data,
|
||
|
bool GenerateStart,
|
||
|
bool GenerateStop
|
||
|
)
|
||
|
{
|
||
|
return HalpI2CMasterCommon(false, OMAP_PM_RECEIVER, Length, Data,
|
||
|
GenerateStart, GenerateStop);
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
HalpI2CMasterSend(
|
||
|
uint8 SlaveAddress,
|
||
|
uint16 Length,
|
||
|
uint8 * Data,
|
||
|
bool GenerateStart,
|
||
|
bool GenerateStop
|
||
|
)
|
||
|
{
|
||
|
return HalpI2CMasterCommon(true, OMAP_PM_RECEIVER, Length, Data,
|
||
|
GenerateStart, GenerateStop);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
void InitializeDisplayPowerDomains()
|
||
|
{
|
||
|
uint32 Value;
|
||
|
bool Good;
|
||
|
uint32 Count;
|
||
|
uint8 Data[2];
|
||
|
|
||
|
//
|
||
|
// Bootstrap VAUX3
|
||
|
//
|
||
|
|
||
|
Data[0] = 0x7A;
|
||
|
Data[1] = 1 << 5;
|
||
|
Good = HalpI2CMasterSend(OMAP_PM_RECEIVER, 2, Data, true, true);
|
||
|
ASSERT(Good);
|
||
|
|
||
|
Data[0] = 0x7B;
|
||
|
Data[1] = 4;
|
||
|
Good = HalpI2CMasterSend(OMAP_PM_RECEIVER, 2, Data, true, true);
|
||
|
ASSERT(Good);
|
||
|
|
||
|
Data[0] = 0x7d;
|
||
|
Data[1] = 0x3;
|
||
|
Good = HalpI2CMasterSend(OMAP_PM_RECEIVER, 2, Data, true, true);
|
||
|
ASSERT(Good);
|
||
|
|
||
|
Data[0] = 0x7d;
|
||
|
Good = HalpI2CMasterSend(OMAP_PM_RECEIVER, 1, Data, true, false);
|
||
|
ASSERT(Good);
|
||
|
Good = HalpI2CMasterReceive(OMAP_PM_RECEIVER, 1, Data, true, true);
|
||
|
ASSERT(Good);
|
||
|
ASSERT(Data[0] == 3);
|
||
|
|
||
|
Count = 0xFFFF;
|
||
|
while (Count--);
|
||
|
|
||
|
uint8 * HalpGPIO1 = (uint8 *)OMAP_GPIO1_BASE;
|
||
|
|
||
|
Value = ReadReg32(HalpGPIO1 + OMAP_GPIO_OE);
|
||
|
Value &= ~(OMAP_GPIO_PIN_24 | OMAP_GPIO_PIN_28);
|
||
|
WriteReg32(HalpGPIO1 + OMAP_GPIO_OE, Value);
|
||
|
|
||
|
WriteReg32(HalpGPIO1 + OMAP_GPIO_SETDATAOUT, OMAP_GPIO_PIN_28);
|
||
|
|
||
|
Count = 0xFFFF;
|
||
|
while (Count--);
|
||
|
|
||
|
WriteReg32(HalpGPIO1 + OMAP_GPIO_SETDATAOUT, OMAP_GPIO_PIN_24);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
uint8 Font8[] =
|
||
|
{
|
||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
|
0x7e,0x81,0xa5,0x81,0xbd,0x99,0x81,0x7e,
|
||
|
0x7e,0xff,0xdb,0xff,0xc3,0xe7,0xff,0x7e,
|
||
|
0x6c,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,
|
||
|
0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,
|
||
|
0x38,0x7c,0x38,0xfe,0xfe,0x7c,0x38,0x7c,
|
||
|
0x10,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x7c,
|
||
|
0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,
|
||
|
0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,
|
||
|
0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,
|
||
|
0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,
|
||
|
0x0f,0x07,0x0f,0x7d,0xcc,0xcc,0xcc,0x78,
|
||
|
0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,
|
||
|
0x3f,0x33,0x3f,0x30,0x30,0x70,0xf0,0xe0,
|
||
|
0x7f,0x63,0x7f,0x63,0x63,0x67,0xe6,0xc0,
|
||
|
0x99,0x5a,0x3c,0xe7,0xe7,0x3c,0x5a,0x99,
|
||
|
0x80,0xe0,0xf8,0xfe,0xf8,0xe0,0x80,0x00,
|
||
|
0x02,0x0e,0x3e,0xfe,0x3e,0x0e,0x02,0x00,
|
||
|
0x18,0x3c,0x7e,0x18,0x18,0x7e,0x3c,0x18,
|
||
|
0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x00,
|
||
|
0x7f,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x00,
|
||
|
0x3e,0x63,0x38,0x6c,0x6c,0x38,0xcc,0x78,
|
||
|
0x00,0x00,0x00,0x00,0x7e,0x7e,0x7e,0x00,
|
||
|
0x18,0x3c,0x7e,0x18,0x7e,0x3c,0x18,0xff,
|
||
|
0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x00,
|
||
|
0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,
|
||
|
0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,
|
||
|
0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,
|
||
|
0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,
|
||
|
0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,
|
||
|
0x00,0x18,0x3c,0x7e,0xff,0xff,0x00,0x00,
|
||
|
0x00,0xff,0xff,0x7e,0x3c,0x18,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
|
0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00,
|
||
|
0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,
|
||
|
0x6c,0x6c,0xfe,0x6c,0xfe,0x6c,0x6c,0x00,
|
||
|
0x30,0x7c,0xc0,0x78,0x0c,0xf8,0x30,0x00,
|
||
|
0x00,0xc6,0xcc,0x18,0x30,0x66,0xc6,0x00,
|
||
|
0x38,0x6c,0x38,0x76,0xdc,0xcc,0x76,0x00,
|
||
|
0x60,0x60,0xc0,0x00,0x00,0x00,0x00,0x00,
|
||
|
0x18,0x30,0x60,0x60,0x60,0x30,0x18,0x00,
|
||
|
0x60,0x30,0x18,0x18,0x18,0x30,0x60,0x00,
|
||
|
0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,
|
||
|
0x00,0x30,0x30,0xfc,0x30,0x30,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,
|
||
|
0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,
|
||
|
0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,
|
||
|
0x7c,0xc6,0xce,0xde,0xf6,0xe6,0x7c,0x00,
|
||
|
0x30,0x70,0x30,0x30,0x30,0x30,0xfc,0x00,
|
||
|
0x78,0xcc,0x0c,0x38,0x60,0xcc,0xfc,0x00,
|
||
|
0x78,0xcc,0x0c,0x38,0x0c,0xcc,0x78,0x00,
|
||
|
0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x1e,0x00,
|
||
|
0xfc,0xc0,0xf8,0x0c,0x0c,0xcc,0x78,0x00,
|
||
|
0x38,0x60,0xc0,0xf8,0xcc,0xcc,0x78,0x00,
|
||
|
0xfc,0xcc,0x0c,0x18,0x30,0x30,0x30,0x00,
|
||
|
0x78,0xcc,0xcc,0x78,0xcc,0xcc,0x78,0x00,
|
||
|
0x78,0xcc,0xcc,0x7c,0x0c,0x18,0x70,0x00,
|
||
|
0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,
|
||
|
0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x60,
|
||
|
0x18,0x30,0x60,0xc0,0x60,0x30,0x18,0x00,
|
||
|
0x00,0x00,0xfc,0x00,0x00,0xfc,0x00,0x00,
|
||
|
0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00,
|
||
|
0x78,0xcc,0x0c,0x18,0x30,0x00,0x30,0x00,
|
||
|
0x7c,0xc6,0xde,0xde,0xde,0xc0,0x78,0x00,
|
||
|
0x30,0x78,0xcc,0xcc,0xfc,0xcc,0xcc,0x00,
|
||
|
0xfc,0x66,0x66,0x7c,0x66,0x66,0xfc,0x00,
|
||
|
0x3c,0x66,0xc0,0xc0,0xc0,0x66,0x3c,0x00,
|
||
|
0xf8,0x6c,0x66,0x66,0x66,0x6c,0xf8,0x00,
|
||
|
0xfe,0x62,0x68,0x78,0x68,0x62,0xfe,0x00,
|
||
|
0xfe,0x62,0x68,0x78,0x68,0x60,0xf0,0x00,
|
||
|
0x3c,0x66,0xc0,0xc0,0xce,0x66,0x3e,0x00,
|
||
|
0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0x00,
|
||
|
0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,
|
||
|
0x1e,0x0c,0x0c,0x0c,0xcc,0xcc,0x78,0x00,
|
||
|
0xe6,0x66,0x6c,0x78,0x6c,0x66,0xe6,0x00,
|
||
|
0xf0,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,
|
||
|
0xc6,0xee,0xfe,0xfe,0xd6,0xc6,0xc6,0x00,
|
||
|
0xc6,0xe6,0xf6,0xde,0xce,0xc6,0xc6,0x00,
|
||
|
0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x38,0x00,
|
||
|
0xfc,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00,
|
||
|
0x78,0xcc,0xcc,0xcc,0xdc,0x78,0x1c,0x00,
|
||
|
0xfc,0x66,0x66,0x7c,0x6c,0x66,0xe6,0x00,
|
||
|
0x78,0xcc,0xe0,0x70,0x1c,0xcc,0x78,0x00,
|
||
|
0xfc,0xb4,0x30,0x30,0x30,0x30,0x78,0x00,
|
||
|
0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xfc,0x00,
|
||
|
0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,
|
||
|
0xc6,0xc6,0xc6,0xd6,0xfe,0xee,0xc6,0x00,
|
||
|
0xc6,0xc6,0x6c,0x38,0x38,0x6c,0xc6,0x00,
|
||
|
0xcc,0xcc,0xcc,0x78,0x30,0x30,0x78,0x00,
|
||
|
0xfe,0xc6,0x8c,0x18,0x32,0x66,0xfe,0x00,
|
||
|
0x78,0x60,0x60,0x60,0x60,0x60,0x78,0x00,
|
||
|
0xc0,0x60,0x30,0x18,0x0c,0x06,0x02,0x00,
|
||
|
0x78,0x18,0x18,0x18,0x18,0x18,0x78,0x00,
|
||
|
0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
|
||
|
0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x78,0x0c,0x7c,0xcc,0x76,0x00,
|
||
|
0xe0,0x60,0x60,0x7c,0x66,0x66,0xdc,0x00,
|
||
|
0x00,0x00,0x78,0xcc,0xc0,0xcc,0x78,0x00,
|
||
|
0x1c,0x0c,0x0c,0x7c,0xcc,0xcc,0x76,0x00,
|
||
|
0x00,0x00,0x78,0xcc,0xfc,0xc0,0x78,0x00,
|
||
|
0x38,0x6c,0x60,0xf0,0x60,0x60,0xf0,0x00,
|
||
|
0x00,0x00,0x76,0xcc,0xcc,0x7c,0x0c,0xf8,
|
||
|
0xe0,0x60,0x6c,0x76,0x66,0x66,0xe6,0x00,
|
||
|
0x30,0x00,0x70,0x30,0x30,0x30,0x78,0x00,
|
||
|
0x0c,0x00,0x0c,0x0c,0x0c,0xcc,0xcc,0x78,
|
||
|
0xe0,0x60,0x66,0x6c,0x78,0x6c,0xe6,0x00,
|
||
|
0x70,0x30,0x30,0x30,0x30,0x30,0x78,0x00,
|
||
|
0x00,0x00,0xcc,0xfe,0xfe,0xd6,0xc6,0x00,
|
||
|
0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0x00,
|
||
|
0x00,0x00,0x78,0xcc,0xcc,0xcc,0x78,0x00,
|
||
|
0x00,0x00,0xdc,0x66,0x66,0x7c,0x60,0xf0,
|
||
|
0x00,0x00,0x76,0xcc,0xcc,0x7c,0x0c,0x1e,
|
||
|
0x00,0x00,0xdc,0x76,0x66,0x60,0xf0,0x00,
|
||
|
0x00,0x00,0x7c,0xc0,0x78,0x0c,0xf8,0x00,
|
||
|
0x10,0x30,0x7c,0x30,0x30,0x34,0x18,0x00,
|
||
|
0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x76,0x00,
|
||
|
0x00,0x00,0xcc,0xcc,0xcc,0x78,0x30,0x00,
|
||
|
0x00,0x00,0xc6,0xd6,0xfe,0xfe,0x6c,0x00,
|
||
|
0x00,0x00,0xc6,0x6c,0x38,0x6c,0xc6,0x00,
|
||
|
0x00,0x00,0xcc,0xcc,0xcc,0x7c,0x0c,0xf8,
|
||
|
0x00,0x00,0xfc,0x98,0x30,0x64,0xfc,0x00,
|
||
|
0x1c,0x30,0x30,0xe0,0x30,0x30,0x1c,0x00,
|
||
|
0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,
|
||
|
0xe0,0x30,0x30,0x1c,0x30,0x30,0xe0,0x00,
|
||
|
0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
|
0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0x00,
|
||
|
0x78,0xcc,0xc0,0xcc,0x78,0x18,0x0c,0x78,
|
||
|
0x00,0xcc,0x00,0xcc,0xcc,0xcc,0x7e,0x00,
|
||
|
0x1c,0x00,0x78,0xcc,0xfc,0xc0,0x78,0x00,
|
||
|
0x7e,0xc3,0x3c,0x06,0x3e,0x66,0x3f,0x00,
|
||
|
0xcc,0x00,0x78,0x0c,0x7c,0xcc,0x7e,0x00,
|
||
|
0xe0,0x00,0x78,0x0c,0x7c,0xcc,0x7e,0x00,
|
||
|
0x30,0x30,0x78,0x0c,0x7c,0xcc,0x7e,0x00,
|
||
|
0x00,0x00,0x78,0xc0,0xc0,0x78,0x0c,0x38,
|
||
|
0x7e,0xc3,0x3c,0x66,0x7e,0x60,0x3c,0x00,
|
||
|
0xcc,0x00,0x78,0xcc,0xfc,0xc0,0x78,0x00,
|
||
|
0xe0,0x00,0x78,0xcc,0xfc,0xc0,0x78,0x00,
|
||
|
0xcc,0x00,0x70,0x30,0x30,0x30,0x78,0x00,
|
||
|
0x7c,0xc6,0x38,0x18,0x18,0x18,0x3c,0x00,
|
||
|
0xe0,0x00,0x70,0x30,0x30,0x30,0x78,0x00,
|
||
|
0xc6,0x38,0x6c,0xc6,0xfe,0xc6,0xc6,0x00,
|
||
|
0x30,0x30,0x00,0x78,0xcc,0xfc,0xcc,0x00,
|
||
|
0x1c,0x00,0xfc,0x60,0x78,0x60,0xfc,0x00,
|
||
|
0x00,0x00,0x7f,0x0c,0x7f,0xcc,0x7f,0x00,
|
||
|
0x3e,0x6c,0xcc,0xfe,0xcc,0xcc,0xce,0x00,
|
||
|
0x78,0xcc,0x00,0x78,0xcc,0xcc,0x78,0x00,
|
||
|
0x00,0xcc,0x00,0x78,0xcc,0xcc,0x78,0x00,
|
||
|
0x00,0xe0,0x00,0x78,0xcc,0xcc,0x78,0x00,
|
||
|
0x78,0xcc,0x00,0xcc,0xcc,0xcc,0x7e,0x00,
|
||
|
0x00,0xe0,0x00,0xcc,0xcc,0xcc,0x7e,0x00,
|
||
|
0x00,0xcc,0x00,0xcc,0xcc,0x7c,0x0c,0xf8,
|
||
|
0xc3,0x18,0x3c,0x66,0x66,0x3c,0x18,0x00,
|
||
|
0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0x78,0x00,
|
||
|
0x18,0x18,0x7e,0xc0,0xc0,0x7e,0x18,0x18,
|
||
|
0x38,0x6c,0x64,0xf0,0x60,0xe6,0xfc,0x00,
|
||
|
0xcc,0xcc,0x78,0xfc,0x30,0xfc,0x30,0x30,
|
||
|
0xf8,0xcc,0xcc,0xfa,0xc6,0xcf,0xc6,0xc7,
|
||
|
0x0e,0x1b,0x18,0x3c,0x18,0x18,0xd8,0x70,
|
||
|
0x1c,0x00,0x78,0x0c,0x7c,0xcc,0x7e,0x00,
|
||
|
0x38,0x00,0x70,0x30,0x30,0x30,0x78,0x00,
|
||
|
0x00,0x1c,0x00,0x78,0xcc,0xcc,0x78,0x00,
|
||
|
0x00,0x1c,0x00,0xcc,0xcc,0xcc,0x7e,0x00,
|
||
|
0x00,0xf8,0x00,0xf8,0xcc,0xcc,0xcc,0x00,
|
||
|
0xfc,0x00,0xcc,0xec,0xfc,0xdc,0xcc,0x00,
|
||
|
0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,
|
||
|
0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,
|
||
|
0x30,0x00,0x30,0x60,0xc0,0xcc,0x78,0x00,
|
||
|
0x00,0x00,0x00,0xfc,0xc0,0xc0,0x00,0x00,
|
||
|
0x00,0x00,0x00,0xfc,0x0c,0x0c,0x00,0x00,
|
||
|
0xc3,0xc6,0xcc,0xde,0x33,0x66,0xcc,0x0f,
|
||
|
0xc3,0xc6,0xcc,0xdb,0x37,0x6f,0xcf,0x03,
|
||
|
0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x00,
|
||
|
0x00,0x33,0x66,0xcc,0x66,0x33,0x00,0x00,
|
||
|
0x00,0xcc,0x66,0x33,0x66,0xcc,0x00,0x00,
|
||
|
0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,
|
||
|
0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,
|
||
|
0xdb,0x77,0xdb,0xee,0xdb,0x77,0xdb,0xee,
|
||
|
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
|
||
|
0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,
|
||
|
0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,
|
||
|
0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,
|
||
|
0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,
|
||
|
0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,
|
||
|
0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,
|
||
|
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
|
||
|
0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,
|
||
|
0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,
|
||
|
0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,
|
||
|
0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,
|
||
|
0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,
|
||
|
0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,
|
||
|
0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,
|
||
|
0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,
|
||
|
0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,
|
||
|
0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,
|
||
|
0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,
|
||
|
0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,
|
||
|
0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,
|
||
|
0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,
|
||
|
0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,
|
||
|
0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,
|
||
|
0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,
|
||
|
0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,
|
||
|
0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,
|
||
|
0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,
|
||
|
0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,
|
||
|
0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,
|
||
|
0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,
|
||
|
0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,
|
||
|
0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,
|
||
|
0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,
|
||
|
0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,
|
||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||
|
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
|
||
|
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
|
||
|
0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
|
||
|
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x76,0xdc,0xc8,0xdc,0x76,0x00,
|
||
|
0x00,0x78,0xcc,0xf8,0xcc,0xf8,0xc0,0xc0,
|
||
|
0x00,0xfc,0xcc,0xc0,0xc0,0xc0,0xc0,0x00,
|
||
|
0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,
|
||
|
0xfc,0xcc,0x60,0x30,0x60,0xcc,0xfc,0x00,
|
||
|
0x00,0x00,0x7e,0xd8,0xd8,0xd8,0x70,0x00,
|
||
|
0x00,0x66,0x66,0x66,0x66,0x7c,0x60,0xc0,
|
||
|
0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x00,
|
||
|
0xfc,0x30,0x78,0xcc,0xcc,0x78,0x30,0xfc,
|
||
|
0x38,0x6c,0xc6,0xfe,0xc6,0x6c,0x38,0x00,
|
||
|
0x38,0x6c,0xc6,0xc6,0x6c,0x6c,0xee,0x00,
|
||
|
0x1c,0x30,0x18,0x7c,0xcc,0xcc,0x78,0x00,
|
||
|
0x00,0x00,0x7e,0xdb,0xdb,0x7e,0x00,0x00,
|
||
|
0x06,0x0c,0x7e,0xdb,0xdb,0x7e,0x60,0xc0,
|
||
|
0x38,0x60,0xc0,0xf8,0xc0,0x60,0x38,0x00,
|
||
|
0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,
|
||
|
0x00,0xfc,0x00,0xfc,0x00,0xfc,0x00,0x00,
|
||
|
0x30,0x30,0xfc,0x30,0x30,0x00,0xfc,0x00,
|
||
|
0x60,0x30,0x18,0x30,0x60,0x00,0xfc,0x00,
|
||
|
0x18,0x30,0x60,0x30,0x18,0x00,0xfc,0x00,
|
||
|
0x0e,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,
|
||
|
0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,
|
||
|
0x30,0x30,0x00,0xfc,0x00,0x30,0x30,0x00,
|
||
|
0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,
|
||
|
0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
|
||
|
0x0f,0x0c,0x0c,0x0c,0xec,0x6c,0x3c,0x1c,
|
||
|
0x78,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,
|
||
|
0x70,0x18,0x30,0x60,0x78,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
|
};
|
||
|
|
||
|
static uint32 videoCursor = 0;
|
||
|
static uint16 * videoBuffer = 0;
|
||
|
|
||
|
void InitializeDisplay(uint16 * VideoBuffer)
|
||
|
{
|
||
|
InitializeDisplayPowerDomains();
|
||
|
|
||
|
videoBuffer = VideoBuffer;
|
||
|
|
||
|
uint8 * DispCRegBase = (uint8 *)0x48050400;
|
||
|
|
||
|
//
|
||
|
// XXX code derived from TI diagnostic, tainted.
|
||
|
//
|
||
|
|
||
|
// xxx dss_clock_init
|
||
|
|
||
|
//
|
||
|
// disable dss
|
||
|
//
|
||
|
|
||
|
uint32 Value = ReadReg32(DispCRegBase + DISPC_CONTROL);
|
||
|
Value &= ~(DISPC_CONTROL_DIGITALENABLE | DISPC_CONTROL_LCDENABLE);
|
||
|
WriteReg32(DispCRegBase + DISPC_CONTROL, Value);
|
||
|
|
||
|
//
|
||
|
// Reset display controller
|
||
|
//
|
||
|
|
||
|
WriteReg32(DispCRegBase + DISPC_SYSCONFIG, DISPC_SYSCONFIG_SOFTRESET);
|
||
|
|
||
|
while((ReadReg32(DispCRegBase + DISPC_SYSSTATUS) & DISPC_SYSSTATUS_RESETDONE) == 0);
|
||
|
Value = ReadReg32(DispCRegBase + DISPC_SYSCONFIG);
|
||
|
Value &= ~DISPC_SYSCONFIG_SOFTRESET;
|
||
|
WriteReg32(DispCRegBase + DISPC_SYSCONFIG, Value);
|
||
|
|
||
|
|
||
|
//
|
||
|
// _ARM_WORKAROUND_ cheat and setup lcd power and backlight
|
||
|
// earlier in HAL. Right way to do this is with query interface
|
||
|
// of the stack to get a control interface.
|
||
|
//
|
||
|
// XXX do triton thing here to enable lcd power, and thena gpio that i don't understand
|
||
|
// xxx gpio thing to enable backlight
|
||
|
|
||
|
// configure dss
|
||
|
|
||
|
WriteReg32(DispCRegBase + DISPC_SYSCONFIG,
|
||
|
DISPC_SYSCONFIG_MIDLEMODE_NSTANDBY |
|
||
|
DISPC_SYSCONFIG_SIDLEMODE_NIDLE);
|
||
|
|
||
|
// disable interrupts
|
||
|
WriteReg32(DispCRegBase + DISPC_IRQENABLE, 0);
|
||
|
|
||
|
// 2:1 - Frame Data only loaded every frame (10)
|
||
|
|
||
|
WriteReg32(DispCRegBase + DISPC_CONFIG,
|
||
|
DISPC_CONFIG_LOADMODE_FRDATLEF);
|
||
|
|
||
|
// Default Color is white
|
||
|
WriteReg32(DispCRegBase + DISPC_DEFAULT_COLOR0,
|
||
|
0xFFFFFF);
|
||
|
|
||
|
// Default Transparency Color is black */
|
||
|
WriteReg32(DispCRegBase + DISPC_TRANS_COLOR0, 0);
|
||
|
|
||
|
// timing logic for HSYNC signal
|
||
|
|
||
|
uint32 bp = (3 - 1);
|
||
|
uint32 fp = (4 - 1);
|
||
|
uint32 sw = (2 - 1);
|
||
|
|
||
|
Value = (bp << DISPC_TIMING_H_HBP_SHIFT) | (fp << DISPC_TIMING_H_HFP_SHIFT) | (sw << DISPC_TIMING_H_HSW_SHIFT);
|
||
|
WriteReg32(DispCRegBase + DISPC_TIMING_H, Value);
|
||
|
|
||
|
// timing logic for VSYNC signal
|
||
|
|
||
|
bp = 6;
|
||
|
fp = 9;
|
||
|
sw = 1;
|
||
|
|
||
|
Value = (bp << DISPC_TIMING_V_VBP_SHIFT) | (fp << DISPC_TIMING_V_VFP_SHIFT) | (sw << DISPC_TIMING_V_VSW_SHIFT);
|
||
|
WriteReg32(DispCRegBase + DISPC_TIMING_V, Value);
|
||
|
|
||
|
// signal configuration
|
||
|
WriteReg32(DispCRegBase + DISPC_POL_FREQ, 0);
|
||
|
|
||
|
// configures the divisor
|
||
|
Value = (1 << DISPC_DIVISOR_LCD_SHIFT) | (17 << DISPC_DIVISOR_PCD_SHIFT);
|
||
|
WriteReg32(DispCRegBase + DISPC_DIVISOR, Value);
|
||
|
|
||
|
// configure panel size
|
||
|
WriteReg32(DispCRegBase + DISPC_SIZE_LCD,
|
||
|
DISPC_SIZE_LCD_QVGA_PORTRAIT);
|
||
|
|
||
|
// set lcd interface datalines
|
||
|
// defaults to 16
|
||
|
|
||
|
// Configure Graphics Window
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_BA0, (uint32)VideoBuffer);
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_BA1, (uint32)VideoBuffer);
|
||
|
|
||
|
// set window position
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_POSITION, 0);
|
||
|
|
||
|
// set window size
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_SIZE, DISPC_SIZE_QVGA_PORTRAIT);
|
||
|
|
||
|
Value = ReadReg32(DispCRegBase + DISPC_GFX_ATTRIBUTES);
|
||
|
Value |= DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGB16;
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_ATTRIBUTES, Value);
|
||
|
|
||
|
Value= (252 << DISPC_GFX_FIFO_THRESHOLD_HIGH_SHIFT) | (192 << DISPC_GFX_FIFO_THRESHOLD_LOW_SHIFT);
|
||
|
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_FIFO_THRESHOLD, Value);
|
||
|
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_ROW_INC, 1);
|
||
|
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_PIXEL_INC, 1);
|
||
|
|
||
|
Value = ReadReg32(DispCRegBase + DISPC_GFX_ATTRIBUTES);
|
||
|
Value |= DISPC_GFX_ATTRIBUTES_ENABLE;
|
||
|
WriteReg32(DispCRegBase + DISPC_GFX_ATTRIBUTES, Value);
|
||
|
|
||
|
// LCD output enabled, active display,16-bit output.
|
||
|
Value = DISPC_CONTROL_GPOUT1 | DISPC_CONTROL_GPOUT0
|
||
|
| DISPC_CONTROL_TFTDATALINES_OALSB16B | DISPC_CONTROL_STNTFT |
|
||
|
DISPC_CONTROL_LCDENABLE;
|
||
|
Value &= ~DISPC_CONTROL_RFBIMODE; // RFBI mode disabled.
|
||
|
WriteReg32(DispCRegBase + DISPC_CONTROL, Value);
|
||
|
|
||
|
Value = ReadReg32(DispCRegBase + DISPC_CONTROL);
|
||
|
Value |= DISPC_CONTROL_GOLCD; // LCD GO command.
|
||
|
WriteReg32(DispCRegBase + DISPC_CONTROL, Value);
|
||
|
|
||
|
memset(VideoBuffer, 0xff, 240 * 320 * 2);
|
||
|
}
|
||
|
|
||
|
void Draw(uint8 c)
|
||
|
{
|
||
|
if (videoBuffer == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (c == '\f') {
|
||
|
videoCursor = 0;
|
||
|
memset(videoBuffer, 0, 240 * 320 * 2);
|
||
|
return;
|
||
|
}
|
||
|
else if (c == '\n') {
|
||
|
videoCursor += 30 - (videoCursor % 30);
|
||
|
check_scroll:
|
||
|
while (videoCursor >= 30 * 40) {
|
||
|
memmove(videoBuffer, videoBuffer + 240 * 8, 240 * 312 * 2);
|
||
|
memset(videoBuffer + 312 * 240, 0, 240 * 16); // 2 bytes/pixel * 8 pixels
|
||
|
videoCursor -= 30;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
uint cy = (videoCursor / 30) * 8;
|
||
|
uint cx = (videoCursor % 30) * 8;
|
||
|
uint16 * buffer = videoBuffer + 240 * cy + cx;
|
||
|
|
||
|
if (c == '\r') {
|
||
|
uint toclear = 30 - (videoCursor % 30);
|
||
|
|
||
|
for (uint y = 0; y < 8; y++) {
|
||
|
memset(buffer, 0, toclear * 16); // 2 bytes/pixel * 8 pixels
|
||
|
buffer += 240;
|
||
|
}
|
||
|
videoCursor -= videoCursor % 30;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Find the glyph.
|
||
|
uint8 *pixels = Font8 + c * 8;
|
||
|
|
||
|
// Draw the pixels.
|
||
|
for (uint y = 0; y < 8; y++) {
|
||
|
uint8 line = *pixels++;
|
||
|
for (int x = 7; x >= 0; x--) {
|
||
|
buffer[x] = (line & 1) ? 0xffff : 0x0000;
|
||
|
line >>= 1;
|
||
|
}
|
||
|
buffer += 240;
|
||
|
}
|
||
|
videoCursor++;
|
||
|
goto check_scroll;
|
||
|
}
|
||
|
|
||
|
void Draw(const char * str)
|
||
|
{
|
||
|
for (int i = 0; i < 2048 && str[i] != '\0'; i++) {
|
||
|
Draw((uint8)str[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void DebugBreak();
|
||
|
|
||
|
void Halt()
|
||
|
{
|
||
|
printf("Halt.");
|
||
|
DebugBreak();
|
||
|
}
|
||
|
|
||
|
void Cls()
|
||
|
{
|
||
|
BdPrintString("-------------------------------------------------------------------------------\n", 80);
|
||
|
Draw('\f');
|
||
|
}
|
||
|
|
||
|
void __cdecl PutChar(char cOut)
|
||
|
{
|
||
|
Draw(cOut);
|
||
|
|
||
|
static CHAR szBuffer[256];
|
||
|
static INT nBuffer = 0;
|
||
|
|
||
|
szBuffer[nBuffer++] = cOut;
|
||
|
if (cOut == '\n' || nBuffer >= sizeof(szBuffer) - 1) {
|
||
|
BdPrintString(szBuffer, nBuffer);
|
||
|
nBuffer = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Probe(UINT8 * pbData, UINT cbData)
|
||
|
{
|
||
|
UINT8 b;
|
||
|
|
||
|
for (UINT i = 0; i < cbData; i++) {
|
||
|
b = pbData[i];
|
||
|
pbData[i] = b;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Dump(UINT8 * pbData, UINT cbData)
|
||
|
{
|
||
|
for (UINT n = 0; n < cbData; n += 16) {
|
||
|
printf(" %08x:", pbData + n);
|
||
|
UINT o = n;
|
||
|
for (; o < n + 16; o++) {
|
||
|
if (o >= cbData) {
|
||
|
printf(" ");
|
||
|
}
|
||
|
else {
|
||
|
printf("%02x", pbData[o]);
|
||
|
}
|
||
|
if (o % 4 == 3) {
|
||
|
printf(" ");
|
||
|
}
|
||
|
}
|
||
|
printf(" ");
|
||
|
for (o = n; o < n + 16; o++) {
|
||
|
if (o >= cbData) {
|
||
|
printf(" ");
|
||
|
}
|
||
|
else {
|
||
|
if (pbData[o] >= ' ' && pbData[o] < 127) {
|
||
|
printf("%c", pbData[o]);
|
||
|
}
|
||
|
else {
|
||
|
printf(".");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
printf("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Dump(UINT8 * pbData, UINT8 * pbLimit, UINT cbMax)
|
||
|
{
|
||
|
UINT cbData = (uint) (pbLimit - pbData);
|
||
|
if (cbData > cbMax) {
|
||
|
cbData = cbMax;
|
||
|
}
|
||
|
Dump(pbData, cbData);
|
||
|
}
|
||
|
|
||
|
static void CopyDown(UINT8 *pbDst, UINT8 *pbSrc, UINT32 cbSrc)
|
||
|
{
|
||
|
//!!! pbDst <= pbSrc
|
||
|
if (pbDst > pbSrc) {
|
||
|
printf("CopyDown(dst=%p > src=%p)\n", pbDst, pbSrc);
|
||
|
Halt();
|
||
|
}
|
||
|
|
||
|
INT32 nSrc = (cbSrc + 3) / 4;
|
||
|
volatile UINT32 *pDst = (UINT32*)pbDst;
|
||
|
volatile UINT32 *pSrc = (UINT32*)pbSrc;
|
||
|
|
||
|
while (nSrc-- > 0) {
|
||
|
*pDst = *pSrc;
|
||
|
if (*pDst != *pSrc) {
|
||
|
printf("CopyDown error at %p/%p : %08x != %08x\n",
|
||
|
pDst, pSrc, *pDst, *pSrc);
|
||
|
Halt();
|
||
|
}
|
||
|
pDst++;
|
||
|
pSrc++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void Zero(uint8 * pbData, uint32 cbData)
|
||
|
{
|
||
|
INT32 nDst = (cbData + 3) / 4;
|
||
|
volatile UINT32 *pDst = (UINT32*)pbData;
|
||
|
|
||
|
while (nDst-- > 0) {
|
||
|
*pDst++ = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const char * SmapTypeToString(int type)
|
||
|
{
|
||
|
switch (type) {
|
||
|
case 1: return "RAM ";
|
||
|
case 2: return "Reserved";
|
||
|
case 3: return "ACPI RAM";
|
||
|
case 4: return "ACPI NVS";
|
||
|
default: return "Other ";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool check(UINT8 *pbCache, UINT8 value, const char *pszDesc)
|
||
|
{
|
||
|
for (int i = 0; i < 16; i++) {
|
||
|
if (pbCache[i] == value) {
|
||
|
pbCache[i] = 0;
|
||
|
printf(" %s\n", pszDesc);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static bool CheckSmapForRam(const Class_Microsoft_Singularity_Hal_Platform *bi, UINT64 base, UINT64 size)
|
||
|
{
|
||
|
Struct_Microsoft_Singularity_SMAPINFO *sm = (Struct_Microsoft_Singularity_SMAPINFO *) bi->Smap32;
|
||
|
for (int32 i = 0; i < bi->SmapCount; i++) {
|
||
|
if (sm[i].type == 1 &&
|
||
|
sm[i].addr <= base &&
|
||
|
sm[i].addr + sm[i].size >= base + size) {
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static void CheckSmap(const Class_Microsoft_Singularity_Hal_Platform *bi)
|
||
|
{
|
||
|
/////////////////////////////////////////////////////// System Memory Map.
|
||
|
//
|
||
|
printf(" BaseAddr LimtAddr Type \n");
|
||
|
printf(" ======== ======== ========== [%8x]\n", bi->Smap32);
|
||
|
|
||
|
Struct_Microsoft_Singularity_SMAPINFO *sm = (Struct_Microsoft_Singularity_SMAPINFO *) bi->Smap32;
|
||
|
for (int32 i = 0; i < bi->SmapCount; i++) {
|
||
|
printf(" %8x", (UINT32)(sm[i].addr));
|
||
|
printf(" %8x", (UINT32)(sm[i].addr + sm[i].size));
|
||
|
printf(" %d:%s\n",
|
||
|
sm[i].type,
|
||
|
SmapTypeToString((int)sm[i].type));
|
||
|
}
|
||
|
printf("\n");
|
||
|
}
|
||
|
|
||
|
void SortSmap(const Class_Microsoft_Singularity_Hal_Platform *bi)
|
||
|
{
|
||
|
Struct_Microsoft_Singularity_SMAPINFO *sm = (Struct_Microsoft_Singularity_SMAPINFO *) bi->Smap32;
|
||
|
// Sort the system memory map.
|
||
|
sortagain:
|
||
|
for (int i = 0; i < bi->SmapCount - 1; i++) {
|
||
|
if ((sm[i].addr > sm[i + 1].addr) ||
|
||
|
(sm[i].addr == sm[i + 1].addr &&
|
||
|
sm[i].addr > sm[i + 1].addr)) {
|
||
|
|
||
|
Struct_Microsoft_Singularity_SMAPINFO s = sm[i];
|
||
|
sm[i] = sm[i+1];
|
||
|
sm[i+1] = s;
|
||
|
|
||
|
goto sortagain;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static uintptr g_Entry = 0;
|
||
|
static uintptr g_Stack = 0;
|
||
|
static Class_Microsoft_Singularity_Hal_Platform *g_bi = 0;
|
||
|
static Class_Microsoft_Singularity_Hal_Cpu *g_ci = 0;
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
static bool memeq(const uint8 * p1, const uint8 * p2, uint size)
|
||
|
{
|
||
|
for (; size > 0; size--) {
|
||
|
if (*p1++ != *p2++) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
struct FlashHead
|
||
|
{
|
||
|
uint8 label[18];
|
||
|
uint8 headSize;
|
||
|
uint8 fileSize;
|
||
|
uint32 pageSize;
|
||
|
uint32 majorVersion;
|
||
|
uint32 minorVersion;
|
||
|
};
|
||
|
|
||
|
struct FlashFile
|
||
|
{
|
||
|
uint32 pathOffset;
|
||
|
uint32 dataOffset;
|
||
|
uint32 size;
|
||
|
};
|
||
|
|
||
|
uintptr FindFlashImage(uintptr begin, uintptr limit)
|
||
|
{
|
||
|
// Round begin and limit to nearest valid addresses.
|
||
|
begin = (begin + 0xffff) & ~(uintptr)0xffff;
|
||
|
limit = (limit + 0xffff) & ~(uintptr)0xffff;
|
||
|
|
||
|
// walk through at 64KB boundaries looking for flash image.
|
||
|
for (; begin < limit ; begin += 0x10000) {
|
||
|
const FlashHead * head = (const FlashHead *)begin;
|
||
|
if (!memeq(head->label, (uint8*)"SingularityFlash!", sizeof(head->label))) {
|
||
|
continue;
|
||
|
}
|
||
|
if (head->headSize != sizeof(FlashHead)) {
|
||
|
continue;
|
||
|
}
|
||
|
if (head->fileSize != sizeof(FlashFile)) {
|
||
|
continue;
|
||
|
}
|
||
|
if (head->majorVersion != ~0u || head->minorVersion != ~0u) {
|
||
|
continue;
|
||
|
}
|
||
|
if (head->pageSize != 0x1000) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Header values all check out, now look at image content.
|
||
|
|
||
|
const FlashFile *file = (FlashFile*)(head + 1);
|
||
|
const FlashFile *fend = file + 8192;
|
||
|
for (; file < fend; file++) {
|
||
|
if ((file->dataOffset == 0xffffffff && file->size == 0xffffffff) ||
|
||
|
(file->dataOffset == 0 && file->size == 0)) {
|
||
|
continue;
|
||
|
}
|
||
|
else if (file->dataOffset == 0xffffffff && file->size == 0) {
|
||
|
return begin;
|
||
|
}
|
||
|
else if ((file->dataOffset & 0xfff) != 0) {
|
||
|
// file has unaligned offset.
|
||
|
printf("Unaligned offset: %x\n", file);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
uintptr SizeFlashImage(uintptr begin, uint& count)
|
||
|
{
|
||
|
uintptr limit = 0;
|
||
|
count = 0;
|
||
|
|
||
|
const FlashHead * head = (const FlashHead *)begin;
|
||
|
const FlashFile *file = (FlashFile*)(head + 1);
|
||
|
|
||
|
// Assumes that there is always at least one valid file in the flash.
|
||
|
for (;; file++) {
|
||
|
if ((file->dataOffset == 0xffffffff && file->size == 0xffffffff) ||
|
||
|
(file->dataOffset == 0 && file->size == 0)) {
|
||
|
continue;
|
||
|
}
|
||
|
else if (file->dataOffset == 0xffffffff && file->size == 0) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (limit < file->dataOffset + file->size) {
|
||
|
limit = file->dataOffset + file->size;
|
||
|
}
|
||
|
count++;
|
||
|
}
|
||
|
|
||
|
return ((limit + 0xfff) & ~0xfff);
|
||
|
}
|
||
|
|
||
|
void ProcessFlashImage(uintptr begin,
|
||
|
Struct_Microsoft_Singularity_Io_FileImage *files, uint count)
|
||
|
{
|
||
|
const FlashHead * head = (const FlashHead *)begin;
|
||
|
const FlashFile *file = (FlashFile*)(head + 1);
|
||
|
|
||
|
// Assumes that there is always at least one valid file in the flash.
|
||
|
for (uint item = 0;; file++) {
|
||
|
if ((file->dataOffset == 0xffffffff && file->size == 0xffffffff) ||
|
||
|
(file->dataOffset == 0 && file->size == 0)) {
|
||
|
continue;
|
||
|
}
|
||
|
else if (file->dataOffset == 0xffffffff && file->size == 0) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (item < count) {
|
||
|
files[item].Address = begin + file->dataOffset;
|
||
|
files[item].Size = file->size;
|
||
|
item++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
|
||
|
extern uintptr GetStack(void);
|
||
|
extern uintptr GetCode(void);
|
||
|
extern uint32 GetMidr(void);
|
||
|
extern uint32 GetPfr0(void);
|
||
|
extern uint32 GetPfr1(void);
|
||
|
extern uintptr GetVbar(void);
|
||
|
extern void SetVbar(uintptr);
|
||
|
extern void SetTpidrurw(uintptr);
|
||
|
|
||
|
uint MpStartupLock = 0;
|
||
|
|
||
|
int BootPhase1(void)
|
||
|
{
|
||
|
HalpClocksInitialize();
|
||
|
HalpGpioInitialize();
|
||
|
HalpI2CMasterInitialize();
|
||
|
|
||
|
BdInitDebugger(BdPortInit((uint32 *)OMAP_UART1_BASE, 115200));
|
||
|
printf("\f\n\rSingularity ARM Boot Loader [" __DATE__ " "__TIME__ "]\n\r");
|
||
|
|
||
|
InitializeDisplay((uint16 *)ON_OMAP3430_VIDEO_ADDR);
|
||
|
Draw("\fSingularity ARM Boot Loader\n[" __DATE__ " "__TIME__ "]\n\r");
|
||
|
|
||
|
uintptr base;
|
||
|
uintptr size = SizeOfPeImage((uintptr)ON_OMAP3430_LOADER_ADDR, base);
|
||
|
|
||
|
ASSERT(size <= ON_OMAP3430_LOADER_SIZE);
|
||
|
|
||
|
// Find out what kind of processor we're running on.
|
||
|
uint32 midr = GetMidr();
|
||
|
switch ((midr & 0xff000000) >> 24) {
|
||
|
case 0x41: printf("ARM Ltd "); break;
|
||
|
case 0x44: printf("DEC "); break;
|
||
|
case 0x4d: printf("Motorola "); break;
|
||
|
case 0x51: printf("Qualcomm "); break;
|
||
|
case 0x56: printf("Marvell "); break;
|
||
|
case 0x69: printf("Intel "); break;
|
||
|
default: printf("Implementor? ");
|
||
|
|
||
|
}
|
||
|
switch ((midr & 0xf0000) >> 16) {
|
||
|
case 0x01: printf("ARMv4 "); break;
|
||
|
case 0x02: printf("ARMv4T "); break;
|
||
|
case 0x03: printf("ARMv5 "); break;
|
||
|
case 0x04: printf("ARMv5T "); break;
|
||
|
case 0x05: printf("ARMv5TE "); break;
|
||
|
case 0x06: printf("ARMv5TEJ "); break;
|
||
|
case 0x07: printf("ARMv6 "); break;
|
||
|
case 0x0f: printf("ARMv7 "); break;
|
||
|
default: printf("Variant? "); break;
|
||
|
}
|
||
|
printf("%x.%x\n", (midr & 0xfff0) >> 4, midr & 0xf);
|
||
|
|
||
|
if ((midr & 0xf0000) == 0xf0000) {
|
||
|
// ARMv7, Used CPUID scheme.
|
||
|
printf("PFR: 0:%08x, 1:%08x\n", GetPfr0(), GetPfr1());
|
||
|
}
|
||
|
printf("\n");
|
||
|
|
||
|
//
|
||
|
// Get the BIOS info
|
||
|
//
|
||
|
g_bi = (Class_Microsoft_Singularity_Hal_Platform *)
|
||
|
alloc(sizeof(Class_Microsoft_Singularity_Hal_Platform));
|
||
|
g_bi->Size = sizeof(Class_Microsoft_Singularity_Hal_Platform);
|
||
|
|
||
|
//
|
||
|
// Save the debug information.
|
||
|
//
|
||
|
g_bi->DebugBasePort = OMAP_UART1_BASE;
|
||
|
|
||
|
//
|
||
|
// Set up Memory Map
|
||
|
//
|
||
|
Struct_Microsoft_Singularity_SMAPINFO *sm =
|
||
|
(Struct_Microsoft_Singularity_SMAPINFO *)
|
||
|
alloc(sizeof(Struct_Microsoft_Singularity_SMAPINFO) * 32);
|
||
|
|
||
|
g_bi->Smap32 = (uintptr)sm;
|
||
|
|
||
|
// Remember loader.
|
||
|
sm[0].type = Struct_Microsoft_Singularity_SMAPINFO_AddressTypeReserved;
|
||
|
sm[0].addr = ON_OMAP3430_LOADER_ADDR;
|
||
|
sm[0].size = SizeOfPeImage((uintptr)ON_OMAP3430_LOADER_ADDR, base);
|
||
|
|
||
|
// Remember other low reserved.
|
||
|
sm[1].type = Struct_Microsoft_Singularity_SMAPINFO_AddressTypeReserved;
|
||
|
sm[1].addr = ON_OMAP3430_RESERVE_ADDR + sm[0].size;
|
||
|
sm[1].size = ON_OMAP3430_RESERVE_SIZE - (sm[1].addr - ON_OMAP3430_RESERVE_ADDR);
|
||
|
|
||
|
// Remember RAM.
|
||
|
sm[2].type = Struct_Microsoft_Singularity_SMAPINFO_AddressTypeFree;
|
||
|
sm[2].addr = ON_OMAP3430_STACK_ADDR;
|
||
|
sm[2].size = ON_OMAP3430_MEMORY_SIZE - (ON_OMAP3430_STACK_ADDR - ON_OMAP3430_MEMORY_ADDR);
|
||
|
|
||
|
// Mark off I/O memory
|
||
|
sm[3].type = Struct_Microsoft_Singularity_SMAPINFO_AddressTypeUnusable;
|
||
|
sm[3].addr = 0;
|
||
|
sm[3].size = 0x80000000;
|
||
|
|
||
|
g_bi->SmapCount = 4;
|
||
|
|
||
|
//
|
||
|
// Register the boot memory that we use to allocated classes
|
||
|
// that will be converted into managed classes once the kernel
|
||
|
// initializes. This is so it can be properly reported to the
|
||
|
// GC.
|
||
|
//
|
||
|
// Record the entire boot memory range so that the kernel does
|
||
|
// not use it for working memory
|
||
|
//
|
||
|
g_bi->BootAllocatedMemory = 0;
|
||
|
g_bi->BootAllocatedMemorySize = 0x00400000; // Leave this as a guess of memory usage
|
||
|
|
||
|
g_bi->CpuRealCount = 1;
|
||
|
g_bi->CpuMaxCount = 1;
|
||
|
g_bi->BootCount = 0;
|
||
|
|
||
|
g_bi->LogRecordBuffer = ON_OMAP3430_LOGBUF_ADDR; // See Platform.cs
|
||
|
g_bi->LogRecordSize = ON_OMAP3430_LOGBUF_SIZE;
|
||
|
g_bi->LogTextBuffer = ON_OMAP3430_LOGTXT_ADDR;
|
||
|
g_bi->LogTextSize = ON_OMAP3430_LOGTXT_SIZE;
|
||
|
g_bi->KernelDllFirstPage=
|
||
|
g_bi->KernelDllBase = ON_OMAP3430_KERNEL_ADDR;
|
||
|
g_bi->PhysicalBase = 0x00010000;
|
||
|
|
||
|
//
|
||
|
// NOTE: The singldr should edit the SMAP to not include memory
|
||
|
// allocated to the kernel, its stacks, etc, similar to busying
|
||
|
// out the dump record.
|
||
|
//
|
||
|
// This would be a cleaner communication than the current
|
||
|
// combination of SMAP's, kernel base etc.
|
||
|
//
|
||
|
// There has been discussion of a modified version of SMAP that
|
||
|
// is communicated to the kernel that describes how memory has
|
||
|
// been used. SMAP describes general memory information, while
|
||
|
// the kernel needs to know how memory taken from the SMAP was
|
||
|
// used. This is important for the kernel to build its GC
|
||
|
// structures that track which pages contain GC objects.
|
||
|
//
|
||
|
|
||
|
g_bi->CpuMaxCount = 1;
|
||
|
|
||
|
g_ci = (Class_Microsoft_Singularity_Hal_Cpu *)
|
||
|
alloc(sizeof(Class_Microsoft_Singularity_Hal_Cpu) * 1);
|
||
|
g_bi->Cpus = (uintptr)g_ci;
|
||
|
g_ci->Size = sizeof(Class_Microsoft_Singularity_Hal_Cpu);
|
||
|
g_ci->Id = 0;
|
||
|
g_ci->KernelStackLimit = ON_OMAP3430_STACK_ADDR; // See also Platform.cs
|
||
|
g_ci->KernelStackBegin = ON_OMAP3430_STACK_ADDR + ON_OMAP3430_STACK_SIZE;
|
||
|
|
||
|
// Default to the Serial debugger
|
||
|
g_bi->DebuggerType = Class_Microsoft_Singularity_Hal_Platform_DEBUGGER_SERIAL;
|
||
|
|
||
|
g_bi->CommandLine32 = 0;
|
||
|
g_bi->CommandLineCount = 0;
|
||
|
|
||
|
printf("\n");
|
||
|
|
||
|
#if 0
|
||
|
//
|
||
|
// Drop SMAP entries above supported limit
|
||
|
//
|
||
|
for (int i = 0; i < g_bi->SmapCount; i++) {
|
||
|
if (sm[i].type != Struct_Microsoft_Singularity_SMAPINFO_AddressTypeFree) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ((sm[i].addr != 0ul) ||
|
||
|
(sm[i].addr >= Class_Microsoft_Singularity_Hal_Platform_MAX_VIRTUAL_ADDR)) {
|
||
|
sm[i] = sm[--g_bi->SmapCount];
|
||
|
}
|
||
|
else if (sm[i].addr + sm[i].size >= Class_Microsoft_Singularity_Hal_Platform_MAX_VIRTUAL_ADDR) {
|
||
|
sm[i].size = Class_Microsoft_Singularity_Hal_Platform_MAX_VIRTUAL_ADDR - sm[i].addr;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// Sort the system memory map.
|
||
|
SortSmap(g_bi);
|
||
|
|
||
|
//
|
||
|
// Make a reasonable guess at the size of physical memory.
|
||
|
//
|
||
|
uint32 memoryKB = 0;
|
||
|
for (int i = 0; i < g_bi->SmapCount; i++) {
|
||
|
if (sm[i].type == Struct_Microsoft_Singularity_SMAPINFO_AddressTypeFree) {
|
||
|
memoryKB += (uint32)(sm[i].size / 1024);
|
||
|
}
|
||
|
}
|
||
|
printf("Physical memory: %uMB\n", memoryKB / 1024);
|
||
|
|
||
|
CheckSmap(g_bi);
|
||
|
|
||
|
//
|
||
|
// Find the flash image.
|
||
|
//
|
||
|
uintptr flash = 0;
|
||
|
for (int i = 0; i < g_bi->SmapCount && flash == 0; i++) {
|
||
|
if (sm[i].type == Struct_Microsoft_Singularity_SMAPINFO_AddressTypeFree ||
|
||
|
sm[i].type == Struct_Microsoft_Singularity_SMAPINFO_AddressTypeReserved) {
|
||
|
|
||
|
flash = FindFlashImage((uintptr)sm[i].addr,
|
||
|
(uintptr)(sm[i].addr + sm[i].size));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (flash == 0) {
|
||
|
printf("No valid flash image.\n");
|
||
|
Halt();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Count the flash files and size the image.
|
||
|
//
|
||
|
uint nMaxImages = 0;
|
||
|
g_bi->DumpAddr32 = flash;
|
||
|
g_bi->DumpSize32 = SizeFlashImage(flash, nMaxImages);
|
||
|
printf("Flash: %08x..%08x.\n",
|
||
|
(uint32)g_bi->DumpAddr32,
|
||
|
(uint32)(g_bi->DumpAddr32 + g_bi->DumpSize32));
|
||
|
printf("Flash has %d files.\n", nMaxImages);
|
||
|
|
||
|
//
|
||
|
// Remember the flash files.
|
||
|
//
|
||
|
Struct_Microsoft_Singularity_Io_FileImage * files =
|
||
|
(Struct_Microsoft_Singularity_Io_FileImage *)
|
||
|
alloc(sizeof(Struct_Microsoft_Singularity_Io_FileImage) * nMaxImages);
|
||
|
|
||
|
ProcessFlashImage(flash, files, nMaxImages);
|
||
|
g_bi->FileImageTableBase32 = (uintptr)files;
|
||
|
g_bi->FileImageTableEntries = nMaxImages;
|
||
|
|
||
|
#if LIEABOUTSMAP
|
||
|
printf("\n");
|
||
|
printf("Editing the SMAP to protect the dump area...\n");
|
||
|
|
||
|
for (i = 0; i < g_bi->SmapCount; i++) {
|
||
|
// Does this region straddle the start of the dump area?
|
||
|
// if so, truncate it
|
||
|
if (sm[i].type == 1 &&
|
||
|
sm[i].addr < g_bi->DumpAddr32 &&
|
||
|
sm[i].addr + sm[i].size > g_bi->DumpAddr32) {
|
||
|
|
||
|
sm[i].size = g_bi->DumpAddr32 - sm[i].addr;
|
||
|
printf(" %08x..%08x %d (truncated)\n",
|
||
|
(uint32)(sm[i].addr),
|
||
|
(uint32)(sm[i].addr + sm[i].size),
|
||
|
sm[i].type);
|
||
|
}
|
||
|
|
||
|
if (sm[i].type == 1 &&
|
||
|
sm[i].addr >= g_bi->DumpAddr32) {
|
||
|
|
||
|
sm[i].type = 2; // Arbitrary non-free value
|
||
|
printf(" %08x..%08x %d (marked unavailable)\n",
|
||
|
(uint32)(sm[i].addr),
|
||
|
(uint32)(sm[i].addr + sm[i].size),
|
||
|
sm[i].type);
|
||
|
}
|
||
|
}
|
||
|
// Sort the system memory map.
|
||
|
SortSmap(g_bi);
|
||
|
#endif
|
||
|
|
||
|
uintptr kernelBase;
|
||
|
g_bi->KernelDllSize = SizeOfPeImage(files[0].Address, kernelBase);
|
||
|
printf("Kernel: %08x..%08x\n",
|
||
|
g_bi->KernelDllBase,
|
||
|
g_bi->KernelDllBase + g_bi->KernelDllSize);
|
||
|
|
||
|
uintptr kernelEntry = ExpandPeImage(g_bi->KernelDllBase, files[0].Address);
|
||
|
printf("Kernel Entry: %08x\n", kernelEntry);
|
||
|
|
||
|
//
|
||
|
g_bi->MpCpuCount = 0;
|
||
|
g_bi->MpStartupLock32 = (uintptr)&MpStartupLock;
|
||
|
|
||
|
//printf("MpStartupLock32* %x, value %x\n", g_bi->MpStartupLock32, MpStartupLock);
|
||
|
|
||
|
//
|
||
|
// Set the offset to the context pointers, which are the
|
||
|
// first two pointer words allocated in the page.
|
||
|
//
|
||
|
//
|
||
|
// Allocate pages for commonly referenced data
|
||
|
//
|
||
|
|
||
|
uint8 * cpuRecord = (uint8 *)allocpages(2);
|
||
|
|
||
|
//
|
||
|
// Set the offset to the context pointers, which are the
|
||
|
// first two pointer words allocated in the page.
|
||
|
//
|
||
|
g_bi->CpuRecordPointerOffset = 0 * sizeof(uintptr);
|
||
|
g_bi->ThreadRecordPointerOffset = 1 * sizeof(uintptr);
|
||
|
|
||
|
//
|
||
|
// Set the DS relative address to the ProcessorContext
|
||
|
//
|
||
|
// Set our base for storing our actual X86.ProcessorContext
|
||
|
//
|
||
|
SetTpidrurw((uintptr)cpuRecord);
|
||
|
|
||
|
// Align CpuRecord to 16-bytes after CpuRecord & ThreadRecord pointers.
|
||
|
g_ci->CpuRecordPage = (uint32)cpuRecord + 16;
|
||
|
|
||
|
g_bi->MiniDumpBase = (uintptr)g_bi->DumpAddr32;
|
||
|
g_bi->MiniDumpLimit = g_bi->MiniDumpBase + ((g_bi->DumpSize32 + 0xffff) & 0xffff0000);
|
||
|
|
||
|
//
|
||
|
// Move to next phase
|
||
|
//
|
||
|
Class_Microsoft_Singularity_Hal_Platform *bi = g_bi;
|
||
|
Class_Microsoft_Singularity_Hal_Cpu *ci = g_ci;
|
||
|
void (* pfHal)(void *, void *) = (void (*)(void *, void *))kernelEntry;
|
||
|
|
||
|
g_bi->IsaCsns = (uint32)videoBuffer;
|
||
|
g_bi->IsaReadPort = videoCursor;
|
||
|
g_bi->KillAction = 0xffff;
|
||
|
|
||
|
pfHal((void*)g_bi, (void*)g_ci);
|
||
|
|
||
|
videoCursor = g_bi->IsaReadPort;
|
||
|
|
||
|
printf("\n");
|
||
|
printf("Kernel exited: %04x\n", g_bi->KillAction);
|
||
|
g_bi->BootCount++;
|
||
|
|
||
|
Halt();
|
||
|
for(;;);
|
||
|
}
|
||
|
|
||
|
extern "C" unsigned __int64 __rt_udiv64by64( unsigned __int64 x, unsigned __int64 y)
|
||
|
{
|
||
|
unsigned __int64 q = 0;
|
||
|
unsigned __int64 mask = 1;
|
||
|
if (y == 0) {
|
||
|
return (unsigned __int64)-1;
|
||
|
}
|
||
|
|
||
|
while (y <= x) {
|
||
|
if (y & 0x8000000000000000) {
|
||
|
x -= y;
|
||
|
q += mask;
|
||
|
break;
|
||
|
}
|
||
|
mask <<= 1;
|
||
|
y <<= 1;
|
||
|
}
|
||
|
|
||
|
while (mask !=0) {
|
||
|
if (y <= x) {
|
||
|
q += mask;
|
||
|
x -= y;
|
||
|
}
|
||
|
y >>= 1;
|
||
|
mask >>= 1;
|
||
|
}
|
||
|
|
||
|
return q;
|
||
|
}
|