📄 sysalib.s
字号:
/* sysALib.s - template for system-dependent assembly routines *//* Copyright 2002 Wind River Systems, Inc. *//*TODO - Remove the template modification history and begin a new history starting with version 01a and growing the history upward with each revision.modification history--------------------01a,21may02,scm written.*//*TODO - Update documentation as necessary.Fill in this file with I/O addresses and related constants for thetemplate BSP. Anything with "template" as a prefix needs to examined and re-named to id the BSP (i.e. iq80321, iq80310, etc.) NOTICEThis template is generic only for the XSCALE.DESCRIPTIONThis module contains the entry code, sysInit(), for VxWorks images that startrunning from RAM, such as 'vxWorks'. These images are loaded into memoryby some external program (e.g., a boot ROM) and then started.The routine sysInit() must come first in the text segment. Its job is to performthe minimal setup needed to call the generic Croutine usrInit() with parameter BOOT_COLD.The routine sysInit() typically masks interrupts in the processor, sets theinitial stack pointer to _sysInit then jumps to usrInit.Most other hardware and device initialization is performed later bysysHwInit().SEE ALSO:.I "ARM Architecture Reference Manual"*/#define _ASMLANGUAGE#include "vxWorks.h"#include "regs.h"#include "arch/arm/arm.h"#include "arch/arm/mmuArmLib.h"#include "arch/arm/excArmLib.h"#include "sysLib.h"#include "config.h" .data .globl VAR(copyright_wind_river) .long VAR(copyright_wind_river) /* internals */ .globl FUNC(sysInit) /* start of system code */ .globl FUNC(sysIntStackSplit) .globl FUNC(sysGetTransTblBase) .globl FUNC(sysWrite16) /* routine to do STRH */ .globl FUNC(sysRead16) /* routine to do LDRH */ .globl FUNC(swap32) /* routine to swap bytes in 32 bit int */ .globl FUNC(swap16) /* routine to swap bytes in 16 bit int */#ifdef LOCAL_MEM_AUTOSIZE .globl FUNC(sysPhysMemSize) /* routine to return auto-sized memory */#endif /* externals */ .extern FUNC(usrInit) /* system initialization routine */ .extern FUNC(vxSvcIntStackBase) /* base of SVC-mode interrupt stack */ .extern FUNC(vxSvcIntStackEnd) /* end of SVC-mode interrupt stack */ .extern FUNC(vxIrqIntStackBase) /* base of IRQ-mode interrupt stack */ .extern FUNC(vxIrqIntStackEnd) /* end of IRQ-mode interrupt stack */#if defined(INCLUDE_HSI_PROBE)/* * Note when debugging, one can create a vxWorks.st image suitable * for visionClick/Probe if one defines INCLUDE_HSI_PROBE, STANDALONE_NET, and * undefines INCLUDE_FLASH... * * One also needs to flush out the DEFAULT_BOOT_LINE for IPs and target name... * * under visionClick/Probe you must convert your vxWorks.st into a "bdx" image... * * I.E.: convert.exe "Z:\wpwr\target\config\ibrh80200\vxWorks.st" -c -m gnu -b -z * * under visionClick/Probe select from menu bar: " TOOLS/CONVERT OBJECT MODULES", * and : * (1) add path to vxWorks.st image, * (2) check "create symbol file for visionClick" * (3) check "create bdx file for RAM download" * */ .globl FUNC(probeInit) /* start of system code under visionClick/Probe */ .globl mcuInit /* set up the memory controller */ .extern FUNC(bcopy) .extern FUNC(bfill)/* TODO - for inclusion, define in template.h */#ifdef INCLUDE_HEX_LED#ifdef SECOND_HEX_LED/* use LSB 7-segment for debug display */#define HEX_DISPLAY_MSB template_7SEG_LED_MSB_REG#define HEX_DISPLAY_LSB template_7SEG_LED_LSB_REG#else/* use MSB 7-segment for debug display */#define HEX_DISPLAY_LSB template_7SEG_LED_LSB_REG#endif#endif#ifdef INCLUDE_HEX_LED/* * Display 'value' on the hex display */#define HEX_DISPLAY_THIS(reg0, reg1, value, addr) \ ldr reg0, =addr ; \ ldr reg1, =value ; \ str reg1, [reg0] ;#endif/* This DELAY macro consumes around 6 cycles per iteration, assuming * the instruction cache is enabled. Given a 600Mhz core clock speed, * each iteration takes 10 nanoseconds. If the core clock speed increases, * be sure to redefine the timing macros appropriately. (It shouldn't * matter if the DELAY macro generates delays that are slightly longer * than intended, but delays that are too short may cause problems.) */#define IMMED1 #1#define DELAY(cycles, reg0) \ ldr reg0, =cycles ; \ subs reg0, reg0, IMMED1 ; \ subne pc, pc, IMMED12 ;#define DELAY_4_CYCLES 0x1#define DELAY_16_CYCLES 0x4 /* Tmrd delay */#define DELAY_64_CYCLES 0x10 /* Trfc delay */#define DELAY_80_NSECS 0x8#define DELAY_200_USECS 0x4f00#define DELAY_2_MSECS 0x31000#define DELAY_MCU_SECS 0x1800000#define DELAY_1_SECS 0x4000000#define DELAY_2_SECS 0xc000000/* On template, for various reasons the MMU should be enabled, always.- Caching Uint requires MMU- The portion of the cache is used as internal data RAM, and since cache unit requires MMU, the MMU should be ON in order to access the internal data RAM.*/#ifdef _DIAB_TOOLPT_ENTRY: .macro base,x,ap,p,d,c,b,total .if total .if total <= 0x40 .long ((base<<20)|(x<<12)|(ap<<10)|(p<<9)|(d<<5)|(c<<3)|(b<<2)|2) PT_ENTRY (base+1),x,ap,p,d,c,b,(total-1) .else .if total <= 0x256 PT_ENTRY base,x,ap,p,d,c,b,0x40 PT_ENTRY (base+0x40),x,ap,p,d,c,b,(total-0x40) .else PT_ENTRY base,x,ap,p,d,c,b,0x256 PT_ENTRY (base+0x256),x,ap,p,d,c,b,(total-0x256) .endif .endif .endif .endm/* Coarse page descriptor contains 14 bits, since it is easy to manipulate * the hex values, here the addr is shifted only by 12 bits, instead of 14bits. * So make sure that bit 11 and 10 are set to correctly in options. * Bit 11 and 10 in options should contain the 2 LSBs from the coarse page address */COARSE_ENTRY: .macro addr,options .long ((addr<<12)|options) .endm/* * Extended Small Page Tables */EX_ENTRY: .macro base,x,ap,c,b,total .if total .if total <= 0x40 .long ((base<<12)|(x<<6)|(ap<<4)|(c<<3)|(b<<2)|3) EX_ENTRY (base+1),x,ap,c,b,(total-1) .else .if total <= 0x256 EX_ENTRY base,x,ap,c,b,0x40 EX_ENTRY (base+0x40),x,ap,c,b,(total-0x40) .else EX_ENTRY base,x,ap,c,b,0x256 EX_ENTRY (base+0x256),x,ap,c,b,(total-0x256) .endif .endif .endif .endmINVALID_ENTRY: .macro total .if total .if total <= 0x40 .long (0) INVALID_ENTRY (total-1) .else .if total <= 0x256 INVALID_ENTRY 0x40 INVALID_ENTRY (total-0x40) .else INVALID_ENTRY 0x256 INVALID_ENTRY (total-0x256) .endif .endif .endif .endm#else /* GNU */.MACRO PT_ENTRY base,x,ap,p,d,c,b,total=0.if \total .if \total <= 0x40 .long (\base << 20) | (\x << 12) | (\ap << 10) | (\p << 9) | (\d << 5) | (\c << 3) | (\b << 2) | 2 PT_ENTRY "(\base+1)",\x,\ap,\p,\d,\c,\b,"(\total-1)" .else .if \total <= 0x256 PT_ENTRY \base,\x,\ap,\p,\d,\c,\b,0x40 PT_ENTRY "(\base+0x40)",\x,\ap,\p,\d,\c,\b,"(\total-0x40)" .else PT_ENTRY \base,\x,\ap,\p,\d,\c,\b,0x256 PT_ENTRY "(\base+0x256)",\x,\ap,\p,\d,\c,\b,"(\total-0x256)" .endif .endif.endif.ENDM/* Coarse page descriptor contains 14 bits, since it is easy to manipulate * the hex values, here the addr is shifted only by 12 bits, instead of 14bits. * So make sure that bit 11 and 10 are set to correctly in options. * Bit 11 and 10 in options should contain the 2 LSBs from the coarse page address */.MACRO COARSE_ENTRY addr=0,options=0 .long ((\addr << 12) | \options).ENDM/* * Extended Small Page Tables */.MACRO EX_ENTRY base,x,ap,c,b,total=0.if \total .if \total <= 0x40 .long (\base << 12) | (\x << 6) | (\ap << 4) | (\c << 3) | (\b << 2) | 3 EX_ENTRY "(\base+1)",\x,\ap,\c,\b,"(\total-1)" .else .if \total <= 0x256 EX_ENTRY \base,\x,\ap,\c,\b,0x40 EX_ENTRY "(\base+0x40)",\x,\ap,\c,\b,"(\total-0x40)" .else EX_ENTRY \base,\x,\ap,\c,\b,0x256 EX_ENTRY "(\base+0x256)",\x,\ap,\c,\b,"(\total-0x256)" .endif .endif.endif.ENDM.MACRO INVALID_ENTRY total=0.if \total .if \total <= 0x40 .long (0) INVALID_ENTRY "(\total-1)" .else .if \total <= 0x256 INVALID_ENTRY 0x40 INVALID_ENTRY "(\total-0x40)" .else INVALID_ENTRY 0x256 INVALID_ENTRY "(\total-0x256)" .endif .endif.endif.ENDM#endif /* _DIAB_TOOL */ .data .align 4_probeInitMmuTable:/********************************************************************************* TRANSLATION TABLE.** This level-one table always contains 4096 entries. Each entry is* one 4-byte word, therefore the table length is 16 kilobytes.*//* TODO - re-define according to template memory map *//* * COARSE_ENTRY addr,options * Virt addr 0x00000000 - 0x000fffff * Pointer to coarse page table t 0x8000. * (1 megabyte entry) */COARSE_ENTRY 0xa0008, 0x00000001/* * PT_ENTRY base,x,ap,p,d,c,b,total * Virt addr 0x00100000 - 0x9fffffff * Read/write, non-cacheable, non-bufferable * Covers ROM space, one megabyte and above * (2558 1 megabyte entries) */PT_ENTRY 0x001,0,3,0,0,0,0,0x9ff/* * PT_ENTRY base,x,ap,p,d,c,b,total * Virt addr 0xa0000000 - 0xfe7fffff * Read/write, cacheable, bufferable, * Covers all of RAM * (1512 1 megabyte entries) */PT_ENTRY 0xa00,0,3,0,0,1,1,0x5e8/* * PT_ENTRY base,x,ap,p,d,c,b,total * Virt addr 0xfe800000 - 0xffffffff * Read/write, non-cacheable, non-bufferable. * Covers 80321 MMRs, UART, CPLD, etc. * (24 1 megabyte entries) */PT_ENTRY 0xfe8,0,3,0,0,0,0,0x18/********************************************************************************* SECOND LEVEL TRANSLATION TABLE.** This coarse second-level table contains 256 entries, each entry mapping* 4k of memory (small page). Each entry occupies one 4-byte word, therefore* the table length is 1 kilobyte.*//* TODO - re-define according to template memory map *//* * EX_ENTRY base,x,ap,c,b,total * Virt addr 0x00000000 - 0x00000fff * Physical address 0xa0000000 * Read/write, cacheable, bufferable * Maps 4k of physical RAM down into * first 4k of virtual address space. */EX_ENTRY 0xa0000,0,3,1,1,1/* * EX_ENTRY base,x,ap,c,b,total * Virt addr 0x00001000 - 0x000fffff * Read/write, cacheable, bufferable. * Covers rest of first megabyte of ROM. */EX_ENTRY 0x1,0,3,1,1,255 .text .align 4/********************************************************************************* sysInit/probeInit - (stand alone debug version with visionProbe) * - 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* sysInit () /@ THIS IS NOT A CALLABLE ROUTINE @/*/_ARM_FUNCTION(probeInit)_ARM_FUNCTION(sysInit)/* closely follows first half of romInit *//*** Disable Write Buffer Coalescing ***/ mcr p15, 0, r0, c7, c10, 4 /* Drain write/fill buffers */ CPWAIT (r0) /* wait for the write to happen */ CPWAIT (r0) /* wait for the write to happen */ mrc p15, 0, r0, c1, c0, 1 /* Read Auxiliary Control Reg */ orr r0, r0, #0x00000001 /* Disable Coalescing */ mcr p15, 0, r0, c1, c0, 1 /* Write Auxiliary Control Reg */ CPWAIT (r0) /* wait for the write to happen *//* Set core clock multiplier to x9, *//* For CCLK=66MHz, frequency=600MHz */ mov r0, #0x07 mcr p14, 0, r0, c6, c0, 0 CPWAIT (r0)/* Enable access to all Coprocessors */ ldr r0, =0x3fff mcr p15, 0, r0, c15, c1, 0 CPWAIT (r0) /* Wait */ mcr p15, 0, r0, c7, c10, 4 /* Drain write/fill buffers */ CPWAIT (r0) /* wait for the write to happen *//* Disable Interrupts */ mrs r1, cpsr /* get current status */ orr r1, r1, #I_BIT | F_BIT /* disable IRQ and FIQ */ msr cpsr, r1/* Interrupts Disabled */ ldr r0, =template_MASK_ALL_INT mcr p6, 0, r0, c0, c0, 0 /* Write Interrupt Control (INTCTL) Register */ adr sp, FUNC(probeInit) /* initialise stack pointer */ mov fp, #0 /* initialise frame pointer *//* Invalidate I-Cache, D-Cache, and BTB */ mcr p15, 0, r0, c7, c7, 0 CPWAIT (r0) /* Wait *//* Drain Write/Fill buffer. */ mcr p15, 0, r0, c7, c10, 4 CPWAIT (r0)/* Clear Low Memory */ ldr r0, =LOCAL_MEM_LOCAL_ADRS ldr r1, =FUNC(probeInit) sub r1, r1, r0 sub r1, r1, #64 mov r2, #0 bl FUNC(bfill)/* Copy Initial MMU Tables to Low Memory */ ldr r0, =_probeInitMmuTable ldr r1, =(LOCAL_MEM_LOCAL_ADRS + MMU_TRANSLATION_BASE) ldr r2, =0x4400 bl FUNC(bcopy)/* * TODO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -