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

📄 target.s

📁 ucos下的driver的抽象层, 有了这一层porting将更容易
💻 S
字号:

	SUBT	PID board description and Semihosted support > pid/target.s
	; ------------------------------------------------------------------
	; ------------------------------------------------------------------

 IF :DEF: OPT
	ASSERT  (listopts_s)
old_opt SETA	{OPT}
	OPT	(opt_off)	; disable listing of include files
 ENDIF

	; ------------------------------------------------------------------

	IF	:LNOT: :DEF: pid_s

		GBLL	pid_s
pid_s	SETL	{TRUE}

	; ------------------------------------------------------------------
	; The "ROMonly" build variable controls whether the system
	; being built supports a system where only ROM is mapped at
	; zero, and RAM cannot be mapped there. i.e. where the ARM
	; vectors are hard-wired in ROM. We create this variable
	; un-conditionally, to ensure that if an attempt is made to
	; define it elsewhere then a build error will occur.
	
		GBLL	ROMonly	; depends on target
ROMonly		SETL	{FALSE}	; {TRUE} if no RAM at zero


	INCLUDE platform.s
	GET	mmumacro.s

	; ------------------------------------------------------------------
	; -- SEMIHOSTED and uHAL Support macros ---------------------------------
	; ------------------------------------------------------------------
	; ------------------------------------------------------------------
	; STEP_ONE
	; --------
	; First instruction.
	; Normally LDR	PC, uHALip_ResetStart
	; If the uHAL application is executing from a different address
	; to the address it was built for (such as a system where 
	; memory management hasn't been turned on yet), the first
	; instruction may _have_ to be a branch relative:
	; B	uHALir_ResetGo

	MACRO
	STEP_ONE
 	LDR	PC, uHALip_ResetStart
	MEND

	; ------------------------------------------------------------------
	; CHECK_PRIMARY_CPU
	; -----------------
	; The Integrator/SDB hardware support multiple headers, however
	; uHAL is not currently multiprocessor aware. If the platform
	; supports multiple CPUs, platform-specific initialisation
	; will be required before this block can be removed.

	MACRO
	CHECK_PRIMARY_CPU
	MEND

	; ------------------------------------------------------------------
	; UNMAPROM
	; --------
	; Provide code to deal with mapping the reset ROM away from zero
	; (if required).

	MACRO
$label  UNMAPROM	$w1,$w2
; The PID maps ROM away from 0 by writing a random word to a specific
; address within the Reset and Wait control area.

	MOV     $w2, #RPCBase
        STR     $w1, [$w2, #RPC_ClearResetMap]
	MEND

	; ------------------------------------------------------------------
	; STARTUPCODE
	; -----------
	; Provide code to deal with the main act of mapping the reset
	; ROM away from zero (if required), and ensuring that the
	; target I/O world is suitably clean before attempting to
	; initialise the rest of Semihosted.
	;
	; NOTE:  do not use r4, that's $pos.
	;
	
	MACRO
$label  STARTUPCODE	$w1, $w2, $pos, $ramsize
	MEND

	; ------------------------------------------------------------------
	; GOTO_ROM
	; --------
	; SEMIHOSTED and uHAL macro to switch from 0 to high alias of ROM.
	; On PID I assume that we are running out of ROM at 0x04000000
	; and that we need to swap to the Normal (re-mapped) address.

	MACRO
	GOTO_ROM	$w1, $w2
        LDR     pc,=uHALip_HiReset
uHALip_HiReset
	UNMAPROM	$w1, $w2
	MEND


; ---------------------------------------------------------------------
; VALIDATE_PROCESSOR
; ------------------
;
; Macro to validate that the software and hardware are compatible.
;
;	MACRO
;	VALIDATE_PROCESSOR	$w1, $w2, $w3
;
;	CHECK_VENDOR	$w1, $w2
;	BNE	%F01
;
;	; Checks to see if the h/w and s/w match.
;	CHECK_CPUID	$w1, $w2
;	BEQ	%F02
;
;	; If we get here then there is a problem.  We will flash the
;	; red LED on the motherboard to indicate this.
;1	LDR	$w3, =INTEGRATOR_RTC_BASE
;	LDR	$w1, [$w3]
;	ANDS	$w1, $w1, #1
;	MOVNE	$w1, #RED_LED
;
;	SET_LEDS $w1, $w2 
;
;	B	%B01
;2
;
;	MEND

	; ------------------------------------------------------------------
	; INIT_RAM
	; --------
	; SEMIHOSTED and uHAL macro to initialise memory on startup. See the calling
	; macros for reasons why this particular register set is used.

	MACRO
	INIT_RAM	$w1,$w2,$w3,$w4,$w5
;	VALIDATE_PROCESSOR	$w1, $w2, $w3

	MEND

	MACRO
$label  SETUPMMU	$tmp1, $size, $tmp2, $tmp3, $tmp4, $tmp5, $offset

	MOV	$tmp1, #4		; DEBUG: 100, R--
	DO_DEBUG	$tmp1, $tmp3

	; Scan for MPU and set up if found
	CHECK_FOR_MPU	$tmp1
	BEQ	%F79

	; ----------------------------------------------------
	; Here lies the MPU memory map for this board. Use it
	; with the offset between physical & virtual TTBs to
	; build a valid page table.
	; To use default memory size, pass in RAM size of zero
	; ----------------------------------------------------
	ldr	$tmp5, =uHAL_MappingTable
	LDR	$offset, =0
	SETUP_MPU	$tmp1, $size, $tmp2, $tmp3, $tmp4, $tmp5, $offset

79
	; Scan for MMU and set up if found
	CHECK_FOR_MMU	$tmp1
	BEQ	%F91

	; ----------------------------------------------------
	; Here lies the MMU memory map for this board. Use it
	; with the offset between physical & virtual TTBs to
	; build a valid page table.
	; To use default memory size, pass in RAM size of zero
	; ----------------------------------------------------
	ldr	$tmp5, =uHAL_AddressTable
	LDR	$offset, =0
	BUILD_PGTABLE	$tmp1, $size, $tmp2, $tmp3, $tmp4, $tmp5, $offset

	LDR	$tmp1, =Level1tab	;TTB address is 2**14 aligned
	WRMMU_TTBase 	 $tmp1		;Initialise Translation Table Base reg.
	LDR	$tmp1, =1
	WRMMU_DAControl $tmp1		;Initialise Domain Access Control

	; ----------------------------------------------------
	; Flush everything and get ready to turn on the MMU
	; ----------------------------------------------------
	WRMMU_FlushTB		 $tmp1	; Flush TB 
	WRCACHE_FlushIDC	 $tmp1	; Flush the Caches 

	NOP				; make sure that the pipe is empty
	NOP
	NOP

91
	MOV			$tmp1, #5		; DEBUG: 101, R-Y
	DO_DEBUG		$tmp1, $tmp3

	MEND

	; ---------------------------------------------------------------------
	; GET_RAMSIZE
	; ---------
	;	$w1 -> minimum guaranteed memory amount
	;	    <- actual memory fitted to machine
	;	$w2, $w3, $w4 are scratch

	MACRO
	GET_RAMSIZE	$w1, $w2, $w3, $w4, $w5
	; first off, do we have any DRAM?
	MOV	$w3,#0xBE000000		; get ourselves a very unlikely number (be so dead!)
	ORR	$w3,$w3,#0x00500000
	ORR	$w3,$w3,#0x0000DE00
	ORR	$w3,$w3,#0x000000AD
	LDR	$w4,[$w1]
	STR	$w3,[$w1]		; store at the base of DRAM
	LDR	$w2,[$w1]
	CMP	$w2,$w3
	BNE	%F01			; 512k is our friend (ie; no DRAM)

	; be paranoid about floating addr lines - try with another value
	STR	$w1,[$w1]
	LDR	$w2,[$w1]
	CMP	$w2,$w1
	BNE	%F01			; was 512k after all ...

	; fairly likely we have RAM there, but how much?
	; $w1 will be test base
	; $w2 will be counter
	; $w3 will be test
	; $w4 will be old contents
	MOV	$w2,$w1
	STR	$w3,[$w1]		; watch for it going to zero
2
	ADD	$w2,$w2,#0x400000	; inc by 4Mb
	CMP	$w2,#0x01000000		; broken 16Mb?
	MOVCS	$w2,#0x01000000
	BCS	%F03
	LDR	$w5,[$w2]		; keep old contents of test location
	STR	$w1,[$w2]		; store some non-besodead value
	LDR	$w3,[$w1]		; see if besodead has been altered
	CMP	$w3,$w1
	STRNE	$w5,[$w2]		; restore old contents
	BNE	%B02
3
	STR	$w4,[$w1]
	MOV	$w1,$w2
	MOV	PC,PC			; skip next instruction
1
	STR	$w4,[$w1]		; restore old value (probably program code)
	MEND

	; ------------------------------------------------------------------
	; INITMMU
	; ----------
	; uHAL macro, calls the core SETUPMMU macro if the MMU is
	; enabled and then sets ICache, DCache & WBuffer as required.
	; On certain system where the target does not have a MMU, then this
	; macro is almost a NOP, since using the ICache & WBuffer on their
	; own is still a big gain.
	;

	MACRO
$label	INITMMU		$tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $tmp6
PIDInitMMU  

 IF :LNOT: :DEF: ENABLE_MMU

ENABLE_MMU	EQU	1		; Semihosted flags not defined in uHAL
CACHE_SUPPORTED	EQU	1

 ENDIF

 IF ENABLE_MMU = 1

	LDR	$tmp2, =uHAL_MEMORY_SIZE	; Pass the top of memory
	SETUPMMU	$tmp1, $tmp2,$tmp3, $tmp4, $tmp5, $tmp6

	; Enable MMU, alignment faults and IC/DC/WB as required
	; 
	LDR	$tmp2, =EnableMMU	; NOTE:  no alignment checks enabled 

 ELSE

	LDR	$tmp2, =0		; No MMU

 ENDIF	; ENABLE_MMU

 IF CACHE_SUPPORTED = 1

    IF ENABLE_MMU = 1

	LDR	$tmp1, =(IC_ON + DC_ON + WB_ON)

    ELSE

	; Cannot use Data Cache without MMU
	LDR	$tmp1, =(IC_ON + WB_ON)

    ENDIF

 ELSE

	; Handy performance boost to be had even if no MMU is available
	;LDR	$tmp1, =(IC_ON + WB_ON)
	LDR	$tmp1, =0

 ENDIF	; CACHE_SUPPORTED

	ORR	$tmp1, $tmp1, $tmp2

 IF {ENDIAN} = "big"

	ORR	$tmp1, $tmp1, #EnableBigEndian

 ENDIF	; BIG_ENDIAN

	WRCP15_Control	$tmp1	; Update control register
	NOP
	NOP
	NOP
	NOP
	MEND

	; ------------------------------------------------------------------
	; INITTIMER
	; ---------
	; Semihosted macro is provided purely as a holder for any code that may
	; be required to initialise a hardware timer as part of the reset
	; sequence. Semihosted does *NOT* make use of any timer resources, so by
	; default this macro should not be required to do anything. However,
	; under exceptional circumstances special code may be required to
	; ensure that Semihosted starts cleanly and that later application
	; specific code can have full control of the timer.

	MACRO
$label  INITTIMER	$w1, $w2
	MEND

	; ------------------------------------------------------------------
	; REVERSE
	; -------
	; Quick word byte-order reversal macro. Handy for endian stuff.

	MACRO
$label  REVERSE	$w1, $w2		; w1:	 D    C    B    A
	EOR	$w2, $w1, $w1, ROR #16	; w2:	D^B, C^A, B^D, A^C
	BIC	$w2, $w2, #0xff0000	; w2:	D^B,  0 , B^D, A^C
	MOV	$w1, $w1, ROR #8	; w1:	 A    D    C    B
	EOR	$w1, $w1, $w2, LSR #8	; w2>>8: 0   D^B   0   B^D

	MEND				; w1:	 A    B    C    D

	; ------------------------------------------------------------------
	; GETSOURCE
	; ---------
	; This Semihosted macro is used to read the current interrupt source
	; activity status for the Semihosted device driver interrupts:

	MACRO
$label  GETSOURCE	$w1, $w2
	;; Find out what caused the interrupt
	MEND

	; ------------------------------------------------------------------
	; READ_INT
	; --------
	; uHAL macro to read which interrupt(s) is active (result in $w1)

	MACRO
$label  READ_INT	$w1, $w2, $w3
        MOV	$w1,#ICBase
	LDR	$w1,[$w1, #IC_IRQStatus]
	MEND

	; ------------------------------------------------------------------
	; CACHE_IBR
	; ---------
	; This Semihosted macro implements an instruction barrier for a range of
	; addresses (i.e. it makes instruction and data memory coherent for
	; this range) .
	; w1 contains the start of the range
	; w2 the next address after the end
	; Note that w1 will be corrupted

	MACRO
$label  CACHE_IBR	$w1, $w2, $temp, $temp2
	MEND

	; ------------------------------------------------------------------
	; Semihosted and uHAL macro to disable interrupts on powerup

	MACRO
$label	DISABLE_INTS	$w1, $w2
        MOV	$w1, #ICBase
	MOV	$w2, #255
	ORR	$w2, $w2, $w2, LSL #8
	STR	$w2, [$w1, #IC_IRQEnableClear]

	MEND

	; ------------------------------------------------------------------
	; uHAL macro to initialise external interrupts and other essential
	; IO on startup when running standalone

	MACRO
$label 	INIT_INTS	$w1, $w2, $w3

 IF :DEF: STANDALONE
	DISABLE_INTS	$w1, $w2
 ENDIF
	MEND


	; ------------------------------------------------------------------
	; macro to set the LEDs to the value given in $w1
	; Variant which writes to numeric display as well as LEDs.

	MACRO
$label 	NSET_LEDS	$w1, $w2, $w3
	SET_LEDS	$w1, $w2, $w3
	MEND


	; ------------------------------------------------------------------
	; macro to set the LEDs to the value given in $w1
	; NOTE: this should be the same as SetLEDs in driver.s

	MACRO
$label 	SET_LEDS	$w1, $w2, $w3
	MEND


	; ------------------------------------------------------------------
	; Macro for debugging without having target-specific code in uHAL

	MACRO
$label 	DO_DEBUG	$w1, $w2, $w3
	NSET_LEDS	$w1, $w2, $w3	; Number + LED lighting on Pid
	MEND

	ENDIF	 ; pid_s

 IF :DEF: OPT
	OPT	(old_opt)	; restore previous listing options
 ENDIF


	END	; EOF target.s

⌨️ 快捷键说明

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