|  | /* See COPYRIGHT for copyright information. */ | 
|  |  | 
|  | #include <arch/pcr.h> | 
|  | #include <ros/arch/arch.h> | 
|  | #include <ros/memlayout.h> | 
|  | #incldue <arch/mmu.h> | 
|  |  | 
|  | /////////////////////////////////////////////////////////////////// | 
|  | // The kernel (this code) is linked at address 0xFFFFFFFF80000000, | 
|  | // but we tell the bootloader to load it at physical address | 
|  | // 0x00000000, which is the start of extended memory. | 
|  | // (See kernel.ld) | 
|  | /////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | /////////////////////////////////////////////////////////////////// | 
|  | // entry point | 
|  | /////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | #define PCR0 (SR_S | SR_S64 | (1 << (IRQ_IPI + SR_IM_SHIFT))) | 
|  | .text | 
|  |  | 
|  | .global _start | 
|  | _start: | 
|  | // This is the first kernel code that executes; it is run only by core 0. | 
|  |  | 
|  | // set up trap entry point.  this is not a relocated address, as we | 
|  | // do not support trapping before the MMU is set up. | 
|  | la     a6, trap_entry | 
|  | mtpcr  a6, ASM_CR(PCR_EVEC) | 
|  |  | 
|  | // clear IPIs and enable traps | 
|  | mtpcr  zero, ASM_CR(PCR_CLR_IPI) | 
|  | li     a6, PCR0 | 
|  | mtpcr  a6, ASM_CR(PCR_SR) | 
|  |  | 
|  | // core 0? | 
|  | mfpcr  a6, ASM_CR(PCR_COREID) | 
|  | bnez   a6, notcore0 | 
|  |  | 
|  | // terminate frame pointer for backtracing and set up stack | 
|  | li     s0, 0 | 
|  | la     sp, percore_stacks + KSTKSIZE | 
|  | li     a7, KERN_LOAD_ADDR | 
|  | sub    sp, sp, a7 | 
|  |  | 
|  | // get memory size and core count from first two words of memory | 
|  | lw     s0, 0(zero) | 
|  | lw     s1, 4(zero) | 
|  |  | 
|  | // set up initial page mappings | 
|  | move   a0, s0 | 
|  | la     a1, l1pt | 
|  | sub    a1, a1, a7 | 
|  | la     a2, l1pt_boot | 
|  | sub    a2, a2, a7 | 
|  | #ifdef __riscv64 | 
|  | la     a3, l2pt | 
|  | sub    a3, a3, a7 | 
|  | #endif | 
|  | jal    pagetable_init | 
|  | jal    enable_mmu | 
|  |  | 
|  | // relocate stack and call into C code using absolute jump, not pc-relative | 
|  | move   a0, s0 | 
|  | move   a1, s1 | 
|  | la     sp, percore_stacks + KSTKSIZE | 
|  | la     a6, cmain | 
|  | jr     a6 | 
|  |  | 
|  | notcore0: | 
|  | // wait for core 0 to boot | 
|  | la     a8, num_cpus_booted - KERN_LOAD_ADDR | 
|  | 1:lw     a9, 0(a8) | 
|  | beqz   a9, 1b | 
|  |  | 
|  | // if for some reason coreid >= num_cpus, don't boot this core | 
|  | la     a8, num_cpus - KERN_LOAD_ADDR | 
|  | lw     a8, 0(a8) | 
|  | 1:bgeu   a6, a8, 1b | 
|  |  | 
|  | // set up stack: sp = percoore_stacks+(core_id()+1)*KSTKSIZE | 
|  | la     sp, percore_stacks | 
|  | add    a6, a6, 1 | 
|  | sll    a6, a6, KSTKSHIFT | 
|  | add    sp, sp, a6 | 
|  | li     a7, KERN_LOAD_ADDR | 
|  | sub    sp, sp, a7 | 
|  |  | 
|  | jal    enable_mmu | 
|  |  | 
|  | // relocate stack and call into C code | 
|  | li     a7, KERN_LOAD_ADDR | 
|  | add    sp, sp, a7 | 
|  | la     a6, smp_init | 
|  | jr     a6 | 
|  |  | 
|  | enable_mmu: | 
|  | la     a6, l1pt_boot | 
|  | li     a7, KERN_LOAD_ADDR | 
|  | sub    a6, a6, a7 | 
|  | mtpcr  a6, ASM_CR(PCR_PTBR) | 
|  | li     a6, PCR0 | SR_VM | 
|  | mtpcr  a6, ASM_CR(PCR_SR) | 
|  | ret | 
|  |  | 
|  | /////////////////////////////////////////////////////////////////// | 
|  | // boot stack and regular stacks. | 
|  | // (boot stack cannot be in .bss, as .bss is later zereoed by the kernel.) | 
|  | /////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | .data | 
|  | .align  PGSHIFT | 
|  | l1pt_boot: | 
|  | .space  PGSIZE | 
|  | .global l1pt | 
|  | l1pt: | 
|  | .space  PGSIZE | 
|  | l2pt: | 
|  | .space  PGSIZE | 
|  |  | 
|  | .global percore_stacks | 
|  | percore_stacks: | 
|  | .space  KSTKSIZE*MAX_NUM_CPUS |