📄 platform.s
字号:
##=============================================================================
##
## 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 + -