OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [or32/] [kernel/] [entry.S] - Rev 1275

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 *  linux/arch/or32/kernel/entry.S
 *
 *  or32 version
 *    author(s): Matjaz Breskvar (phoenix@opencores.org)
 *
 *  changes:
 *  18. 11. 2003: Matjaz Breskvar (phoenix@opencores.org)
 *    initial port to or32 architecture
 *  06. 12. 2003: Matjaz Breskvar (phoenix@opencores.org)
 *    major changes in handling exceptions
 *    physical addresses used only by code in head.S
 *    cleand exception handlers and moved them to entry.S
 *
 * syscall table entries are based on ppc port, so they will probably 
 * need some more cleaning.
 *
 * Stack layout in 'ret_from_system_call':
 *      ptrace needs to have all regs on the stack.
 *      if the order here is changed, it needs to be
 *      updated in fork.c:copy_process, signal.c:do_signal,
 *      ptrace.c and ptrace.h
 *
 * syscall table entries are based on ppc port, so it will probably need
 * some more cleaning.
 */

#include <linux/config.h>
#include <linux/linkage.h>
#include <linux/sys.h>
#include <asm/processor.h>
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/or32_asm.h>
#include <asm/spr_defs.h>

#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/pgtable.h>
        
/* some defines to ease or32 assembly programming */
#include "or32_defs.h"
#include "or32_funcs.S"
        
#define GET_CURRENT(reg,t1)                                     \
        LOAD_SYMBOL_2_GPR(reg,_current_set)                     ;\
        tophys  (t1,reg)                                        ;\
        l.lwz   reg,0(t1)
        
/* =========================================================[ macros ]=== */

#define PUSH_PT_REGS_NO_TRANS                                   \
        l.addi  r1,r1,-(INT_FRAME_SIZE)                         ;\
        l.sw    GPR3(r1),r3                                     ;\
        l.sw    ORIG_GPR3(r1),r3                                ;\
        l.mfspr r3,r0,SPR_EPCR_BASE                             ;\
        l.sw    PC(r1),r3                                       ;\
        l.mfspr r3,r0,SPR_ESR_BASE                              ;\
        l.sw    SR(r1),r3                                       ;\
        l.addi  r3,r1,+(INT_FRAME_SIZE)                         ;\
        l.sw    SP(r1),r3                                       ;\
        l.sw    GPR2(r1),r2                                     ;\
        l.lwz   r3,GPR3(r1)                                     ;\
        l.sw    GPR4(r1),r4                                     ;\
        l.sw    GPR5(r1),r5                                     ;\
        l.sw    GPR6(r1),r6                                     ;\
        l.sw    GPR7(r1),r7                                     ;\
        l.sw    GPR8(r1),r8                                     ;\
        l.sw    GPR9(r1),r9                                     ;\
        l.sw    GPR10(r1),r10                                   ;\
        l.sw    GPR11(r1),r11                                   ;\
        l.sw    GPR12(r1),r12                                   ;\
        l.sw    GPR13(r1),r13                                   ;\
        l.sw    GPR14(r1),r14                                   ;\
        l.sw    GPR15(r1),r15                                   ;\
        l.sw    GPR16(r1),r16                                   ;\
        l.sw    GPR17(r1),r17                                   ;\
        l.sw    GPR18(r1),r18                                   ;\
        l.sw    GPR19(r1),r19                                   ;\
        l.sw    GPR20(r1),r20                                   ;\
        l.sw    GPR21(r1),r21                                   ;\
        l.sw    GPR22(r1),r22                                   ;\
        l.sw    GPR23(r1),r23                                   ;\
        l.sw    GPR24(r1),r24                                   ;\
        l.sw    GPR25(r1),r25                                   ;\
        l.sw    GPR26(r1),r26                                   ;\
        l.sw    GPR27(r1),r27                                   ;\
        l.sw    GPR28(r1),r28                                   ;\
        l.sw    GPR29(r1),r29                                   ;\
        l.sw    GPR30(r1),r30                                   ;\
        l.sw    GPR31(r1),r31                                   ;\
        l.sw    RESULT(r1),r0

        
/*
 * We need to disable interrupts at beginning of RESTORE_ALL
 * since interrupt might come in after we've loaded EPC return address
 * and overwrite EPC with address somewhere in RESTORE_ALL
 * which is of course wrong!
 */
        
#define RESTORE_ALL                                             \
        DISABLE_INTERRUPTS(r3,r4)                               ;\
        l.lwz   r3,PC(r1)                                       ;\
        l.mtspr r0,r3,SPR_EPCR_BASE                             ;\
        l.lwz   r3,SR(r1)                                       ;\
        l.mtspr r0,r3,SPR_ESR_BASE                              ;\
        l.lwz   r2,GPR2(r1)                                     ;\
        l.lwz   r3,GPR3(r1)                                     ;\
        l.lwz   r4,GPR4(r1)                                     ;\
        l.lwz   r5,GPR5(r1)                                     ;\
        l.lwz   r6,GPR6(r1)                                     ;\
        l.lwz   r7,GPR7(r1)                                     ;\
        l.lwz   r8,GPR8(r1)                                     ;\
        l.lwz   r9,GPR9(r1)                                     ;\
        l.lwz   r10,GPR10(r1)                                   ;\
        l.lwz   r11,GPR11(r1)                                   ;\
        l.lwz   r12,GPR12(r1)                                   ;\
        l.lwz   r13,GPR13(r1)                                   ;\
        l.lwz   r14,GPR14(r1)                                   ;\
        l.lwz   r15,GPR15(r1)                                   ;\
        l.lwz   r16,GPR16(r1)                                   ;\
        l.lwz   r17,GPR17(r1)                                   ;\
        l.lwz   r18,GPR18(r1)                                   ;\
        l.lwz   r19,GPR19(r1)                                   ;\
        l.lwz   r20,GPR20(r1)                                   ;\
        l.lwz   r21,GPR21(r1)                                   ;\
        l.lwz   r22,GPR22(r1)                                   ;\
        l.lwz   r23,GPR23(r1)                                   ;\
        l.lwz   r24,GPR24(r1)                                   ;\
        l.lwz   r25,GPR25(r1)                                   ;\
        l.lwz   r26,GPR26(r1)                                   ;\
        l.lwz   r27,GPR27(r1)                                   ;\
        l.lwz   r28,GPR28(r1)                                   ;\
        l.lwz   r29,GPR29(r1)                                   ;\
        l.lwz   r30,GPR30(r1)                                   ;\
        l.lwz   r31,GPR31(r1)                                   ;\      
        l.lwz   r1,SP(r1)                                       ;\      
        l.rfe

#define RESTORE_ALL_NO_R11                                      \
        DISABLE_INTERRUPTS(r3,r4)                               ;\
        l.lwz   r3,PC(r1)                                       ;\
        l.mtspr r0,r3,SPR_EPCR_BASE                             ;\
        l.lwz   r3,SR(r1)                                       ;\
        l.mtspr r0,r3,SPR_ESR_BASE                              ;\
        l.lwz   r2,GPR2(r1)                                     ;\
        l.lwz   r3,GPR3(r1)                                     ;\
        l.lwz   r4,GPR4(r1)                                     ;\
        l.lwz   r5,GPR5(r1)                                     ;\
        l.lwz   r6,GPR6(r1)                                     ;\
        l.lwz   r7,GPR7(r1)                                     ;\
        l.lwz   r8,GPR8(r1)                                     ;\
        l.lwz   r9,GPR9(r1)                                     ;\
        l.lwz   r10,GPR10(r1)                                   ;\
        l.lwz   r12,GPR12(r1)                                   ;\
        l.lwz   r13,GPR13(r1)                                   ;\
        l.lwz   r14,GPR14(r1)                                   ;\
        l.lwz   r15,GPR15(r1)                                   ;\
        l.lwz   r16,GPR16(r1)                                   ;\
        l.lwz   r17,GPR17(r1)                                   ;\
        l.lwz   r18,GPR18(r1)                                   ;\
        l.lwz   r19,GPR19(r1)                                   ;\
        l.lwz   r20,GPR20(r1)                                   ;\
        l.lwz   r21,GPR21(r1)                                   ;\
        l.lwz   r22,GPR22(r1)                                   ;\
        l.lwz   r23,GPR23(r1)                                   ;\
        l.lwz   r24,GPR24(r1)                                   ;\
        l.lwz   r25,GPR25(r1)                                   ;\
        l.lwz   r26,GPR26(r1)                                   ;\
        l.lwz   r27,GPR27(r1)                                   ;\
        l.lwz   r28,GPR28(r1)                                   ;\
        l.lwz   r29,GPR29(r1)                                   ;\
        l.lwz   r30,GPR30(r1)                                   ;\
        l.lwz   r31,GPR31(r1)                                   ;\      
        l.lwz   r1,SP(r1)                                       ;\      
        l.rfe

                
#define EXCEPTION_ENTRY(handler)                                \
        .global handler                                         ;\
handler:                                                        ;\
        /* r1, r2, EPCR, ESR a  already saved */                ;\
        l.sw    GPR3(r1),r3                                     ;\
        l.sw    ORIG_GPR3(r1),r3                                ;\
        l.sw    GPR5(r1),r5                                     ;\
        l.sw    GPR6(r1),r6                                     ;\
        l.sw    GPR7(r1),r7                                     ;\
        l.sw    GPR8(r1),r8                                     ;\
        l.sw    GPR9(r1),r9                                     ;\
        l.sw    GPR10(r1),r10                                   ;\
        l.sw    GPR11(r1),r11                                   ;\
        /* r12,r13 already saved */                             ;\
        l.sw    GPR14(r1),r14                                   ;\
        l.sw    GPR15(r1),r15                                   ;\
        l.sw    GPR16(r1),r16                                   ;\
        l.sw    GPR17(r1),r17                                   ;\
        l.sw    GPR18(r1),r18                                   ;\
        l.sw    GPR19(r1),r19                                   ;\
        l.sw    GPR20(r1),r20                                   ;\
        l.sw    GPR21(r1),r21                                   ;\
        l.sw    GPR22(r1),r22                                   ;\
        l.sw    GPR23(r1),r23                                   ;\
        l.sw    GPR24(r1),r24                                   ;\
        l.sw    GPR25(r1),r25                                   ;\
        l.sw    GPR26(r1),r26                                   ;\
        l.sw    GPR27(r1),r27                                   ;\
        l.sw    GPR28(r1),r28                                   ;\
        l.sw    GPR29(r1),r29                                   ;\
        l.sw    GPR30(r1),r30                                   ;\
        /* r31 already save */                                  ;\
        l.sw    RESULT(r1),r0

#define UNHANDLED_EXCEPTION(handler,vector)                     \
        .global handler                                         ;\
handler:                                                        ;\
        /* r1, r2, EPCR, ESR a  already saved */                ;\
        l.sw    GPR3(r1),r3                                     ;\
        l.sw    ORIG_GPR3(r1),r3                                ;\
        l.sw    GPR5(r1),r5                                     ;\
        l.sw    GPR6(r1),r6                                     ;\
        l.sw    GPR7(r1),r7                                     ;\
        l.sw    GPR8(r1),r8                                     ;\
        l.sw    GPR9(r1),r9                                     ;\
        l.sw    GPR10(r1),r10                                   ;\
        l.sw    GPR11(r1),r11                                   ;\
        /* r12,r13 already saved */                             ;\
        l.sw    GPR14(r1),r14                                   ;\
        l.sw    GPR15(r1),r15                                   ;\
        l.sw    GPR16(r1),r16                                   ;\
        l.sw    GPR17(r1),r17                                   ;\
        l.sw    GPR18(r1),r18                                   ;\
        l.sw    GPR19(r1),r19                                   ;\
        l.sw    GPR20(r1),r20                                   ;\
        l.sw    GPR21(r1),r21                                   ;\
        l.sw    GPR22(r1),r22                                   ;\
        l.sw    GPR23(r1),r23                                   ;\
        l.sw    GPR24(r1),r24                                   ;\
        l.sw    GPR25(r1),r25                                   ;\
        l.sw    GPR26(r1),r26                                   ;\
        l.sw    GPR27(r1),r27                                   ;\
        l.sw    GPR28(r1),r28                                   ;\
        l.sw    GPR29(r1),r29                                   ;\
        l.sw    GPR30(r1),r30                                   ;\
        /* r31 already saved */                                 ;\
        l.sw    RESULT(r1),r0                                   ;\
        l.addi  r3,r1,0                                         ;\
        /* r4 is exception EA */                                ;\
        l.addi  r5,r0,vector                                    ;\
        l.jal   _unhandled_exception                            ;\
        l.nop                                                   ;\
        l.j     _ret_from_exception                             ;\
        l.nop   1
        
/*
 * NOTE: one should never assume that SPR_EPC, SPR_ESR, SPR_EEAR
 *       contain the same values as when exception we're handling
 *       occured. in fact they never do. if you need them use
 *       values saved on stack (for SPR_EPC, SPR_ESR) or content
 *       of r4 (for SPR_EEAR). for details look at EXCEPTION_HANDLE()
 *       in 'arch/or32/kernel/head.S'
 */
        
/* =====================================================[ exceptions] === */

/* ---[ 0x100: RESET exception ]----------------------------------------- */

EXCEPTION_ENTRY(_tng_kernel_start)
        l.jal   _start
        l.nop
        
/* ---[ 0x200: BUS exception ]------------------------------------------- */
        
UNHANDLED_EXCEPTION(_vector_0x200,0x200)

/* ---[ 0x300: Data Page Fault exception ]------------------------------- */

EXCEPTION_ENTRY(_data_page_fault_handler)
        /* set up parameters for do_page_fault */
        l.addi  r3,r1,0                    // pt_regs
        /* r4 set be EXCEPTION_HANDLE */   // effective address of fault
        l.ori   r5,r0,0x300                // exception vector

        /*
         * __PHX__: TODO
         *
         * all this can be written much simpler. look at
         * DTLB miss handler in the CONFIG_GUARD_PROTECTED_CORE part
         */
#ifdef CONFIG_OR32_NO_SPR_SR_DSX
        l.lwz   r6,PC(r3)                  // address of an offending insn
        l.lwz   r6,0(r6)                   // instruction that caused pf

        l.srli  r6,r6,26                   // check opcode for jump insn
        l.sfeqi r6,0                       // l.j
        l.bf    8f
        l.sfeqi r6,1                       // l.jal
        l.bf    8f
        l.sfeqi r6,3                       // l.bnf
        l.bf    8f
        l.sfeqi r6,4                       // l.bf
        l.bf    8f
        l.sfeqi r6,0x11                    // l.jr
        l.bf    8f
        l.sfeqi r6,0x12                    // l.jalr
        l.bf    8f
        
        l.nop

        l.j     9f
        l.nop
8:

        l.lwz   r6,PC(r3)                  // address of an offending insn
        l.addi  r6,r6,4
        l.lwz   r6,0(r6)                   // instruction that caused pf
        l.srli  r6,r6,26                   // get opcode
9:

#else

        l.mfspr r6,r0,SPR_SR               // SR
//      l.lwz   r6,SR(r3)                  // ESR
        l.andi  r6,r6,SPR_SR_DSX           // check for delay slot exception
        l.sfeqi r6,0x1                     // exception happened in delay slot
        l.bnf   7f      
        l.lwz   r6,PC(r3)                  // address of an offending insn
        
        l.addi  r6,r6,4                    // offending insn is in delay slot
7:
        l.lwz   r6,0(r6)                   // instruction that caused pf
        l.srli  r6,r6,26                   // check opcode for write access                     
#endif          

        l.sfgeui r6,0x34                   // check opcode for write access
        l.bnf   1f
        l.sfleui r6,0x37
        l.bnf   1f
        l.ori   r6,r0,0x1                  // write access
        l.j     2f
        l.nop
1:      l.ori   r6,r0,0x0                  // !write access
2:
        
        /* call fault.c handler in or32/mm/fault.c */
        l.jal   _do_page_fault
        l.nop
        l.j     _ret_from_exception
        l.nop
        
/* ---[ 0x400: Insn Page Fault exception ]------------------------------- */

EXCEPTION_ENTRY(_insn_page_fault_handler)       
        /* set up parameters for do_page_fault */
        l.addi  r3,r1,0                    // pt_regs
        /* r4 set be EXCEPTION_HANDLE */   // effective address of fault
        l.ori   r5,r0,0x400                // exception vector
        l.ori   r6,r0,0x0                  // !write access
        
        /* call fault.c handler in or32/mm/fault.c */
        l.jal   _do_page_fault
        l.nop
        l.j     _ret_from_exception
        l.nop

        
/* ---[ 0x500: Timer exception ]----------------------------------------- */

EXCEPTION_ENTRY(_timer_handler)
#ifndef CONFIG_ESR_EXCEPTION_WORKS
        
        l.lwz   r4,SR(r1)               // were interrupts enabled ?
        l.andi  r4,r4,SPR_SR_TEE
        l.sfeqi r4,0
        l.bnf   1f                      // tick irq enabled, all ok.
        l.nop

        l.addi  r1,r1,-0x8
        LOAD_SYMBOL_2_GPR(r3,42f)
        l.sw    0x0(r1),r3
        l.jal   _printk
        l.sw    0x4(r1),r4
        l.addi  r1,r1,0x8

        .section .rodata, "a"
42:     
                .string "\n\rESR interrupt bug: in _timer_handler (ESR %x)\n\r"
                .align 4
        .previous

        l.ori   r4,r4,SPR_SR_TEE        // fix the bug
        l.sw    SR(r1),r4
1:      
#endif
        l.addi r3,r1,0
        LOAD_SYMBOL_2_GPR(r8,_timer_interrupt)
        l.jalr r8
        l.nop
        l.j    _ret_from_intr
        l.nop

/* ---[ 0x600: Aligment exception ]-------------------------------------- */

#if 1
UNHANDLED_EXCEPTION(_vector_0x600,0x600)
#endif
                
#if 0
EXCEPTION_ENTRY(_aligment_handler)
//        l.mfspr r2,r0,SPR_EEAR_BASE     /* Load the efective addres */
        l.addi  r2,r4,0
//        l.mfspr r5,r0,SPR_EPCR_BASE     /* Load the insn address */
        l.lwz   r5,PC(r1)
        
        l.lwz   r3,0(r5)                /* Load insn */
        l.srli  r4,r3,26                /* Shift left to get the insn opcode */

        l.sfeqi r4,0x00                 /* Check if the load/store insn is in delay slot */
        l.bf    jmp
        l.sfeqi r4,0x01
        l.bf    jmp
        l.sfeqi r4,0x03
        l.bf    jmp
        l.sfeqi r4,0x04
        l.bf    jmp
        l.sfeqi r4,0x11
        l.bf    jr
        l.sfeqi r4,0x12
        l.bf    jr
        l.nop
        l.j     1f
        l.addi  r5,r5,4                 /* Increment PC to get return insn address */
        
jmp:
        l.slli  r4,r3,6                 /* Get the signed extended jump length */
        l.srai  r4,r4,4

        l.lwz   r3,4(r5)                /* Load the real load/store insn */

        l.add   r5,r5,r4                /* Calculate jump target address */
        
        l.j     1f
        l.srli  r4,r3,26                /* Shift left to get the insn opcode */

jr:
        l.slli  r4,r3,9                 /* Shift to get the reg nb */
        l.andi  r4,r4,0x7c

        l.lwz   r3,4(r5)                /* Load the real load/store insn */

        l.add   r4,r4,r1                /* Load the jump register value from the stack */
        l.lwz   r5,0(r4)

        l.srli  r4,r3,26                /* Shift left to get the insn opcode */
        
        
1:      
//        l.mtspr r0,r5,SPR_EPCR_BASE
        l.sw    PC(r1),r5
        
        l.sfeqi r4,0x26
        l.bf    lhs
        l.sfeqi r4,0x25
        l.bf    lhz
        l.sfeqi r4,0x22
        l.bf    lws
        l.sfeqi r4,0x21
        l.bf    lwz
        l.sfeqi r4,0x37
        l.bf    sh
        l.sfeqi r4,0x35
        l.bf    sw
        l.nop

1:      l.j     1b                      /* I don't know what to do */
        l.nop

lhs:    l.lbs   r5,0(r2)
        l.slli  r5,r5,8
        l.lbz   r6,1(r2)
        l.or    r5,r5,r6
        l.srli  r4,r3,19
        l.andi  r4,r4,0x7c
        l.add   r4,r4,r1
        l.j     align_end
        l.sw    0(r4),r5        
        
lhz:    l.lbz   r5,0(r2)
        l.slli  r5,r5,8
        l.lbz   r6,1(r2)
        l.or    r5,r5,r6
        l.srli  r4,r3,19
        l.andi  r4,r4,0x7c
        l.add   r4,r4,r1
        l.j     align_end
        l.sw    0(r4),r5        
                
lws:    l.lbs   r5,0(r2)
        l.slli  r5,r5,24
        l.lbz   r6,1(r2)
        l.slli  r6,r6,16
        l.or    r5,r5,r6
        l.lbz   r6,2(r2)
        l.slli  r6,r6,8
        l.or    r5,r5,r6
        l.lbz   r6,3(r2)
        l.or    r5,r5,r6
        l.srli  r4,r3,19
        l.andi  r4,r4,0x7c
        l.add   r4,r4,r1
        l.j     align_end
        l.sw    0(r4),r5        
                
lwz:    l.lbz   r5,0(r2)
        l.slli  r5,r5,24
        l.lbz   r6,1(r2)
        l.slli  r6,r6,16
        l.or    r5,r5,r6
        l.lbz   r6,2(r2)
        l.slli  r6,r6,8
        l.or    r5,r5,r6
        l.lbz   r6,3(r2)
        l.or    r5,r5,r6
        l.srli  r4,r3,19
        l.andi  r4,r4,0x7c
        l.add   r4,r4,r1
        l.j     align_end
        l.sw    0(r4),r5        
                
sh:
        l.srli  r4,r3,9
        l.andi  r4,r4,0x7c
        l.add   r4,r4,r1
        l.lwz   r5,0(r4)        
        l.sb    1(r2),r5
        l.srli  r5,r5,8
        l.j     align_end
        l.sb    0(r2),r5

sw:
        l.srli  r4,r3,9
        l.andi  r4,r4,0x7c
        l.add   r4,r4,r1
        l.lwz   r5,0(r4)        
        l.sb    3(r2),r5
        l.srli  r5,r5,8
        l.sb    2(r2),r5
        l.srli  r5,r5,8
        l.sb    1(r2),r5
        l.srli  r5,r5,8
        l.j     align_end
        l.sb    0(r2),r5

align_end:
        l.j    _ret_from_intr
        l.nop   
#endif  

/* ---[ 0x700: Illegal insn exception ]---------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x700,0x700)

/* ---[ 0x800: External interrupt exception ]---------------------------- */

EXCEPTION_ENTRY(_external_irq_handler)
#ifndef CONFIG_ESR_EXCEPTION_WORKS
        l.lwz   r4,SR(r1)               // were interrupts enabled ?
        l.andi  r4,r4,SPR_SR_IEE
        l.sfeqi r4,0
        l.bnf   1f                      // ext irq enabled, all ok.
        l.nop

        l.addi  r1,r1,-0x8
        LOAD_SYMBOL_2_GPR(r3,42f)
        l.sw    0x0(r1),r3
        l.jal   _printk
        l.sw    0x4(r1),r4
        l.addi  r1,r1,0x8

        .section .rodata, "a"
42:     
                .string "\n\rESR interrupt bug: in _external_irq_handler (ESR %x)\n\r"
                .align 4
        .previous

        l.ori   r4,r4,SPR_SR_IEE        // fix the bug
        l.sw    SR(r1),r4
1:      
#endif
        l.addi r3,r1,0
        LOAD_SYMBOL_2_GPR(r8,_do_IRQ)
        l.jalr r8
        l.nop
        l.j    _ret_from_intr
        l.nop   
        
/* ---[ 0x900: DTLB miss exception ]------------------------------------- */

                
/* ---[ 0xa00: ITLB miss exception ]------------------------------------- */

                
/* ---[ 0xb00: Range exception ]----------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0xb00,0xb00)

/* ---[ 0xc00: Syscall exception ]--------------------------------------- */

EXCEPTION_ENTRY(_sys_call_handler)
        /* r3 is not tainted by EXCEPTION_HANDLE() */
        
        /* r4 holds the EEAR address of the fault, load the original r4 */
        l.lwz   r4,GPR4(r1)

        /* check that userspace didn't try to fool us with 
         * syscall number greater then __NR_syscall. 
         */     
        l.sfgeui r11,NR_syscalls
        l.bnf   10f
        l.nop
        
        l.addi  r1,r1,-0x8
        LOAD_SYMBOL_2_GPR(r3,42f)
        l.sw    0x0(r1),r3
        l.jal   _printk
        l.sw    0x4(r1),r11
        l.addi  r1,r1,0x8

        .section .rodata, "a"
42:     
                .string "\n\rkernel error: SYSCALL_NR out of range (0x%x)\n\r"
                .align 4
        .previous       

        /* let's fix it to the last */
        l.ori   r11,r0,NR_syscalls-1

        
/*
 * __PHX__ i think we don't need this ... till 10:      
 *         if it is, make sure to also fix jump to 10f (a few lines higer up)
 */
                
/*      
        l.sfeqi r11,0x7777              // Special case for 'sys_sigreturn'
        l.bnf   10f
        l.nop
        l.jal   _sys_sigreturn
        l.addi  r8,r1,0
        l.sfgtsi r11,0                  // Check for restarted system call
        l.bf    99f
        l.nop
        l.j     20f
        l.nop
*/
        
10:
        l.movhi r30,hi(_sys_call_table)
        l.ori   r30,r30,lo(_sys_call_table)
        l.slli  r11,r11,2
        l.add   r30,r30,r11
        l.lwz   r30,0(r30)
        l.addi  r8,r1,0                 // regs pointer
        l.jalr  r30
        l.nop
        l.sw    GPR11(r1),r11           // save return value
20:
        l.sw    RESULT(r1),r11          // save result
/*
 *      
 * __PHX__: do we need this ??
 *
        l.sfgesi r11,0
        l.bf    99f
        l.nop
        l.sfeqi r11,-ERESTARTNOHAND
        l.bnf   22f
        l.nop
        l.addi  r11,r0,EINTR
22:
        l.sw    RESULT(r1),r11
*/
                
99:
        l.j     _ret_from_sys_call
        l.addi  r12,r0,0x1              // we came from syscall

/* ---[ 0xd00: Trap exception ]------------------------------------------ */

UNHANDLED_EXCEPTION(_vector_0xd00,0xd00)

/* ---[ 0xe00: Trap exception ]------------------------------------------ */

UNHANDLED_EXCEPTION(_vector_0xe00,0xe00)

/* ---[ 0xf00: Reserved exception ]-------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0xf00,0xf00)

/* ---[ 0x1000: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1000,0x1000)

/* ---[ 0x1100: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1100,0x1100)

/* ---[ 0x1200: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1200,0x1200)

/* ---[ 0x1300: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1300,0x1300)

/* ---[ 0x1400: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1400,0x1400)

/* ---[ 0x1500: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1500,0x1500)

/* ---[ 0x1600: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1600,0x1600)

/* ---[ 0x1700: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1700,0x1700)

/* ---[ 0x1800: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1800,0x1800)

/* ---[ 0x1900: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1900,0x1900)

/* ---[ 0x1a00: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1a00,0x1a00)

/* ---[ 0x1b00: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1b00,0x1b00)

/* ---[ 0x1c00: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1c00,0x1c00)

/* ---[ 0x1d00: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1d00,0x1d00)

/* ---[ 0x1e00: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1e00,0x1e00)

/* ---[ 0x1f00: Reserved exception ]------------------------------------- */

UNHANDLED_EXCEPTION(_vector_0x1f00,0x1f00)

/* ========================================================[ return ] === */

ENTRY(_ret_from_fork)
        l.jal   _schedule_tail
        l.nop
        //
        // __PHX__:     TODO
        // here comes also some ptrace stuff
        //
        l.j     _ret_from_sys_call
        l.nop

ENTRY(_ret_from_sys_call)
        DISABLE_INTERRUPTS(r3,r4)
        /* kernel -> user transition
         * we need to save kernel sp so we can restore it
         * at user -> kernel transition
         */
        LOAD_SYMBOL_2_GPR(r3,_current_set)
        l.lwz   r2,0(r3)
        l.addi  r4,r1,INT_FRAME_SIZE
        l.sw    (THREAD+THREAD_KSP)(r2),r4
        /*
         * if (current->need_resched != 0)
         *     schedule();
         */ 
reschedule:
        l.lwz   r3,NEED_RESCHED(r2)     
        l.sfeqi r3,0
        l.bf    signal_return
        l.nop
        l.jal   _schedule
        l.nop
        l.j     reschedule
        l.nop
        /* 
         * if (current->sigpending != 0)
         *     do_signal(r3,r4);
         */
signal_return:
        /* __PHX__ recheck the right behaviour */
//      ENABLE_INTERRUPTS(r3)
        DISABLE_INTERRUPTS(r3,r4)
        /* r12 is parameter: 1 if we came fro sys_call, else 0 */
        l.lwz   r5,SIGPENDING(r2)       
        l.sfeqi r5,0
        l.bf    _restore_all
        l.addi  r3,r12,0
        l.addi  r4,r0,0
        l.addi  r5,r1,0
        l.jal   _do_signal
        l.nop
        RESTORE_ALL
        
ENTRY(_restore_all)
        // we need to save KSP here too
        // or else fork's 'eat' stack space
        l.addi  r4,r1,INT_FRAME_SIZE
        l.sw    (THREAD+THREAD_KSP)(r2),r4
        RESTORE_ALL
        
ENTRY(_ret_from_intr)
        // i386 version:        
        // GET_CURRENT(%ebx)

ENTRY(_ret_from_exception)
        l.lwz   r4,SR(r1)
        l.andi  r3,r4,SPR_SR_SM
        l.sfeqi r3,0
        l.bnf   _restore_all
        l.nop
        /* 
         * return to usermode
         */             
        l.j     _ret_from_sys_call
        l.nop
        
/* ========================================================[ switch ] === */

/*
 * This routine switches between two different tasks.  The process
 * state of one is saved on its kernel stack.  Then the state
 * of the other is restored from its kernel stack.  The memory
 * management hardware is updated to the second process's state.
 * Finally, we can return to the second process, via the 'return'.
 *
 * Note: there are two ways to get to the "going out" portion
 * of this code; either by coming in via the entry (_switch)
 * or via "fork" which must set up an environment equivalent
 * to the "_switch" path.  If you change this (or in particular, the
 * SAVE_REGS macro), you'll have to change the fork code also.
 */

ENTRY(__switch)
        l.sw    (GPR3-INT_FRAME_SIZE)(r1),r3
        l.mtspr r0,r9,SPR_EPCR_BASE             /* Link register to EPCR */
        l.mfspr r3,r0,SPR_SR                    /* From SR to ESR */
        l.mtspr r0,r3,SPR_ESR_BASE
        l.addi  r11,r2,0                        /* Save old 'current' to 'last' return value*/
        l.lwz   r3,(GPR3-INT_FRAME_SIZE)(r1)
        PUSH_PT_REGS_NO_TRANS
        l.sw    THREAD_KSP(r3),r1               /* Set old stack pointer */
        l.lwz   r1,THREAD_KSP(r4)               /* Load new stack pointer */
        l.addi  r2,r4,-THREAD                   /* set current (r2) to new */
        RESTORE_ALL_NO_R11
                
/* =================================================[ syscall table ] === */
        
        .data
        .align 4
        .global _sys_call_table
_sys_call_table:        
        .long SYMBOL_NAME(_sys_ni_syscall)      /* 0  -  old "setup()" system call */
        .long SYMBOL_NAME(_sys_exit)
        .long SYMBOL_NAME(_sys_fork)
        .long SYMBOL_NAME(_sys_read)
        .long SYMBOL_NAME(_sys_write)
        .long SYMBOL_NAME(_sys_open)            /* 5 */
        .long SYMBOL_NAME(_sys_close)
        .long SYMBOL_NAME(_sys_waitpid)
        .long SYMBOL_NAME(_sys_creat)
        .long SYMBOL_NAME(_sys_link)
        .long SYMBOL_NAME(_sys_unlink)          /* 10 */
        .long SYMBOL_NAME(_sys_execve)
        .long SYMBOL_NAME(_sys_chdir)
        .long SYMBOL_NAME(_sys_time)
        .long SYMBOL_NAME(_sys_mknod)
        .long SYMBOL_NAME(_sys_chmod)           /* 15 */
        .long SYMBOL_NAME(_sys_lchown)
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old break syscall holder */
        .long SYMBOL_NAME(_sys_stat)
        .long SYMBOL_NAME(_sys_lseek)
        .long SYMBOL_NAME(_sys_getpid)          /* 20 */
        .long SYMBOL_NAME(_sys_mount)
        .long SYMBOL_NAME(_sys_oldumount)
        .long SYMBOL_NAME(_sys_setuid)
        .long SYMBOL_NAME(_sys_getuid)
        .long SYMBOL_NAME(_sys_stime)           /* 25 */
        .long SYMBOL_NAME(_sys_ptrace)
        .long SYMBOL_NAME(_sys_alarm)
        .long SYMBOL_NAME(_sys_fstat)
        .long SYMBOL_NAME(_sys_pause)
        .long SYMBOL_NAME(_sys_utime)           /* 30 */
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old stty syscall holder */
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old gtty syscall holder */
        .long SYMBOL_NAME(_sys_access)
        .long SYMBOL_NAME(_sys_nice)
        .long SYMBOL_NAME(_sys_ni_syscall)      /* 35 */        /* old ftime syscall holder */
        .long SYMBOL_NAME(_sys_sync)
        .long SYMBOL_NAME(_sys_kill)
        .long SYMBOL_NAME(_sys_rename)
        .long SYMBOL_NAME(_sys_mkdir)
        .long SYMBOL_NAME(_sys_rmdir)           /* 40 */
        .long SYMBOL_NAME(_sys_dup)
        .long SYMBOL_NAME(_sys_pipe)
        .long SYMBOL_NAME(_sys_times)
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old prof syscall holder */
        .long SYMBOL_NAME(_sys_brk)             /* 45 */
        .long SYMBOL_NAME(_sys_setgid)
        .long SYMBOL_NAME(_sys_getgid)
        .long SYMBOL_NAME(_sys_signal)
        .long SYMBOL_NAME(_sys_geteuid)
        .long SYMBOL_NAME(_sys_getegid)         /* 50 */
        .long SYMBOL_NAME(_sys_acct)
        .long SYMBOL_NAME(_sys_umount)                          /* recycled never used phys() */
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old lock syscall holder */
        .long SYMBOL_NAME(_sys_ioctl)
        .long SYMBOL_NAME(_sys_fcntl)           /* 55 */
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old mpx syscall holder */
        .long SYMBOL_NAME(_sys_setpgid)
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old ulimit syscall holder */
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old _sys_olduname holder */
        .long SYMBOL_NAME(_sys_umask)           /* 60 */
        .long SYMBOL_NAME(_sys_chroot)
        .long SYMBOL_NAME(_sys_ustat)
        .long SYMBOL_NAME(_sys_dup2)
        .long SYMBOL_NAME(_sys_getppid)
        .long SYMBOL_NAME(_sys_getpgrp)         /* 65 */
        .long SYMBOL_NAME(_sys_setsid)
        .long SYMBOL_NAME(_sys_sigaction)
        .long SYMBOL_NAME(_sys_sgetmask)
        .long SYMBOL_NAME(_sys_ssetmask)
        .long SYMBOL_NAME(_sys_setreuid)        /* 70 */
        .long SYMBOL_NAME(_sys_setregid)
        .long SYMBOL_NAME(_sys_sigsuspend)
        .long SYMBOL_NAME(_sys_sigpending)
        .long SYMBOL_NAME(_sys_sethostname)
        .long SYMBOL_NAME(_sys_setrlimit)       /* 75 */
        .long SYMBOL_NAME(_sys_old_getrlimit)
        .long SYMBOL_NAME(_sys_getrusage)
        .long SYMBOL_NAME(_sys_gettimeofday)
        .long SYMBOL_NAME(_sys_settimeofday)
        .long SYMBOL_NAME(_sys_getgroups)       /* 80 */
        .long SYMBOL_NAME(_sys_setgroups)
        .long SYMBOL_NAME(_sys_select)                          /* was old_select */
        .long SYMBOL_NAME(_sys_symlink)
        .long SYMBOL_NAME(_sys_lstat)
        .long SYMBOL_NAME(_sys_readlink)        /* 85 */
        .long SYMBOL_NAME(_sys_uselib)
        .long SYMBOL_NAME(_sys_swapon)
        .long SYMBOL_NAME(_sys_reboot)
        .long SYMBOL_NAME(_old_readdir)
        .long SYMBOL_NAME(_old_mmap)            /* 90 */
        .long SYMBOL_NAME(_sys_munmap)
        .long SYMBOL_NAME(_sys_truncate)
        .long SYMBOL_NAME(_sys_ftruncate)
        .long SYMBOL_NAME(_sys_fchmod)
        .long SYMBOL_NAME(_sys_fchown)          /* 95 */
        .long SYMBOL_NAME(_sys_getpriority)
        .long SYMBOL_NAME(_sys_setpriority)
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old profil syscall holder */
        .long SYMBOL_NAME(_sys_statfs)
        .long SYMBOL_NAME(_sys_fstatfs)         /* 100 */
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* _sys_ioperm in i386 */
        .long SYMBOL_NAME(_sys_socketcall)
        .long SYMBOL_NAME(_sys_syslog)
        .long SYMBOL_NAME(_sys_setitimer)
        .long SYMBOL_NAME(_sys_getitimer)       /* 105 */
        .long SYMBOL_NAME(_sys_newstat)
        .long SYMBOL_NAME(_sys_newlstat)
        .long SYMBOL_NAME(_sys_newfstat)
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* old _sys_uname holder */
        .long SYMBOL_NAME(_sys_ni_syscall)      /* 110 */       /* _sys_iopl in i386 */
        .long SYMBOL_NAME(_sys_vhangup)
        .long SYMBOL_NAME(_sys_ni_syscall)      /* old 'idle' syscall */
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* vm86 in i386 */
        .long SYMBOL_NAME(_sys_wait4)
        .long SYMBOL_NAME(_sys_swapoff)         /* 115 */
        .long SYMBOL_NAME(_sys_sysinfo)
        .long SYMBOL_NAME(_sys_ipc)
        .long SYMBOL_NAME(_sys_fsync)
        .long SYMBOL_NAME(_sys_sigreturn)
        .long SYMBOL_NAME(_sys_clone)           /* 120 */
        .long SYMBOL_NAME(_sys_setdomainname)
        .long SYMBOL_NAME(_sys_newuname)
        .long SYMBOL_NAME(_sys_ni_syscall)
        .long SYMBOL_NAME(_sys_adjtimex)
        .long SYMBOL_NAME(_sys_mprotect)                /* 125 */
        .long SYMBOL_NAME(_sys_sigprocmask)
        .long SYMBOL_NAME(_sys_create_module)
        .long SYMBOL_NAME(_sys_init_module)
        .long SYMBOL_NAME(_sys_delete_module)
        .long SYMBOL_NAME(_sys_get_kernel_syms) /* 130 */
        .long SYMBOL_NAME(_sys_quotactl)
        .long SYMBOL_NAME(_sys_getpgid)
        .long SYMBOL_NAME(_sys_fchdir)
        .long SYMBOL_NAME(_sys_bdflush)
        .long SYMBOL_NAME(_sys_sysfs)           /* 135 */
        .long SYMBOL_NAME(_sys_personality)
        .long SYMBOL_NAME(_sys_ni_syscall)      /* for afs_syscall */
        .long SYMBOL_NAME(_sys_setfsuid)
        .long SYMBOL_NAME(_sys_setfsgid)
        .long SYMBOL_NAME(_sys_llseek)          /* 140 */
        .long SYMBOL_NAME(_sys_getdents)
        .long SYMBOL_NAME(_sys_select)
        .long SYMBOL_NAME(_sys_flock)
        .long SYMBOL_NAME(_sys_msync)
        .long SYMBOL_NAME(_sys_readv)           /* 145 */
        .long SYMBOL_NAME(_sys_writev)
        .long SYMBOL_NAME(_sys_getsid)
        .long SYMBOL_NAME(_sys_fdatasync)
        .long SYMBOL_NAME(_sys_sysctl)
        .long SYMBOL_NAME(_sys_mlock)           /* 150 */
        .long SYMBOL_NAME(_sys_munlock)
        .long SYMBOL_NAME(_sys_mlockall)
        .long SYMBOL_NAME(_sys_munlockall)
        .long SYMBOL_NAME(_sys_sched_setparam)
        .long SYMBOL_NAME(_sys_sched_getparam)  /* 155 */
        .long SYMBOL_NAME(_sys_sched_setscheduler)
        .long SYMBOL_NAME(_sys_sched_getscheduler)
        .long SYMBOL_NAME(_sys_sched_yield)
        .long SYMBOL_NAME(_sys_sched_get_priority_max)
        .long SYMBOL_NAME(_sys_sched_get_priority_min)  /* 160 */
        .long SYMBOL_NAME(_sys_sched_rr_get_interval)
        .long SYMBOL_NAME(_sys_nanosleep)
        .long SYMBOL_NAME(_sys_mremap)
        .long SYMBOL_NAME(_sys_setresuid)
        .long SYMBOL_NAME(_sys_getresuid)       /* 165 */
        .long SYMBOL_NAME(_sys_query_module)
        .long SYMBOL_NAME(_sys_poll)
        .long SYMBOL_NAME(_sys_nfsservctl)
        .long SYMBOL_NAME(_sys_setresgid)
        .long SYMBOL_NAME(_sys_getresgid)       /* 170 */
        .long SYMBOL_NAME(_sys_prctl)
        .long SYMBOL_NAME(_sys_rt_sigreturn)
        .long SYMBOL_NAME(_sys_rt_sigaction)
        .long SYMBOL_NAME(_sys_rt_sigprocmask)  
        .long SYMBOL_NAME(_sys_rt_sigpending)   /* 175 */
        .long SYMBOL_NAME(_sys_rt_sigtimedwait)
        .long SYMBOL_NAME(_sys_rt_sigqueueinfo)
        .long SYMBOL_NAME(_sys_rt_sigsuspend)
        .long SYMBOL_NAME(_sys_pread)
        .long SYMBOL_NAME(_sys_pwrite)          /* 180 */
        .long SYMBOL_NAME(_sys_chown)
        .long SYMBOL_NAME(_sys_getcwd)
        .long SYMBOL_NAME(_sys_capget)
        .long SYMBOL_NAME(_sys_capset)
        .long SYMBOL_NAME(_sys_sigaltstack)     /* 185 */
        .long SYMBOL_NAME(_sys_sendfile)
        .long SYMBOL_NAME(_sys_ni_syscall)      /* streams1 */
        .long SYMBOL_NAME(_sys_ni_syscall)      /* streams2 */
        .long SYMBOL_NAME(_sys_vfork)
        .long SYMBOL_NAME(_sys_getrlimit)       /* 190 */
        .long SYMBOL_NAME(_sys_readahead)
        .long SYMBOL_NAME(_sys_mmap2)
        .long SYMBOL_NAME(_sys_truncate64)
        .long SYMBOL_NAME(_sys_ftruncate64)
        .long SYMBOL_NAME(_sys_stat64)          /* 195 */
        .long SYMBOL_NAME(_sys_lstat64)
        .long SYMBOL_NAME(_sys_fstat64)
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* _sys_pciconfig_read */
        .long SYMBOL_NAME(_sys_ni_syscall)                      /* _sys_pciconfig_write */
        .long SYMBOL_NAME(_sys_ni_syscall)      /* 200 */       /* _sys_pciconfig_iobase */
        .long SYMBOL_NAME(_sys_ni_syscall)      /* 201 - reserved - MacOnLinux - new */
        .long SYMBOL_NAME(_sys_getdents64)
        .long SYMBOL_NAME(_sys_pivot_root)
        .long SYMBOL_NAME(_sys_fcntl64)
        .long SYMBOL_NAME(_sys_madvise)         /* 205 */
        .long SYMBOL_NAME(_sys_mincore)
        .long SYMBOL_NAME(_sys_gettid)
        .long SYMBOL_NAME(_sys_tkill)
        .long SYMBOL_NAME(_sys_setxattr)
        .long SYMBOL_NAME(_sys_lsetxattr)       /* 210 */
        .long SYMBOL_NAME(_sys_fsetxattr)
        .long SYMBOL_NAME(_sys_getxattr)
        .long SYMBOL_NAME(_sys_lgetxattr)
        .long SYMBOL_NAME(_sys_fgetxattr)
        .long SYMBOL_NAME(_sys_listxattr)       /* 215 */
        .long SYMBOL_NAME(_sys_llistxattr)
        .long SYMBOL_NAME(_sys_flistxattr)
        .long SYMBOL_NAME(_sys_removexattr)
        .long SYMBOL_NAME(_sys_lremovexattr)
        .long SYMBOL_NAME(_sys_fremovexattr)    /* 220  */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_futex */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_sched_setaffinity */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_sched_getaffinity */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_security */
        .long SYMBOL_NAME(_sys_ni_syscall)      /* 225  reserved for Tux */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_sendfile64 */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_io_setup */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_io_destroy */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_io_getevents */
        .long SYMBOL_NAME(_sys_ni_syscall)      /* 230  reserved for sys_io_submit */
        .long SYMBOL_NAME(_sys_ni_syscall)      /*      reserved for sys_io_cancel */

        /*
         * NOTE!! This doesn't have to be exact - we just have
         * to make sure we have _enough_ of the "sys_ni_syscall"
         * entries. Don't panic if you notice that this hasn't
         * been shrunk every time we add a new system call.
         */

        .rept NR_syscalls-(.-_sys_call_table)/4
                .long SYMBOL_NAME(_sys_ni_syscall)
        .endr

/* ============================================================[ EOF ]=== */

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.