| | execute NetBSD kernel | | written by ITOH Yasufumi | public domain | | $NetBSD: execkern.S,v 1.4 2011/02/21 02:31:58 itohy Exp $ #include #include "execkern.h" #define MFP 0x00E88000 /* MFP */ #define MFP_IERA (MFP+0x07) /* (B) interrupt enable reg A */ #define MFP_IERB (MFP+0x09) /* (B) interrupt enable reg B */ #define MFP_RSR (MFP+0x2B) /* (B) USART receiver status reg */ #ifndef SRAM_MEMSZ #define SRAM 0x00ED0000 /* SRAM start addr */ #define SRAM_MEMSZ (SRAM + 8) /* (L) size of main memory */ #endif | a3+0 load address | | a3+4 section #1 image top address | a3+8 section #1 size | a3+12 section #1 gap size | : : | a3+n-12 section #XK_NSEC image top address | a3+n-8 section #XK_NSEC size | a3+n-4 section #XK_NSEC gap size | | a3+n (reserved) (d5) | a3+n+4 bootdev (d6) | a3+n+8 boothowto (d7) | a3+n+12 entry address (absolute address) #ifndef XK_NO_C_INTERFACE .text .even ENTRY_NOPROFILE(exec_kernel) addql #4,%sp moveal %sp@+,%a3 | struct execkern_arg * #endif moveal %a3@+,%a1 | load address movel %a1,%d3 | | copy image | movel #XK_NSEC-1,%d2 Lloop: moveal %a3@+,%a0 | section image address movel %a3@+,%d0 | section size movel %d0,%d1 jbsr copy movel %a3@+,%d0 | section gap jbsr clear dbra %d2,Lloop | stop MFP interrupts (for compatibility) clrb MFP_IERA clrb MFP_IERB clrb MFP_RSR | | execute kernel | start(load_addr, mem_max, kernel_end) | movel %a1,%d0 addql #3,%d0 andib #0xFC,%d0 subl %d3,%d0 movel %d0,%sp@- | arg #3 (end of kernel) movel SRAM_MEMSZ,%sp@- | arg #2 (RAM size from SRAM) movel %d3,%sp@- | arg #1 (load address) #if 0 movel %a3@+,%d5 | (reserved) movel %a3@+,%d6 | boot device movel %a3@+,%d7 | boot howto movel %a3@+,%a0 | entry address #else /* optimized */ moveml %a3@+,%d5-%d7/%a0 #endif | clear unused registers moveq #0,%d0 moveq #0,%d1 moveq #0,%d2 moveq #0,%d3 moveq #0,%d4 moveal %d0,%a1 moveal %d0,%a2 moveal %d0,%a3 moveal %d0,%a4 moveal %d0,%a5 moveal %d0,%a6 jsr %a0@ | execute NetBSD kernel | NOTREACHED | ??? returned from kernel -- issue software reset subal %a1,%a1 moveml 0x00ff0000,#0x0101 | get RESET vectors (%d0: ssp, %a0: pc) moveml #0x0101,%a1@ | put them at 0x00000000 (for Xellent) .long 0x4E7B9801 | movec %a1,%vbr jmp %a0@ | go to reset address | | utility routines | | copy %d0 bytes from higher (%a0) to lower (%a1) address 1: moveb %a0@+,%a1@+ copy: subql #1,%d0 bpls 1b rts | clear %d0 bytes at %a1 | do nothing if %d0 is zero 1: clrb %a1@+ clear: subql #1,%d0 bpls 1b rts