📄 sysalib.s
字号:
/* sysALib.s - Pb1x00 system-dependent assembly routines *//* Copyright 2002 Wind River Systems, Inc. */ .data .globl copyright_wind_river/* * This file has been developed or significantly modified by the * MIPS Center of Excellence Dedicated Engineering Staff. * This notice is as per the MIPS Center of Excellence Master Partner * Agreement, do not remove this notice without checking first with * WR/Platforms MIPS Center of Excellence engineering management. */ /*modification history--------------------01f,05apr05,fhc adopted from pb1500_mips32sf/sysALib.s 01e,14may02,zmm Global au1000 name changes. SPR 77333.01d,06nov01,tlc Commonization. General cleanup.01c,02oct01,agf add sysSetTlbEntry function01b,05sep01,zmm Add LCD display support.01a,18may01,mem written.*//*DESCRIPTIONThis module contains system-dependent routines written in assemblylanguage.This module must be the first specified in the 'ld' command used tobuild the system. The sysInit() routine is the system start-up code.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "sysLib.h"#include "config.h"#include "asm.h"#include "esf.h" /* defines */ /* internals */ .globl sysWait /* wait for keyboard ready */ .globl sysInit /* start of system code */ .globl sysClearTlbEntry /* clear entry in tlb */ .globl sysSetTlbEntry /* set entry in tlb */ .globl sysWbFlush /* flush write buffers */ .globl sysFpaAck /* acknowledge fp unit interrupt */ .globl sysCompareSet .globl sysCompareGet .globl sysWiredSet .globl sysWiredGet .globl sysTimerIntClr /* clear internal timer interrupt */ /* externals */ .extern usrInit /* system initialization routine */ .text/********************************************************************************* sysInit - start after boot** This routine is the system start-up entry point for VxWorks in RAM, the* first code executed after booting. It disables interrupts, sets up the* stack, and jumps to the C routine usrInit() in usrConfig.c.** The initial stack is set to grow down from the address of sysInit(). This* stack is used only by usrInit() and is never used again. Memory for the* stack must be accounted for when determining the system load address.** NOTE: This routine should not be called by the user.** RETURNS: N/A** void sysInit (void) /@ THIS IS NOT A CALLABLE ROUTINE @/**/ .ent sysInitsysInit: /* disable all interrupts */ li t0, SR_CU0 mtc0 t0, C0_SR mtc0 zero, C0_CAUSE /* clear software interrupts */ /* give us as long as possible before a clock interrupt */ li v0,1 mtc0 v0,C0_COUNT mtc0 zero,C0_COMPARE /* set stack to grow down from code, leave room for four parameters */ la sp, sysInit-(4*_RTypeSize) la gp,_gp /* set global ptr from cmplr */ li a0, BOOT_WARM_AUTOBOOT /* push start type arg = WARM_BOOT */ jal usrInit /* never returns - starts up kernel */ li ra, R_VEC /* load prom reset address */ j ra /* just in case */ .end sysInit /********************************************************************************* sysClearTlbEntry - clear translation lookaside buffer entry** This routine clears a specified translation lookaside buffer (TLB)* entry by writing a zero to the virtual page number and valid bit.** RETURNS: N/A** void sysClearTlbEntry * (* int entry* )**/ .ent sysClearTlbEntrysysClearTlbEntry: subu t0, a0, AU_N_TLB_ENTRIES - 1 bgtz t0, invalidEntry /* is my index bad ? */ move t1, a0 /* generate unique tlbhi value */ sll t1, AU_P_ENTRY_SHIFT+1 /* leave Valid bit set to zero */ /* +1 because VPN2 field maps 2 pages */ mtc0 t1,C0_TLBHI /* set tlbhi entry */ mtc0 zero,C0_TLBLO0 /* set valid bit to zero */ mtc0 zero,C0_TLBLO1 /* set valid bit to zero */ mtc0 zero,C0_PAGEMASK /* 4k pages */ mtc0 a0,C0_INX /* set up index for write */ HAZARD_TLB tlbwi /* write entry */ HAZARD_CP_WRITEinvalidEntry: j ra .end sysClearTlbEntry/********************************************************************************* sysSetTlbEntry - set a translation lookaside buffer entry** RETURNS: N/A** STATUS sysSetTlbEntry* (* UINT virtual, /@ 32 bit virtual address @/* UINT physical, /@ upper 23 bits [35:12] of physical address @/* UINT mode /@ bits 28:13 for PageSize; @/ * /@ bits 5:0 for cache mode/enable @/* UINT entry, /@ row of TLB to write to @/* )*/ .ent sysSetTlbEntrysysSetTlbEntry: subu t0, a3, AU_N_TLB_ENTRIES - 1 bgtz t0, 0f /* is the index bad ? */ /* Save the mode bits for setting EntryLo (below) */ and t3, a2, ~TLBLO_PFNMASK /* isolate cache & enable bits */ /* Set the PageSize register */ and t2, a2, TLBLO_PFNMASK /* isolate page size bits */ mtc0 t2, C0_PAGEMASK /* set page size register */ HAZARD_CP_WRITE /* Use the PageSize to compute the PFN bit for EntryLo1 */ or t2, 0x1fff /* set implicit page size bits */ srl t2, 1 /* shift 1 bit to right */ add t2, 1 /* now add 1 to set just the PFN bit */ srl t2, TLBLO_PFNSHIFT /* shift to align to PFN field */ /* Set the EntryLo0/1 registers */ sll t1, a1, TLBLO_PFNSHIFT /* align physical addr to PFN field */ or t1, t3 /* apply cache & enable bits */ mtc0 t1, C0_TLBLO0 /* set tlblo0 entry */ HAZARD_TLB or t1, t2 /* apply PFN bit from above */ mtc0 t1, C0_TLBLO1 /* set tlblo1 entry */ HAZARD_TLB /* Set the EntryHi register */ and t1, a0, TLBHI_VPN2MASK /* isolate bits 31:13 of virt addr */ mtc0 t1, C0_TLBHI /* set tlbhi entry (ASID is always 0) */ mtc0 a3, C0_INX /* set up index for write */ HAZARD_TLB tlbwi /* write entry */ HAZARD_CP_WRITE /* Set the return value */ li v0, OK b 1f0: li v0, ERROR1: j ra .end sysSetTlbEntry/********************************************************************************* sysWiredGet - get the TLB wired register** RETURNS: The value in the CP0 wired register.** int sysWiredGet (void)**/ .ent sysWiredGetsysWiredGet: mfc0 v0,C0_WIRED HAZARD_CP_READ j ra .end sysWiredGet/********************************************************************************* sysWiredSet - set the TLB wired register** RETURNS: N/A** void sysWiredSet (int)**/ .ent sysWiredSetsysWiredSet: mtc0 a0,C0_WIRED HAZARD_CP_WRITE j ra .end sysWiredSet/********************************************************************************* sysCompareSet - set the timer compare register** Care is taken to make sure that no interrupts are missed.** RETURNS: N/A** int sysCompareSet (void)**/ .lcomm softCompare, 4 .ent sysCompareSetsysCompareSet: mfc0 v1,C0_COUNT HAZARD_CP_READ lw v0,softCompare /* return original value */ sw a0,softCompare /* set new value */ subu t0,v1,v0 /* normalise count */ addu t0,10 /* with a margin of error (~20 cycles) */ subu t1,a0,v0 /* normalise compare */ bgeu t0,t1,1f /* counter has passed so don't clear interrupt */ mtc0 a0,C0_COMPARE HAZARD_CP_WRITE1: j ra .end sysCompareSet/********************************************************************************* sysCompareGet - get the timer compare register** Care is taken to make sure that no interrupts are missed.** RETURNS: The value in the compare register.** int sysCompareGet (void)**/ .ent sysCompareGetsysCompareGet: lw v0,softCompare j ra .end sysCompareGet /********************************************************************************* sysWbFlush - flush the write buffer** This routine flushes the write buffers, making certain all subsequent* memory writes have occurred. It is used during critical periods only, e.g.,* after memory-mapped I/O register writes.** RETURNS: N/A** void sysWbFlush (void)* */ .ent sysWbFlushsysWbFlush: sync j ra .end sysWbFlush/********************************************************************************* sysFpaAck - acknowledge a floating point unit interrupt** This routine writes the floating point unit (FPU) status register to* acknowledge the appropriate FPU interrupt. It returns an index to the vector* table.** The au1x00 has no floating point unit, but this routine is left as a* stub.** RETURNS: An interrupt vector.* int sysFpaAck (void)*/ .ent sysFpaAcksysFpaAck: j ra /* return to caller */ .end sysFpaAck/******************************************************************************** sysTimerIntClr - clear the intyerrupt generated by the CPU internal timer** This routine clears the interrupt pending bit ,IP7, of the CAUSE register* using a side effect of writing to the COMPARE register** This routine is loaded into the static interrupt priority table.* It is called by jumping to the address in this table, not by* user calls.** SEE ALSO: sysSetCompare()** void sysTimerIntClr (void)*/ .ent sysTimerIntClrsysTimerIntClr: /* give us as long as possible before a clock interrupt */ li t0, 1 mtc0 t0, C0_COUNT mtc0 zero, C0_COMPARE HAZARD_CP_WRITE j ra /* return */ .end sysTimerIntClr/********************************************************************************* sysWait - wait until the input buffer become empty** wait until the input buffer become empty** RETURNS: N/A* void sysWait (void) */ .ent sysWaitsysWait: j ra .end sysWait #define SYS_COMPARE_SET /* The pb1x00 has a specialized sysCompareSet routine */#define SYS_COMPARE_GET /* The pb1x00 has a specialized sysCompareGet routine */ #include "sysMipsALib.s"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -