⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmgr1110.s

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 S
📖 第 1 页 / 共 2 页
字号:

;      TITLE("SA11X0 Firmware Initialization")
;++
;
; Copyright (c) 1999  Intel Corporation
;
;--

	OPT     2								; disable listing

	INCLUDE kxarm.h
	INCLUDE sa11x0.inc
	INCLUDE sa11x0BD.inc
	INCLUDE sa11x1.inc

	;OPT     128							; disable listing of macro expansions
	OPT     1								; reenable listing

	

;TEST_LCD_DELAY			EQU 1				; Insert 20 ms delay in shutdown
;TEST_DISABLE_INTERRUPT	EQU 1				; Disable interrupts before shutdown
TEST_DISABLE_DMA		EQU 1				; Disable DMA before shutdown
;TEST_DISABLE_LCD		EQU 1				; Disable LCD before shutdown
TEST_EARLY_STOP_CBR		EQU 1				; Stop CBR before cache sweep
TEST_PRESTOP_CBR		EQU 1				; Stop CBR and wait
TEST_DMA_SYNC			EQU 1				; Sync with running DMA
TEST_SW_SHUTDOWN		EQU 1				; Use S/W shutdown method
;TEST_TRACE_GPIO		EQU 1				; Debug only since this is borrowed

TEST_GPIO_BIT			EQU BIT24			; Select the GPIO bit to use for tuning
LCD_DELAY_TIME			EQU 0x1400000		; 20 ms untuned (likely 60 or so).



	TEXTAREA
	LEAF_ENTRY OEMPowerOff
; OEMPowerOff - OFF button handler
;
;      This routine is invoked when the OFF button is pressed. It is responsible
; for any final power off state and putting the cpu into standby.
;
;	Entry	none
;	Exit	none
;	Uses	r0-r3

	mov	pc, lr


	LEAF_ENTRY OEMPowerOffIntel
;
; OEMPowerOff - OFF button handler
;
;   This routine is invoked when the OFF button is pressed. It is responsible
; for any final power off state and putting the cpu into standby.
;
;       Entry   none
;       Exit    none
;
;
; Intel code
;
; In sleep mode the processor core is powered down.  This means that
; we lose processor state (including banked registers), cache contents, etc.
; We count on WinCE to save the User Mode info but walk the other modes
; and save state.
;
; When we are called, the processor is in SVC mode with interrupts off
;

	stmdb   sp!, {r4-r12}                   ; Push SVC state onto our stack
	stmdb   sp!, {lr}



	ldr     r0, =GPIO_BASE_VIRTUAL
	mvn     r1, #0
	str     r1, [r0, #GPCR_OFFSET]         		; turn off all GPIOs

	ldr     r3, =SLEEPDATA_BASE_VIRTUAL             ; base of Sleep mode storage

	ldr     r2, =Awake_address              ; store Virtual return address
	str     r2, [r3], #4

	;mrc    p15, 0, r2, c1, c0              ; load r2 with MMU Control
	mrc     p15, 0, r2, c1, c0, 0           ; load r2 with MMU Control
	ldr     r0, =MMU_CTL_MASK               ; mask off the undefined bits
	bic     r2, r2, r0
	str     r2, [r3], #4                    ; store MMU Control data

	;mrc    p15, 0, r2, c2, c0              ; load r2 with TTB address.
	mrc     p15, 0, r2, c2, c0, 0           ; load r2 with TTB address.
	ldr     r0, =MMU_TTB_MASK               ; mask off the undefined bits
	bic     r2, r2, r0
	str     r2, [r3], #4                    ; store TTB address

	mrc     p15, 0, r2, c3, c0, 0           ; load r2 with domain access control.
	str     r2, [r3], #4                    ; store domain access control

	str     sp, [r3], #4                    ; store SVC stack pointer

	mrs     r2, spsr
	str     r2, [r3], #4                    ; store SVC status register

	mov     r1, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; Enter FIQ mode, no interrupts
	msr     cpsr, r1
	mrs     r2, spsr
	stmia   r3!, {r2, r8-r12, sp, lr}       ; store the FIQ mode registers

	mov     r1, #Mode_ABT:OR:I_Bit:OR:F_Bit ; Enter ABT mode, no interrupts
	msr     cpsr, r1
	mrs		r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the ABT mode Registers

	mov     r1, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; Enter IRQ mode, no interrupts
	msr     cpsr, r1
	mrs     r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the IRQ Mode Registers

	mov     r1, #Mode_UND:OR:I_Bit:OR:F_Bit ; Enter UND mode, no interrupts
	msr     cpsr, r1
	mrs     r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the UND mode Registers

	mov     r1, #Mode_SYS:OR:I_Bit:OR:F_Bit ; Enter SYS mode, no interrupts
	msr     cpsr, r1
	stmia   r3!, {sp, lr}                   ; store the SYS mode Registers

	mov     r1, #Mode_SVC:OR:I_Bit:OR:F_Bit ; Back to SVC mode, no interrupts
	msr     cpsr, r1

	ldr     r0, =GPIO_BASE_VIRTUAL                  ; Store GPIO registers
	ldr     r5, [r0, #GAFR_OFFSET]
	str     r5, [r3], #4

	ldr     r5, [r0, #GFER_OFFSET]
	str     r5, [r3], #4

	ldr     r5, [r0, #GRER_OFFSET]
	str     r5, [r3], #4

	ldr     r0, =OSC_BASE_VIRTUAL
	ldmia   r0!, {r4-r7}                    ; Get OSMR array
	stmia   r3!, {r4-r7}
	ldmia   r0!, {r4-r7}                    ; Get OSCR, OSSR, OWER, OIER
	stmia   r3!, {r4-r7}

                  ldr     r0, =RTC_BASE_VIRTUAL
	ldr     r5, [r0, #RTTR_OFFSET]
	str     r5, [r3], #4

	ldr     r5, [r0, #RTSR_OFFSET]
	str     r5, [r3], #4

	ldr     r1, [r0, #RTSR_OFFSET]
	orr     r1, r1, #(RTC_AL|RTC_HZ)        ; Clear Clock Interrupt Sources
	str     r1, [r0, #RTSR_OFFSET]

	ldr     r0, =IC_BASE_VIRTUAL
	ldr     r5, [r0, #ICMR_OFFSET]
	str     r5, [r3]

	ldr     r1, [r0, #ICMR_OFFSET]
	and     r1, r1, #GPIO_31
	orr     r1, r1, #(GPIO_0 | GPIO_1)      ; Mask all interrupts but GPIO0 & GPIO1 (SW1)
	str     r1, [r0, #ICMR_OFFSET]

	ldr     r0, =PMC_BASE_VIRTUAL
	orr     r1, r1, #GPIO_23        		; DCD wakeup
	;orr    r1, r1, #GPIO_31        		; RTC ALARM wakeup
	str     r1, [r0, #PWER_OFFSET]                 ; Allow GPIO0/GPIO1,DCD,RTC

	and     r1, r1, #(~GPIO_0)              ; DC - Disable rising
											; edge interrupt for ON button.
	ldr     r0, =GPIO_BASE_VIRTUAL

	str     r1, [r0, #GRER_OFFSET]                 ; Enable Rising Edge source


;   mov     r1, #0
	mov     r1, #GPIO_0						; DC - Support ON button falling edge to quick wakeup device

	str     r1, [r0, #GFER_OFFSET]                 ; Falling Edge source setting
	mov     r1, #GPIO_0:OR:GPIO_1			; Clear any pending interrupts on SW1/2
	str     r1, [r0, #GEDR_OFFSET]
	mov     r1, #GPIO_23
	str     r1, [r0, #GEDR_OFFSET]                 ; clear any pending interrupts on DCD

; Is this debug trigger ??
;   mov     r1, #BIT17
;   str     r1, [r0, #GPSR]

	; do Checksum on the Sleepdata

	ldr     r3, =SLEEPDATA_BASE_VIRTUAL				; get pointer to SLEEPDATA
	mov     r2, #0
	ldr     r0, =SLEEPDATA_SIZE				; get size of data structure (in words)
30
	ldr     r1, [r3], #4
	and     r1, r1, #0x1
	mov     r1, r1, LSL #31
	orr     r1, r1, r1, LSR #1
	add     r2, r2, r1
	subs    r0, r0, #1
	bne     %b30

	ldr     r0, =PMC_BASE_VIRTUAL
	str     r2, [r0, #PSPR_OFFSET]					; Store in Power Manager Scratch pad register

	;------------------------------------------------------------------------
	; At this point in the shutdown it is safe to use any registers

  IF :DEF: TEST_TRACE_GPIO
	ldr     r0, =GPIO_BASE_VIRTUAL
	mov     r1, #TEST_GPIO_BIT
	str     r1, [r0, #GPCR_OFFSET]					; Clear the GPIO driver
	ldr		r1, [r0, #GPDR]
	orr     r1, r1, #TEST_GPIO_BIT
	str     r1, [r0, #GPDR_OFFSET]					; Enable GPIO bit as output (should go low)
  ENDIF ; TEST_TRACE_GPIO

  IF :DEF: TEST_EARLY_STOP_CBR
	;------------------------------------------------------------------------
	; Stop CBR refresh now, the SDRAM accesses below will be sufficient
	mov		r1, #MC_BASE_VIRTUAL				; memory controller base
	ldr     r0, [r1, #MDREFR_OFFSET]				; Get MDREFR
	bic		r0, r0, #0xff00					; Clear DRI high
	bic		r0, r0, #0x00f0					;  and low part
	str		r0, [r1, #MDREFR_OFFSET]				;  and save it
  ENDIF ; TEST_EARLY_STOP_CBR

	;------------------------------------------------------------------------
	; Clean dcache. Use a reserved region for single length sweep. This needs
	; to be very fast.
	ldr     r0, =ZBANK_BASE_C_VIRTUAL+CACHE_SIZE		; Address of C=1/B=1 zero space
	ldr     r1, =(CACHE_SIZE / CACHE_LINE)	; 8KB / 32Bytes/blk = 256 blk
40
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	subs    r1, r1, #8
	bne     %b40

	;------------------------------------------------------------------------
	; Clean baby dcache. Use a reserved region as above.
	ldr     r0, =ZBANK_BASE_U_VIRTUAL+512			; Address of C=1/B=0 zero space
	mov     r1, #16							; .5KB / 32Bytes/blk = 16 blk
50
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	ldr     r2, [r0], #CACHE_LINE
	subs    r1, r1, #8
	bne     %b50

	mcr     p15, 0, r0, c7, c10, 4			; drain write buffer

	;------------------------------------------------------------------------
	; At this point all memory and register data is saved in SDRAM. Prepare
	; for final shutdown.
	ldr     r0, =PMC_BASE_VIRTUAL
	mov     r1, #PCFR_OPDE                  ; Sleep mode function setup
	str     r1, [r0, #PCFR_OFFSET]

  IF :DEF: TEST_DISABLE_INTERRUPT
	;------------------------------------------------------------------------
	; Disable all interrupts in case they have been left on. We can't get
	; faulted out of this code. This should not be needed as interrupts are
	; already disbled, but ...
	ldr     r1, =IC_BASE_VIRTUAL
	mov     r2, #0
	str     r2, [r1,#ICMR_OFFSET]
  ENDIF ; TEST_DISABLE_INTERRUPT

  IF :DEF: TEST_DISABLE_DMA
	;------------------------------------------------------------------------
	; Disable all DMA in case they have been left on. Any memory reference
	; will cause the shutdown to fail.
	ldr     r1,=DMA_BASE_U_VIRTUAL
	mov     r2,#1
	str     r2,[r1, #0x08]
	str     r2,[r1, #0x28]
	str     r2,[r1, #0x48]
	str     r2,[r1, #0x68]
	str     r2,[r1, #0x88]
	str     r2,[r1, #0xA8]
  ENDIF ; TEST_DISABLE_DMA

  IF :DEF: TEST_DISABLE_LCD
	;------------------------------------------------------------------------
	; Disable the LCD controller. This *really* needs to be done in the
	;  power handler for the display driver.
  IF :DEF: TEST_TRACE_GPIO
	ldr     r0, =GPIO_BASE_VIRTUAL
	mov		r1, #TEST_GPIO_BIT
	str     r1, [r0, #GPSR_OFFSET]					; Set to mark start (pin pulled high)
  ENDIF ; TEST_TRACE_GPIO
	;------------------------------------------------------------------------
	; We need to stop the LCD as fast as possible. To do so we will drop the LPP
	; to force the end of frame signal ASAP. We then disable the device and wait
	; for LDD.
	ldr		r1,=LCD_BASE_VIRTUAL
	;ldr	r2,[r1,#LCCR2_OFFSET]
	;bic	r2,r2,#255						; Clear LPP - not sure if this is legal,
											; need to check
	;bic	r2,r2,#256						; Clear LPP
	mov		r2,#0							; Clear all counts
	str		r2,[r1,#LCCR2_OFFSET]

	ldr		r2,[r1,#LCCR0_OFFSET]
	bic		r2,r2,#1						; Clear LEN
	str		r2,[r1,#LCCR0_OFFSET]

86	ldr		r2,[r1,#LCSR_OFFSET]
	tst		r2,#1							; Wait for LDD
	bne		%B86

  IF :DEF: TEST_TRACE_GPIO
	mov		r1, #TEST_GPIO_BIT
	str     r1, [r0, #GPCR_OFFSET]				     ; And clear GPIO bit to mark end of window
  ENDIF ; TEST_TRACE_GPIO
  ENDIF ; TEST_DISABLE_LCD

  IF :DEF: TEST_LCD_DELAY
	;------------------------------------------------------------------------
	; This method inserts a delay to allow the last frame to complete
	; naturally. This will prevent any DMA activity during final shutdown
	; but requires an additional 20ms in the shutdown path.
  IF :DEF: TEST_TRACE_GPIO
	ldr     r0, =GPIO_BASE_VIRTUAL
	mov		r1, #TEST_GPIO_BIT
	str     r1, [r0, #GPSR_OFFSET]					; Set to mark start (pin pulled high)
  ENDIF ; TEST_TRACE_GPIO

	mov		r1,#LCD_DELAY_TIME				; Give a bit of time to stop (20ms)
55	subs	r1,r1,#1
	bne		%B55

  IF :DEF: TEST_TRACE_GPIO
	mov		r1, #TEST_GPIO_BIT
	str     r1, [r0, #GPCR_OFFSET]					; And clear GPIO bit to mark end of window
  ENDIF ; TEST_TRACE_GPIO
  ENDIF ; TEST_LCD_DELAY

  IF :DEF: TEST_SW_SHUTDOWN
	;------------------------------------------------------------------------
	; If we are using S/W shutdown go do it now
	b       SelfRefresh
  ELSE
	;------------------------------------------------------------------------
	; If we are using H/W shutdown just hit the force sleep now and we're done
	mov     r1, #PMCR_SLEEPFORCE			; Force sleep entry
	str     r1, [r0, #PMCR_OFFSET]
58
	b       %B58                            ; don't let it fall through
  ENDIF ; TEST_SW_SHUTDOWN

	;------------------------------------------------------------------------
	; Software initiated shutdown sequence. We need to insure that memory activity
	; is stopped and the system put to sleep.
	;
	; No registers need to be preserved since we will never come back.
	;
	ALIGN 32
SelfRefresh
	
	; Set up all data in registers as we can not incur any memory cycles
	; later in the shutdown.

	mov		r1, #MC_BASE_VIRTUAL				; memory controller base

	ldr     r4, [r1, #MSC0_OFFSET]
	ldr     r5, [r1, #MSC1_OFFSET]
	ldr     r6, [r1, #MSC2_OFFSET]
	ldr     r3, =0xfffcfffc					; use to clear RT fields of any VLIO
											; also to clear DE bits in MDCNFG
	and     r4, r3, r4
	and     r5, r3, r5
	and     r6, r3, r6

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -