/******************************************************************************** * File : reset.S * Author : Alain Greiner * Date : 15/01/2014 ********************************************************************************* * This is a boot code for a generic multi-clusters / multi-processors * TSAR architecture (up to 256 clusters / up to 4 processors per cluster). * The physical address is 40 bits, and the 8 MSB bits A[39:32] define the * cluster index. * * As we don't want to use the virtual memory, the physical address is * equal to the virtual address (identity mapping) and all processors use * the physical memory bank in cluster 0. Both the reset base address and * the kernel base address can be redefined to use a physical memory bank * smaller than 4 Gbytes. * * There is one XCU iand one MMC per cluster. * All other peripherals (including the boot ROM) are located in cluster 0. * Only two HWI interrupts are supported: * - IRQ_IN[0] IOC * - IRQ_IN[12] MMC * * The boot sequence is the following: * - Each processor initializes the stack pointer ($29) depending on proc_id. * - Each processor initializes the CP0 EBASE register * - Only processor 0 initializes the Interrupt vector. * - Each processor initializes its private XCU mask. * - Each processor initializes the Status Register (SR) * - Each processor jumps to the same main address in kernel mode... ********************************************************************************/ #include "hard_config.h" #include "mips32_registers.h" .section .reset,"ax",@progbits .extern seg_stack_base .extern seg_xcu_base .extern seg_kcode_base .extern _interrupt_vector .extern _ioc_isr .extern _mmc_isr .extern main .globl reset .ent reset .align 2 reset: .set noreorder /* each proc computes proc_id, lpid, cluster_xy */ mfc0 $26, CP0_PROCID andi $26, $26, 0x3FF /* at most 1024 processors */ move $10, $26 /* $10 <= proc_id */ li $27, NB_PROCS_MAX divu $26, $27 mfhi $11 /* $11 <= lpid */ mflo $12 /* $12 <= cluster_xy */ /* each proc initializes stack pointer (64K per processor) */ la $27, seg_stack_base addi $26, $10, 1 /* $26 <= (proc_id + 1) */ sll $26, $26, 16 /* $26 <= (proc_id + 1) * 64K */ addu $29, $27, $26 /* $29 <= seg_stack_base(proc_id) */ /* each proc initializes CP0 EBASE register */ la $26, seg_kcode_base mtc0 $26, CP0_EBASE /* CP0_EBASE <= seg_kcode_base */ /* only proc (0,0,0) initializes interrupt vector */ bne $10, $0, reset_xcu nop la $26, _interrupt_vector /* interrupt vector address */ la $27, _ioc_isr sw $27, 0($26) /* interrupt_vector[0] <= _isr_ioc */ la $27, _mmc_isr sw $27, 48($26) /* interrupt_vector[12] <= _isr_mmc */ reset_xcu: /* only proc (x,y,0) receive IRQs and initialise its private XCU mask */ bne $11, $0, reset_end nop la $26, seg_xcu_base li $27, 0b010010000000 /* offset for MSK_HWI_ENABLE & lpid == 0 */ addu $24, $26, $27 /* $24 <= &MASK */ li $25, 0x00001001 /* IOC: IRQ[0] / MEMC: IRQ[12] */ sw $25, 0($24) /* set MASK */ reset_end: /* initializes SR register */ li $26, 0x0000FF01 mtc0 $26, $12 /* SR <= kernel mode / IRQ enable */ /* jumps to main in kernel mode */ la $26, main jr $26 nop .end reset .set reorder