📄 xllp_suspendresume.c
字号:
/*
** INTEL CONFIDENTIAL
** Copyright 2000-2005 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
**
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
*/
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//****************************************************************************************
// SUSPEND/RESUME.
//
// Suspend/Resume Process Overview
//
// Suspend consists of saving the CPU and platform state, setting up wakeup triggers,
// then powering off the system. It is performed by code in this module with the aid of
// some external assembly code.
//
// Resume consists of restoring the saved state, and continuing platform operation.
// Resume may be viewed as occurring in several phases...
// Phase 1: Boot the platform to a default working state.
// Phase 2: Restore MMU state, the processor mode, and the stack.
// Phase 3: Restore other device controller and platform state.
// Phase 4: Return system control to the OS.
// Phase 1 is performed by the boot loader.
// Phase 2 is performed by a relatively small assembler module (ResumePhase2A.s) linked with the boot loader.
// Phases 3 and 4 are performed by code in this module (with the aid of some external assembly code).
//
// The main function in this module (Xllp_SuspendAndResume) is intended to be called by the host OS.
// (in the case of WinCE, the calling function is OEMPowerOff)
// It saves system state, establishes wakeup triggers, and powers the system off by calling
// Xllp_SuspendAndResumeA (in xllp_SuspendResumeA.s)
// When the platform wakes up the boot loader performs basic initialization (as it does for any reset),
// senses that the reset reason is wake-from-sleep, and calls Xllp_ResumePhase2A.
// Xllp_ResumePhase2A performs resume phase 2 processing and returns control to Xllp_SuspendAndResumeA
// which restores the stack and returns control Xllp_SuspendAndResume (in this module).
//
// Data restored by resume phase 2 needs to be stored in an area of writable, physically contiguous memory.
// Currently, for WinCE, a 4K page of memory referred to as IMAGE_SHARE_ARGS is used.
// Files involved in suspend/resume
//
// XLLP files
//
// xllp_SuspendResume.c (this file)
// xllp_SuspendResume.h (exports and data definitions for this file)
// xllp_SuspendResumeA.s (Assembly helper functions)
// xllp_SuspendResumeA.h
// xllp_ARM_primitives.s (utility assembly routines for saving/restoring registers, etc.)
// xllp_ARM_primitives.h
// xllp_checksum.s (simple checksum routine)
// xllp_checksum.h
// xllp_ResumePhase2_Data.h,inc (data structure definition)
// xllp_restart_data.h,inc (data structure and constants definition)
//
// OS files (WinCE)
// platform\common\src\arm\intel\pxa27x\power\off.c (OEMPowerOff function)
// platform\common\src\arm\intel\pxa27x\STARTUP\startup.s (boot loader)
// platform\MAINSTONEII\SRC\INC\image_cfg.h,inc (layout and sddress of IMAGE_SHARE_ARGS page)
// platform\MAINSTONEII\SRC\INC\args.h,inc (layout and address of IMAGE_SHARE_ARGS page)
//
//****************************************************************************************
// NOTE 1:
// This file is intended to be OS independent and to a large extent it currently is.
// To achieve OS independence, OS dependent addresses are passed in
// and a few OSD_..... extern functions need to be provided by the host environment.
//
// At this point there is a problem with log messages.
// It is intended that an OSD_LogMessage function be provided by the host environment.
// However, I'm having unresolved reference problems implementing the function under WinCE.
// For now, this is worked around by WINCEOS conditional code in this module.
//
// NOTE 2:
// The new (Magneto) model of WinCE is to seperate platform (eg. Mainstone) specific code
// from chip specific (eg. Bulverde) code by putting the different code in directories.
// However that model is not currently being followed by this code.
// Platform specific code is mixed with other code but conditionalized based on BSP_MAINSTONE.
//****************************************************************************************
#ifndef NO_NHLOGGING
#define ENABLE_DEBUG_MESSAGES 1
#define ENABLE_LOG_MESSAGES 1
#else
#define ENABLE_DEBUG_MESSAGES 0
#define ENABLE_LOG_MESSAGES 0
#endif /* NHLOGGING */
#include "xllp_logmessage.h"
#ifdef TEXT
#undef TEXT
#endif
#define TEXT(s) s
//*********************************************************************************************
// Since this file is intended to be OS independent no OS specific header files should be used.
//*********************************************************************************************
#include <xllp_defs.h>
#include <xllp_ARM_primitives.h> // Core register get/set functions
#include <xllp_restart_data.h> // for RESTART_DATA area definition
#include <xllp_resumephase2_data.h> // for RESUMEPHASE2_DATA area definition
#include <xllp_SuspendResume.h> // for XLLP_SR_OSD_ADDRESSES_T and XllpSuspendAndResume prototype
#include <xllp_SuspendResumeA.h> // for assembler routines
#ifdef BSP_MAINSTONE
#include <xllp_bcr.h>
#endif
#include <xllp_intc.h>
#include <xllp_ost.h>
#include <xllp_rtc.h>
#include <xllp_gpio.h>
#include <xllp_pm.h>
#include <xllp_clkmgr.h>
#include <xllp_i2c.h>
#include <xllp_memctrl.h>
#define XLLP_CPSR_Mode_Mask (0x1f)
#define XLLP_CPSR_Mode_USR (0x10)
#define XLLP_CPSR_Mode_FIQ (0x11)
#define XLLP_CPSR_Mode_IRQ (0x12)
#define XLLP_CPSR_Mode_SVC (0x13)
#define XLLP_CPSR_Mode_ABT (0x17)
#define XLLP_CPSR_Mode_UND (0x1B)
#define XLLP_CPSR_Mode_SYS (0x1F)
#define XLLP_CPSR_I_bit (0x80)
#define XLLP_CPSR_F_bit (0x40)
#define DIFF_UL(a,b) (int)((unsigned long)(a)-(unsigned long)(b))
#define DIMENSION(a) (sizeof(a)/sizeof(a[0]))
//extern int g_13MEnable;
//void InitEthDevice(void);
// Cache flushing is OS Dependent but needs to be done by XLLP code just before power off.
extern void OSD_CacheFlush(void);
//extern void *OSD_MapPAtoVA(unsigned long PA);
//extern long OSD_MapVAtoPA(void *VA);
extern void OSD_DebugCommsResume(void);
extern void OSD_ExecuteAfterAllResets(void);
#define REG_COPY(dst, src, reg, mask) (dst->reg = src->reg & mask)
void intCopy(int *dst, int *src, int n)
{
int i;
for (i = 0; i < n; i++)
*dst++ = *src++;
}
void CLKCopy(XLLP_CLKMGR_T *dst, XLLP_CLKMGR_T *src)
{
REG_COPY(dst, src, cken, XLLP_CLKEN_MASK);
}
void PWRCopy(XLLP_PWRMGR_T *dst, XLLP_PWRMGR_T *src)
{
REG_COPY(dst, src, PSPR, XLLP_PM_PSPR_VLD_MSK);
REG_COPY(dst, src, PWER, XLLP_PM_PWER_VLD_MSK);
REG_COPY(dst, src, PRER, XLLP_PM_PRER_VLD_MSK);
REG_COPY(dst, src, PFER, XLLP_PM_PFER_VLD_MSK);
REG_COPY(dst, src, PKWR, XLLP_PM_PKWR_VLD_MSK);
REG_COPY(dst, src, PCFR, XLLP_PM_PCFR_VLD_MSK);
REG_COPY(dst, src, PSLR, XLLP_PM_PSLR_VLD_MSK);
REG_COPY(dst, src, PGSR0, XLLP_PM_PGSR0_VLD_MSK);
REG_COPY(dst, src, PGSR1, XLLP_PM_PGSR1_VLD_MSK);
REG_COPY(dst, src, PGSR2, XLLP_PM_PGSR2_VLD_MSK);
REG_COPY(dst, src, PGSR3, XLLP_PM_PGSR3_VLD_MSK);
}
void OSTCopy(XLLP_OST_T *dst, XLLP_OST_T *src)
{
REG_COPY(dst, src, oscr0, 0xffffffff);
}
void GPIOCopy(XLLP_GPIO_T *dst, XLLP_GPIO_T *src)
{
REG_COPY(dst, src, GPDR0, XLLP_GPIO_GPDR0_VLD_MSK);
REG_COPY(dst, src, GPDR1, XLLP_GPIO_GPDR1_VLD_MSK);
REG_COPY(dst, src, GPDR2, XLLP_GPIO_GPDR2_VLD_MSK);
REG_COPY(dst, src, GPDR3, XLLP_GPIO_GPDR3_VLD_MSK);
REG_COPY(dst, src, GAFR0_L, XLLP_GPIO_GAFR0_L_VLD_MSK);
REG_COPY(dst, src, GAFR0_U, XLLP_GPIO_GAFR0_U_VLD_MSK);
REG_COPY(dst, src, GAFR1_L, XLLP_GPIO_GAFR1_L_VLD_MSK);
REG_COPY(dst, src, GAFR1_U, XLLP_GPIO_GAFR1_U_VLD_MSK);
REG_COPY(dst, src, GAFR2_L, XLLP_GPIO_GAFR2_L_VLD_MSK);
REG_COPY(dst, src, GAFR2_U, XLLP_GPIO_GAFR2_U_VLD_MSK);
REG_COPY(dst, src, GAFR3_L, XLLP_GPIO_GAFR3_L_VLD_MSK);
REG_COPY(dst, src, GAFR3_U, XLLP_GPIO_GAFR3_U_VLD_MSK);
REG_COPY(dst, src, GRER0, XLLP_GPIO_GRER0_VLD_MSK);
REG_COPY(dst, src, GRER1, XLLP_GPIO_GRER1_VLD_MSK);
REG_COPY(dst, src, GRER2, XLLP_GPIO_GRER2_VLD_MSK);
REG_COPY(dst, src, GRER3, XLLP_GPIO_GRER3_VLD_MSK);
REG_COPY(dst, src, GFER0, XLLP_GPIO_GFER0_VLD_MSK);
REG_COPY(dst, src, GFER1, XLLP_GPIO_GFER1_VLD_MSK);
REG_COPY(dst, src, GFER2, XLLP_GPIO_GFER2_VLD_MSK);
REG_COPY(dst, src, GFER3, XLLP_GPIO_GFER3_VLD_MSK);
}
void INTCCopy(XLLP_INTC_T *dst, XLLP_INTC_T *src)
{
int i;
REG_COPY(dst, src, iclr, XLLP_INTC_ICLR_MASK);
REG_COPY(dst, src, iclr2, XLLP_INTC_ICLR2_MASK);
REG_COPY(dst, src, iccr, XLLP_INTC_ICCR_MASK);
for (i = 0; i < 32; i++)
REG_COPY(dst, src, ipr[i], XLLP_INTC_IPR_MASK);
REG_COPY(dst, src, ipr2[0], XLLP_INTC_IPR2_MASK);
REG_COPY(dst, src, ipr2[1], XLLP_INTC_IPR2_MASK);
REG_COPY(dst, src, icmr, XLLP_INTC_ICMR_MASK);
REG_COPY(dst, src, icmr2, XLLP_INTC_ICMR2_MASK);
}
void XllpCLKSave(XLLP_CLKMGR_T *regs, XLLP_CLKMGR_T *save)
{
CLKCopy(save, regs);
}
void XllpCLKRestore(XLLP_CLKMGR_T *regs, XLLP_CLKMGR_T *save)
{
CLKCopy(regs, save);
}
void XllpPWRSave(XLLP_PWRMGR_T *regs, XLLP_PWRMGR_T *save)
{
PWRCopy(save, regs);
}
void XllpPWRRestore(XLLP_PWRMGR_T *regs, XLLP_PWRMGR_T *save)
{
PWRCopy(regs, save);
}
void XllpOSTSave(XLLP_OST_T *regs, XLLP_OST_T *save)
{
OSTCopy(save, regs);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -