📄 halboot.si
字号:
#ifndef CYGONCE_HAL_HALBOOT_SI /* -*-asm-*- */#define CYGONCE_HAL_HALBOOT_SI// ====================================================================//// <platform>/halboot.si//// HAL bootup platform-oriented code (assembler)//// ====================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License. You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus. Portions created// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####// ====================================================================//#####DESCRIPTIONBEGIN####//// Author(s): hmt// Contributors: hmt// Date: 1999-02-01// Purpose: Bootup code, platform oriented.// Description:////####DESCRIPTIONEND####//// ====================================================================// External Platform Initial Setup//// This should set up RAM and caches, and calm down any external// interrupt sources.//// It is just plain included in vectors.S//// RAM has not yet been touched at all; in fact all you have is a// register window selected. #ifdef CYG_HAL_STARTUP_RAM ! copy the real instructions into the vector: rd %tbr, %g1 andn %g1, 0xfff, %g1 ! clear non-address bits set real_vector_instructions, %l0 ld [ %l0 ], %l1 st %l1, [ %g1 ] ! into the vector ld [ %l0 + 4 ], %l1 st %l1, [ %g1 + 4 ] ! into the vector ! then invalidate the instruction cache: set 3, %l0 set 0x00001000, %l1 set 0x80001000, %l2 sta %l0, [ %l1 ] 0x0c sta %l0, [ %l2 ] 0x0c ! and the data cache sta %l0, [ %l1 ] 0x0e sta %l0, [ %l2 ] 0x0e nop nop nop nop ! should be enough#endif // CYG_HAL_STARTUP_RAM #include <cyg/hal/hal_cpu.h> // a copy of CygMon~s cpu.h /* Address of clock switch */#define CLKSW_ADDR 0x01000003/* Address of SW1 */#define SW1_ADDR 0x02000003/* Address of LED bank */#define LED_ADDR 0x02000003#define SRAM_BASE 0x30000000#define SRAM_END 0x30080000#define DRAM_BASE 0x04000000 /* base of system DRAM */#define CS3_BASE 0x00000000 /* base of internal resource regs */#define CS3_ASI 7 /* ASI of internal resource regs */// DRAM_BASE2 is defined so that we run the same RAM-sizing code in both// RAM and ROM startup versions; but the RAM startup one starts RAM sizing// at 0x043ff000 ie. 4k down from the top of the 4M available. #ifdef CYG_HAL_STARTUP_RAM#define DRAM_BASE2 DRAM_BASE + 0x00400000 - 0x1000#else#define DRAM_BASE2 DRAM_BASE#endif .macro led val sethi %hi(LED_ADDR),%l7 set \val,%l6 not %l6, %l6 stb %l6,[%l7 + %lo(LED_ADDR)] .endm /* * First, setup chip selects. * * NB: The AMR_VAL macro actually inverts the mask bits. For me, it is * more natural to write a 1 bit where I want the address compared. * The sparc registers use 0 bits, instead. */ /* -CS0 ADDR_MASK:0xfc000000 ASI_MASK:0xfc */ set AMR_VAL(0xfc,0xfc000000),%l0 mov AMR0,%l1 sta %l0,[%l1] 1 /* -CS1 BASE:0x10000000 ASI:4 */ set ARSR_VAL(4,0x10000000),%l0 mov ARSR1,%l1 sta %l0,[%l1] 1 /* -CS1 ADDR MASK:0xf0000000 ASI MASK:0x7 */ set AMR_VAL(7,0xf0000000),%l0 mov AMR1,%l1 sta %l0,[%l1] 1 /* -CS2 BASE:0x20000000 ASI:4 */ set ARSR_VAL(4,0x20000000), %l0 mov ARSR2,%l1 sta %l0,[%l1] 1 /* -CS2 ADDR MASK:0xf0000000 ASI MASK:0x7 */ set AMR_VAL(7,0xf0000000),%l0 mov AMR2,%l1 sta %l0,[%l1] 1 /* -CS3 BASE:CS3_BASE ASI:CS3_ASI */ set ARSR_VAL(CS3_ASI,CS3_BASE),%l0 mov ARSR3,%l1 sta %l0,[%l1] 1 /* -CS3 ADDR MASK:0xffff0000 ASI MASK:0x7 */ set AMR_VAL(7,0xffff0000),%l0 mov AMR3,%l1 sta %l0,[%l1] 1 /* -CS4 BASE: DRAM_BASE ASI:0xb */ set ARSR_VAL(0xb,DRAM_BASE),%l0 mov ARSR4,%l1 sta %l0,[%l1] 1 /* -CS4 ADDR MASK:0xfc000000 ASI MASK:0xfc */ set AMR_VAL(0xfc,0xfc000000),%l0 mov AMR4,%l1 sta %l0,[%l1] 1 /* -CS5 BASE:0x30000000 ASI:0xb */ set ARSR_VAL(0xb,0x30000000),%l0 mov ARSR5,%l1 sta %l0,[%l1] 1 /* -CS5 ADDR MASK:0xfff80000 ASI MASK:0xfc */ set AMR_VAL(0xfc,0xfff80000),%l0 mov AMR5,%l1 sta %l0,[%l1] 1 /* * Setup wait states. Each wait state register sets the wait states for * a pair of chip selects. The lower bits hold the wait state info for * the lower numbered chip select. */ /* -CS0: 5 wait states, -CS1: 7 wait states */// set WSSR_VAL(7,7,WSSR_WAITEN,5,5,WSSR_WAITEN),%l0// set WSSR_VAL(4,4,WSSR_WAITEN,5,5,WSSR_WAITEN),%l0 // FOUR -> CS1 set WSSR_VAL(10,10,WSSR_WAITEN,5,5,WSSR_WAITEN),%l0 // TEN -> CS1 mov WSSR0,%l1 sta %l0,[%l1] 1 /* -CS2: wait states disabled, -CS3: wait states disabled */ set WSSR_VAL(0,0,0,0,0,0),%l0 mov WSSR1,%l1 sta %l0,[%l1] 1 /* -CS4: wait states disabled, -CS5: 0 wait states */ set WSSR_VAL(0,0,WSSR_WAITEN|WSSR_OVERRIDE,0,0,0),%l0 mov WSSR2,%l1 sta %l0,[%l1] 1 led 0x10 /* clear cache/BIU control register */ mov CBIR,%l1 sta %g0,[%l1] 1 /* Read clock switch to determine the value of the refresh timer */ sethi %hi(CLKSW_ADDR),%l1 ldub [%l1 + %lo(CLKSW_ADDR)],%l0 btst 0x80,%l0 bne,a 1f mov 10,%l0 /* force to 10MHz if CLKSW-8 is ON */ 1: umul %l0,15,%l0 mov DRLD,%l1 sta %l0,[%l1] 1 mov REFTMR,%l1 sta %l0,[%l1] 1 /* read SW1 to get DRAM page size */ sethi %hi(SW1_ADDR),%l1 ldub [%l1 + %lo(SW1_ADDR)],%l0 btst 0x10,%l0 be,a 1f mov 0x0e,%l0 /* 1K page if branch taken (SW1-5 is OFF) */ mov 0x06,%l0 /* 2K page (SW1-5 is OFF) */ 1: mov SPGMR,%l1 sta %l0,[%l1] 1 led 0x20#ifdef CYG_HAL_STARTUP_ROM /* Turn on all system services */ mov SSCR_TIMER|SSCR_WAIT|SSCR_CS|SSCR_SAMEPG,%l0 mov SSCR,%l1 sta %l0,[%l1] 1 nop nop nop nop #endif led 0x30 /* * Initialize caches. */ sethi %hi(0x1000),%l0 /* bank 1 invalidate */ sethi %hi(0x80000000),%l1 /* bank 2 invalidate */ mov 3,%l2 /* clear lock, lru, and valid bits */ sta %l2,[%l0] 0xc /* do it - icache bank 1 */ sta %l2,[%l0] 0xe /* do it - dcache bank 1 */ sta %l2,[%l0 + %l1] 0xc /* do it - icache bank 2 */ sta %l2,[%l0 + %l1] 0xe /* do it - dcache bank 2 */ /* now, enable caches and buffers */ mov CBIR_ICEN|CBIR_DCEN|CBIR_PBEN|CBIR_WBEN,%l0 mov CBIR,%l1 sta %l0,[%l1] 1 nop nop nop nop /* enable data and insn bursts */ mov BCR_IBE|BCR_DBE,%l0 mov BCR,%l1 sta %l0,[%l1] 1 nop nop nop nop /* * DRAM setup/test. */ led 0x40 /* * Test SW1-7 to determine normal or EDO mode. * SW1-7 ON = EDO * SW1-7 OFF = Normal. */ sethi %hi(SW1_ADDR),%l1 ldub [%l1 + %lo(SW1_ADDR)],%l7 mov DBANKR_SA04,%l0 /* DRAM starts at 0x04000000 */ btst 0x40,%l7 bne 1f /* branch if SW1-7 is OFF */ mov SSCR_DRAM,%l1 /* EDO DRAM, enable burst in SSCR and EDO in DBANKR */ or %l1,SSCR_BURST,%l1 or %l0,DBANKR_EDO,%l0 1: /* * Now, test SW1 to get DRAM page and bank size. * SW1-5 ON = 2k page, 16MB bank. (up to 64MB total) * SW1-5 OFF = 1k page, 4MB bank. (up to 16MB total) */ btst 0x10,%l7 bne,a 1f /* branch if OFF */ or %l0,DBANKR_4M|DBANKR_CA10,%l0 /* 1K page */ or %l0,DBANKR_16M|DBANKR_CA11,%l0 /* 2K page */ 1: mov CS3_BASE+DBANKR,%l2 sta %l0,[%l2] CS3_ASI mov DTIMR_RPS2|DTIMR_CBR3|DTIMR_CAS2|DTIMR_RP2,%l0 mov CS3_BASE+DTIMR,%l2 sta %l0,[%l2] CS3_ASI mov SSCR,%l2 lda [%l2] 1, %l0 or %l0,%l1,%l0 sta %l0,[%l2] 1 /* * Test SW1 to get potential DRAM limit. * SW1-5 ON = 2k page, up to 64MB total * SW1-5 OFF = 1k page, up to 16MB total */ btst 0x10,%l7 bne,a 1f /* branch if OFF */ sethi %hi(DRAM_BASE + 16*1024*1024),%l0 sethi %hi(DRAM_BASE + 64*1024*1024),%l0 1: /* subtract 4 to get last valid DRAM address */ add %l0,-4,%l0 /* Assume maximim memory and fill with pattern */ set DRAM_BASE2,%l2 set 0xaaaaaaaa,%l3 1: st %l3,[%l2] cmp %l2,%l0 blt 1b add %l2,4,%l2 /* * Go back, read data and compare with written data. * Fill in with zero as we go along. */ set DRAM_BASE2,%l2 1: ld [%l2],%l4 cmp %l4,%l3 bne 2f st %g0,[%l2] cmp %l2,%l0 blt,a 1b add %l2,4,%l2 2: led 0x50 sub %l2,64,%i6 sethi %hi(DRAM_BASE),%l1 sub %l2,%l1,%l0 st %l0,[%i6]// NOTE that here, the frame pointer is set up to the top of RAM minus a// little bit with the size of RAM at %fp (%i6)#ifdef CYG_HAL_STARTUP_ROM led 0x58 ! copy the trampoline code into the base of RAM ! including the two ~rogue~ instructions... .extern .data sethi %hi(.data), %l0 ! get the start of RAM andn %l0, 0xfff, %l0 set rom_vectors, %l1 ! get the start of the trampoline set rom_vectors_end, %l2 ! ...and its end.33: ldd [ %l1 ], %l4 ! also uses %l5 std %l4, [ %l0 ] inc 8, %l1 inc 8, %l0 cmp %l1, %l2 bl 33b nop led 0x59 sethi %hi(.data), %g1 ! get the start of RAM andn %g1, 0xfff, %g1 set real_vector_instructions, %l0 ld [ %l0 ], %l1 st %l1, [ %g1 ] ! into the vector ld [ %l0 + 4 ], %l1 st %l1, [ %g1 + 4 ] ! into the vector led 0x5a ! then invalidate the instruction cache: set 3, %l0 set 0x00001000, %l1 set 0x80001000, %l2 sta %l0, [ %l1 ] 0x0c sta %l0, [ %l2 ] 0x0c led 0x5b ! and the data cache sta %l0, [ %l1 ] 0x0e sta %l0, [ %l2 ] 0x0e nop nop nop nop ! should be enough led 0x5c ! and (re)set the tbr, finally. sethi %hi(.data), %g1 andn %g1, 0xfff, %g1 wr %g1, %tbr ! Traps are at RAM start nop nop nop led 0x5d#else led 0x5f#endif // CYG_HAL_STARTUP_ROM ! turn on caches - copied from the book #define set_size 64#define ini_tag 0#define adr1 0x00000000#define adr2 0x80000000#define step 16#define CTL_BITS 0x35 set set_size, %l7 set adr1, %o1 set adr2, %o2 set ini_tag, %l010: sta %l0, [ %o1 ] 0x0c sta %l0, [ %o1 ] 0x0e sta %l0, [ %o2 ] 0x0c sta %l0, [ %o2 ] 0x0e add %o1, step, %o1 subcc %l7, 1, %l7 bne 10b add %o2, step, %o2 set 0, %l1 set CTL_BITS, %l2 sta %l2, [ %l1 ] 0x01 nop nop nop nop ! delay to let caches stabilize led 0x60 // Now set up the 86940 #define TRGM0 0#define TRGM1 4 #define REQSNS 8#define REQCLR 12#define IMASK 16#define IRLAT 20#define IMODE 24 sethi %hi( 0x10000000 ), %l1 ! base address of the 86940 companion set 0xfffe0000, %l4 ! mask all intrs add %l1, IMASK, %l3 sta %l4, [ %l3 ] 4 set 0x11400000, %l6 ! Channels 14,12,11 into Active Low add %l1, TRGM0, %l3 sta %l6, [ %l3 ] 4 set 0x05100000, %l6 ! Channels 5,4,2 into Active Low add %l1, TRGM1, %l3 sta %l6, [ %l3 ] 4 add %l1, REQCLR, %l3 ! clear all pending intrs sta %l4, [ %l3 ] 4 set 0x00100000, %l6 ! clear the latch add %l1, IRLAT, %l3 sta %l6, [ %l3 ] 4 nop nop nop led 0x70 #endif /* CYGONCE_HAL_HALBOOT_SI *//* EOF halboot.si */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -