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

📄 platform.s

📁 开放源码实时操作系统源码.
💻 S
📖 第 1 页 / 共 2 页
字号:
##=============================================================================
##
##	platform.S
##
##	MIPS VRC4372 platform code
##
##=============================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
##
## eCos is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free
## Software Foundation; either version 2 or (at your option) any later version.
##
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
## WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
## for more details.
##
## You should have received a copy of the GNU General Public License along
## with eCos; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## As a special exception, if other files instantiate templates or use macros
## or inline functions from this file, or you compile this file and link it
## with other works to produce a work based on this file, this file does not
## by itself cause the resulting work to be covered by the GNU General Public
## License. However the source code for this file must still be made available
## in accordance with section (3) of the GNU General Public License.
##
## This exception does not invalidate any other reasons why a work based on
## this file might be covered by the GNU General Public License.
##
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
## at http://sources.redhat.com/ecos/ecos-license/
## -------------------------------------------
#####ECOSGPLCOPYRIGHTEND####
##=============================================================================
#######DESCRIPTIONBEGIN####
##
## Author(s): 	nickg
## Contributors:	nickg
## Date:	1999-04-20
## Purpose:	MIPS vrc4372 platform code
## Description:	Platform specific code for VRC4372 board.
##              
##		
##		
##
######DESCRIPTIONEND####
##
##=============================================================================

#include <pkgconf/system.h>	
#include <pkgconf/hal.h>

#ifdef CYGPKG_KERNEL
# include <pkgconf/kernel.h>	
#endif
			
#include <cyg/hal/arch.inc>	

##-----------------------------------------------------------------------------
## ISR springboard.
## This routine decodes the interrupt from the VRC4372 interrupt controller
## and vectors to it.

	# On entry:
	# a0 = MIPS status register interrupt number (1,2 or 3)
	# a1 = ISR data value (= interrupt status reg address)
	# a2 = saved reg dump ptr
	# s0 = saved reg dump ptr
	# s1 = vector table offset
	# s2 = interrupt number
	# a3,v0,v1 etc available for use

	.text
			
hal_isr_springboard:
		
	lw	v0,0(a1)			# v0 = stat reg value

	# The following code implements an ls bit index algorithm similar
	# to that in hal_lsbit_index() in hal_misc.c. 
	negu	v1,v0				# v1 = -v0
	and	v1,v1,v0			# v1 &= v0 [isolate ls bit]
	sll	v0,v1,16			# v0 = v1<<16
	subu	v1,v0,v1			# v1 = v0 - v1
	sll	a0,v1,6				# a0 = v1<<6
	addu	v1,v1,a0			# v1 += a0
	sll	a1,v1,4				# a1 = v1<<4
	addu	v1,v1,a1			# v1 += a1
	la	v0,hal_isr_springboard_table	# v0 = table address
	srl	v1,v1,26			# v1 = v1>>26
	addu	v1,v1,v0			# v1 = table entry address
	lb	a0,0(v1)			# a0 = intc isr number
	
	addi	s2,a0,6				# s2 = eCos isr number
	sll	s1,s2,2				# s1 = isr table index

	la	v1,hal_interrupt_handlers
	addu	v1,v1,s1			# v1 = isr handler address
	lw	v1,0(v1)			# v1 = isr handler

	la	a1,hal_interrupt_data
	addu	a1,a1,s1			# a1 = address of data ptr
	lw	a1,0(a1)			# a1 = data pointer

	move	a0,s2				# pass interrupt number	

	jr	v1				# jump to handler, return is to
						# default vsr already in ra
	nop

hal_isr_springboard_table:	
	.byte  -1,  0,  1, 12,  2,  6,  0, 13
	.byte   3,  0,  7,  0,  0,  0,  0, 14
	.byte  10,  4,  0,  0,  8,  0,  0, 25
	.byte   0,  0,  0,  0,  0, 21, 27, 15
	.byte  31, 11,  5,  0,  0,  0,  0,  0
	.byte   9,  0,  0, 24,  0,  0, 20, 26
	.byte  30,  0,  0,  0,  0, 23,  0, 19
	.byte  29,  0, 22, 18, 28, 17, 16,  0

##-----------------------------------------------------------------------------
## Data Load/Store Bus error VSR
##
## If the VRC4373 tries to access a PCI config space register that does
## not have a real device behind it, it provokes a bus error.
## This is a special bus error VSR that detects when we get a bus error
## from a PCI configuration space access and fixes it up to allow the 
## program to continue.
## This VSR works in conjunction with hal_pci_config_read().
## Essentially, if we get a bus error it checks the EPC value and if it 
## is at the instruction that accesses the PCI bus, in hal_pci_config_read(),
## it skips it and fixes the registers to allow the program to continue.
## None of this would be necessary if the VRC4373 behaved sensibly and
## returned 0xFFFFFFFF for reads from empty device slots like it should.

	.text
	
	.globl	hal_bus_error_vsr	
hal_bus_error_vsr:
	# We come here with everything still in registers and:
	# K0 = vector number (==7*4)
	# K1 = address of this routine

	# Check for special address
	
	la	k1,hal_pci_config_read_load
	mvafc0	k0,epc
	bne	k0,k1,1f
	nop

	# We have a match, skip the offending instruction
	# and put 0xFFFFFFFF into V0.
	# First we must clear the EXL bit so that we can
	# write to EPC.
	mfc0	k1,status		# Get status reg
	la	v0,0xFFFFFFFD		# mask for EXL
	and	k1,v0,k1		# clear EXL
	mtc0	k1,status		# return to CP0
	nop				# let it work
	nop
	nop
	addi	k0,k0,4			# skip offending instruction
	mvatc0	k0,epc			# return to EPC
	nop				# let it work
	nop
	nop
	la	v0,0xFFFFFFFF		# Put 0xFFFFFFFF into v0
	sync				# let everything settle
	eret				# and return
	nop

	# If this is not the special location, we need to continue
	# with the usual bus error handling. Since we no longer have
	# the original VSR table entry, we use the one just before it
	# (for instruction fetch bus error). At present this points
	# to the same error handler.
1:
	la	k1,hal_vsr_table	# Get VSR table
	lw	k1,24(k1)		# Pick another vector to follow
	la	k0,28			# but pretend we are still Bus Error
	jr	k1			# go there
	nop
	
	
##-----------------------------------------------------------------------------
## PCI config space access function
##
## This is the only function that should be used to read data from the PCI
## configuration space data register. It works with the bus error VSR
## above to work around any bus errors provoked by the VRC4373.
	
FUNC_START(hal_pci_config_read)

hal_pci_config_read_load:
        .set noreorder
	lw	v0,0(a0)	# Read the value. If this bus-errors the
				# handler will skip this instruction and
				# put 0xFFFFFFFF into v0.
	jr	ra		# And return
	nop
	
FUNC_END(hal_pci_config_read)
				
	
##-----------------------------------------------------------------------------
## Breakpoint springboard

## The following value has been determined by looking at the code that
## PMON puts in the interrupt vector. Clearly it will be different for
## different versions of PMON. A better approach might be to copy the original
## code out and execute that here. However, there is no guarantee that it is
## position independent. 
			
#define CYGHWR_MIPS_PMON_EXEPTION_ENTRY 0xa0000dd4

	.text
			
	.globl hal_breakpoint_springboard
hal_breakpoint_springboard:

	# We enter here with all of the CPU state still
	# in its registers except:
	# K0 = vector index
	# K1 = address of this function

	la	k0,CYGHWR_MIPS_PMON_EXEPTION_ENTRY
	jr	k0	
	nop				

##-----------------------------------------------------------------------------
## ISR tables.
			
	.extern hal_default_isr
	
	.data

	.globl	hal_interrupt_handlers
hal_interrupt_handlers:
	.long	hal_default_isr
	.long	hal_isr_springboard
	.long	hal_isr_springboard
	.long	hal_isr_springboard
	.long	hal_default_isr
	.long	hal_default_isr

	.rept	32
	.long	hal_default_isr
	.endr
	
	.globl	hal_interrupt_data
hal_interrupt_data:

	.long	0
	.long	CYGHWR_HAL_MIPS_VRC4373_INTC_STAT0
	.long	CYGHWR_HAL_MIPS_VRC4373_INTC_STAT1
	.long	CYGHWR_HAL_MIPS_VRC4373_INTC_STAT2
	.long	0
	.long	0

	.rept	32
	.long	0
	.endr

	.globl	hal_interrupt_objects
hal_interrupt_objects:
	.rept	38
	.long	0
	.endr

	.globl	cyg_hal_interrupt_level
cyg_hal_interrupt_level:
	.rept	38
	.byte	0
	.endr

##-----------------------------------------------------------------------------
## MMU setup.
## Much of this code is taken from the PMON sources, hence it does not fully
## conform to our normal coding conventions.

#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)

## DEFINITIONS FOR THE TLB SUPPORT

#define IO_PHYSICAL_BASE 0x80000000
#define IO_VIRTUAL_BASE  0xc0000000
#define NTLBENTRIES      32 
#define K0BASE           0x80000000
#define TLBLO_G          0x00000001
#define TLBLO_V          0x00000002
#define TLBLO_D          0x00000004
#define TLBPGMASK_MASK   0x01ffe000
#define TLBINX_INXMASK   0x0000003f
#define CFG_C_UNCACHED   2
#define TLBLO_CSHIFT     3
#define TLBLO_PFNSHIFT   6
#define TLBLO_PFNMASK    0x3fffffc0
#define TLBHI_VPN2MASK	0xffffe000
#define TLBHI_VPN2SHIFT	13
#define TLBHI_VPNMASK	0xfffff000
#define TLBHI_VPNSHIFT	12


#define TLBLO_UNCACHED  (CFG_C_UNCACHED<<TLBLO_CSHIFT)
#define PAGE_SIZE       0x01000000
#define PADDR_INC       0x02000000
#define NUMB_PG         8

	.text
	
	.set noreorder
		
	.extern	hal_mmu_setup_return
	
FUNC_START(hal_mmu_setup)

	mtc0	zero,tlbhi
	nop
	li      a0,0
2:
	bal     resettlb
	nop
	addiu   a0,a0,1
	bne     a0,NTLBENTRIES,2b
	nop
	

#define tlblo_even	s0
#define tlblo_odd	s1
#define vaddr           s2
#define paddr0          s3
#define paddr1          s4
#define pmask           s5
#define tmp	        s6
#define ix              k1


	li	ix,0
	li	vaddr,IO_VIRTUAL_BASE
	li	paddr0,IO_PHYSICAL_BASE
loop:

        li	a0,((PAGE_SIZE - 1) << 1)
        li	a1,TLBPGMASK_MASK
        and	pmask, a0,a1

	li	tlblo_even, TLBLO_V | TLBLO_D | TLBLO_G
	li	tlblo_odd, TLBLO_V | TLBLO_D | TLBLO_G
 
	li	tmp,PAGE_SIZE
	addu	paddr1,paddr0,tmp
	li	tmp,TLBHI_VPN2MASK
        and	a1,vaddr,tmp

	li	tmp,TLBLO_PFNSHIFT
	srl	a2,paddr0,tmp
	li	tmp,TLBLO_PFNMASK
	and	a2,a2,tmp
	or	a2,a2,TLBLO_UNCACHED
	or	a2,a2,tlblo_even
	
	li	tmp,TLBLO_PFNSHIFT
	srl	a3,paddr1,tmp
	li	tmp,TLBLO_PFNMASK
	and	a3,a3,tmp
	or	a3,a3,TLBLO_UNCACHED
	or	a3,a3,tlblo_odd


	move	a0,pmask
	or	a0,a0,ix

	bal	map_tlb4000
	nop
	
	addi	ix,ix,1

	li	tmp,PADDR_INC
	addu	vaddr,vaddr,tmp
	addu	paddr0,paddr0,tmp

	li	tmp,NUMB_PG
	bne	ix,tmp,loop
	nop

	# Go back via a jump, not a return
	lar	k0,hal_mmu_setup_return
	jr	k0
	nop
		
FUNC_END(hal_mmu_setup)			


## Invalidate the TLB entry specified by index
##
## resettlb(index) 
##	a0  =  index

⌨️ 快捷键说明

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