#include <linux/init.h>
#include <linux/pgtable.h>
#include <linux/linkage.h>
#include <asm/reg.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/cputable.h>
#include <asm/cache.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/ptrace.h>
#include <asm/bug.h>
#include <asm/kvm_book3s_asm.h>
#include <asm/feature-fixups.h>
#include <asm/interrupt.h>
#include "head_32.h"
#define LOAD_BAT(n, reg, RA, RB) \
\
li RA,0; \
mtspr SPRN_IBAT##n##U,RA; \
mtspr SPRN_DBAT##n##U,RA; \
lwz RA,(n*16)+0(reg); \
lwz RB,(n*16)+4(reg); \
mtspr SPRN_IBAT##n##U,RA; \
mtspr SPRN_IBAT##n##L,RB; \
lwz RA,(n*16)+8(reg); \
lwz RB,(n*16)+12(reg); \
mtspr SPRN_DBAT##n##U,RA; \
mtspr SPRN_DBAT##n##L,RB
__HEAD
_GLOBAL(_stext);
_GLOBAL(_start);
nop
nop
nop
.globl __start
__start:
cmpwi 0,r5,0
beq 1f
#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
bcl 20,31,$+4
0: mflr r8
addis r8,r8,(_stext - 0b)@ha
addi r8,r8,(_stext - 0b)@l
bl prom_init
#endif
trap
#ifdef CONFIG_PPC_PMAC
1: lis r31,0x426f
ori r31,r31,0x6f58
cmpw 0,r3,r31
bne 1f
bl bootx_init
trap
#endif
1: mr r31,r3
li r24,0
bl early_init
bl mmu_off
__after_mmu_off:
bl clear_bats
bl flush_tlbs
bl initial_bats
bl load_segment_registers
bl reloc_offset
bl early_hash_table
#if defined(CONFIG_BOOTX_TEXT)
bl setup_disp_bat
#endif
#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
bl setup_cpm_bat
#endif
#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
bl setup_usbgecko_bat
#endif
bl reloc_offset
li r24,0
bl call_setup_cpu
bl reloc_offset
bl init_idle_6xx
bl reloc_offset
mr r26,r3
addis r4,r3,KERNELBASE@h
lis r5,PHYSICAL_START@h
cmplw 0,r4,r5
bne relocate_kernel
turn_on_mmu:
mfmsr r0
ori r0,r0,MSR_DR|MSR_IR|MSR_RI
mtspr SPRN_SRR1,r0
lis r0,start_here@h
ori r0,r0,start_here@l
mtspr SPRN_SRR0,r0
rfi
. = 0xc0
li r3,1
.globl __secondary_hold
__secondary_hold:
stw r3,__secondary_hold_acknowledge@l(0)
#ifdef CONFIG_SMP
100: lwz r4,0(0)
cmpw 0,r4,r3
bne 100b
mr r24,r3
b __secondary_start
#else
b .
#endif
.globl __secondary_hold_spinloop
__secondary_hold_spinloop:
.long 0
.globl __secondary_hold_acknowledge
__secondary_hold_acknowledge:
.long -1
EXCEPTION(INTERRUPT_SYSTEM_RESET, Reset, unknown_async_exception)
START_EXCEPTION(INTERRUPT_MACHINE_CHECK, MachineCheck)
EXCEPTION_PROLOG_0
#ifdef CONFIG_PPC_CHRP
mtspr SPRN_SPRG_SCRATCH2,r1
mfspr r1, SPRN_SPRG_THREAD
lwz r1, RTAS_SP(r1)
cmpwi cr1, r1, 0
bne cr1, 7f
mfspr r1, SPRN_SPRG_SCRATCH2
#endif
EXCEPTION_PROLOG_1
7: EXCEPTION_PROLOG_2 0x200 MachineCheck
#ifdef CONFIG_PPC_CHRP
beq cr1, 1f
twi 31, 0, 0
#endif
1: prepare_transfer_to_handler
bl machine_check_exception
b interrupt_return
START_EXCEPTION(INTERRUPT_DATA_STORAGE, DataAccess)
#ifdef CONFIG_PPC_BOOK3S_604
BEGIN_MMU_FTR_SECTION
mtspr SPRN_SPRG_SCRATCH2,r10
mfspr r10, SPRN_SPRG_THREAD
stw r11, THR11(r10)
mfspr r10, SPRN_DSISR
mfcr r11
andis. r10, r10, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h
mfspr r10, SPRN_SPRG_THREAD
beq hash_page_dsi
.Lhash_page_dsi_cont:
mtcr r11
lwz r11, THR11(r10)
mfspr r10, SPRN_SPRG_SCRATCH2
MMU_FTR_SECTION_ELSE
b 1f
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
#endif
1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1
EXCEPTION_PROLOG_1
EXCEPTION_PROLOG_2 INTERRUPT_DATA_STORAGE DataAccess handle_dar_dsisr=1
prepare_transfer_to_handler
lwz r5, _DSISR(r1)
andis. r0, r5, DSISR_DABRMATCH@h
bne- 1f
bl do_page_fault
b interrupt_return
1: bl do_break
REST_NVGPRS(r1)
b interrupt_return
START_EXCEPTION(INTERRUPT_INST_STORAGE, InstructionAccess)
mtspr SPRN_SPRG_SCRATCH0,r10
mtspr SPRN_SPRG_SCRATCH1,r11
mfspr r10, SPRN_SPRG_THREAD
mfspr r11, SPRN_SRR0
stw r11, SRR0(r10)
mfspr r11, SPRN_SRR1
stw r11, SRR1(r10)
mfcr r10
#ifdef CONFIG_PPC_BOOK3S_604
BEGIN_MMU_FTR_SECTION
andis. r11, r11, SRR1_ISI_NOPT@h
bne hash_page_isi
.Lhash_page_isi_cont:
mfspr r11, SPRN_SRR1
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
#endif
andi. r11, r11, MSR_PR
EXCEPTION_PROLOG_1
EXCEPTION_PROLOG_2 INTERRUPT_INST_STORAGE InstructionAccess
andis. r5,r9,DSISR_SRR1_MATCH_32S@h
stw r5, _DSISR(r11)
stw r12, _DAR(r11)
prepare_transfer_to_handler
bl do_page_fault
b interrupt_return
EXCEPTION(INTERRUPT_EXTERNAL, HardwareInterrupt, do_IRQ)
START_EXCEPTION(INTERRUPT_ALIGNMENT, Alignment)
EXCEPTION_PROLOG INTERRUPT_ALIGNMENT Alignment handle_dar_dsisr=1
prepare_transfer_to_handler
bl alignment_exception
REST_NVGPRS(r1)
b interrupt_return
START_EXCEPTION(INTERRUPT_PROGRAM, ProgramCheck)
EXCEPTION_PROLOG INTERRUPT_PROGRAM ProgramCheck
prepare_transfer_to_handler
bl program_check_exception
REST_NVGPRS(r1)
b interrupt_return
START_EXCEPTION(0x800, FPUnavailable)
#ifdef CONFIG_PPC_FPU
BEGIN_FTR_SECTION
b ProgramCheck
END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE)
EXCEPTION_PROLOG INTERRUPT_FP_UNAVAIL FPUnavailable
beq 1f
bl load_up_fpu
b fast_exception_return
1: prepare_transfer_to_handler
bl kernel_fp_unavailable_exception
b interrupt_return
#else
b ProgramCheck
#endif
EXCEPTION(INTERRUPT_DECREMENTER, Decrementer, timer_interrupt)
EXCEPTION(0xa00, Trap_0a, unknown_exception)
EXCEPTION(0xb00, Trap_0b, unknown_exception)
START_EXCEPTION(INTERRUPT_SYSCALL, SystemCall)
SYSCALL_ENTRY INTERRUPT_SYSCALL
EXCEPTION(INTERRUPT_TRACE, SingleStep, single_step_exception)
EXCEPTION(0xe00, Trap_0e, unknown_exception)
START_EXCEPTION(INTERRUPT_PERFMON, PerformanceMonitorTrap)
b PerformanceMonitor
START_EXCEPTION(INTERRUPT_ALTIVEC_UNAVAIL, AltiVecUnavailableTrap)
b AltiVecUnavailable
__HEAD
. = INTERRUPT_INST_TLB_MISS_603
InstructionTLBMiss:
mfspr r0,SPRN_IMISS
mfspr r2, SPRN_SDR1
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
rlwinm r2, r2, 28, 0xfffff000
rlwimi r2,r0,12,20,29
lwz r2,0(r2)
#ifdef CONFIG_EXECMEM
rlwinm r3, r0, 4, 0xf
subi r3, r3, NUM_USER_SEGMENTS
#endif
rlwinm. r2,r2,0,0,19
beq- InstructionAddressInvalid
rlwimi r2,r0,22,20,29
lwz r2,0(r2)
andc. r1,r1,r2
bne- InstructionAddressInvalid
#ifdef CONFIG_EXECMEM
rlwimi r2, r3, 1, 31, 31
#endif
ori r1, r1, 0xe06
andc r1, r2, r1
BEGIN_FTR_SECTION
rlwinm r1,r1,0,~_PAGE_COHERENT
END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
mtspr SPRN_RPA,r1
tlbli r0
mfspr r3,SPRN_SRR1
mtcrf 0x80,r3
rfi
InstructionAddressInvalid:
mfspr r3,SPRN_SRR1
rlwinm r1,r3,9,6,6
addis r1,r1,0x2000
mtspr SPRN_DSISR,r1
andi. r2,r3,0xFFFF
or r2,r2,r1
mtspr SPRN_SRR1,r2
mfspr r1,SPRN_IMISS
rlwinm. r2,r2,0,31,31
rlwimi r2,r2,1,30,30
xor r1,r1,r2
mtspr SPRN_DAR,r1
mfmsr r0
xoris r0,r0,MSR_TGPR>>16
mtcrf 0x80,r3
mtmsr r0
b InstructionAccess
. = INTERRUPT_DATA_LOAD_TLB_MISS_603
DataLoadTLBMiss:
mfspr r0,SPRN_DMISS
mfspr r2, SPRN_SDR1
rlwinm r1, r2, 28, 0xfffff000
rlwimi r1,r0,12,20,29
lwz r2,0(r1)
rlwinm r3, r0, 4, 0xf
rlwinm. r2,r2,0,0,19
subi r3, r3, NUM_USER_SEGMENTS
beq- 2f
1: rlwimi r2,r0,22,20,29
lwz r2,0(r2)
li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_READ
andc. r1,r1,r2
bne- DataAddressInvalid
rlwinm r1,r2,32-9,30,30
rlwimi r2,r3,2,30,31
rlwimi r1,r2,32-3,24,24
xori r1,r1,_PAGE_DIRTY
ori r1,r1,0xe04
andc r1,r2,r1
BEGIN_FTR_SECTION
rlwinm r1,r1,0,~_PAGE_COHERENT
END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
mtspr SPRN_RPA,r1
BEGIN_MMU_FTR_SECTION
li r3,1
mfspr r1,SPRN_SPRG_603_LRU
rlwinm r2,r0,20,27,31
slw r3,r3,r2
xor r1,r3,r1
srw r3,r1,r2
mtspr SPRN_SPRG_603_LRU,r1
mfspr r2,SPRN_SRR1
rlwimi r2,r3,31-14,14,14
mtspr SPRN_SRR1,r2
mtcrf 0x80,r2
tlbld r0
rfi
MMU_FTR_SECTION_ELSE
mfspr r2,SPRN_SRR1
mtcrf 0x80,r2
tlbld r0
rfi
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
2: lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l
rlwimi r2,r0,12,20,29
lwz r2,0(r2)
cmpwi cr0,r2,0
beq- DataAddressInvalid
stw r2,0(r1)
rlwinm. r2,r2,0,0,19
b 1b
DataAddressInvalid:
mfspr r3,SPRN_SRR1
rlwinm r1,r3,9,6,6
addis r1,r1,0x2000
mtspr SPRN_DSISR,r1
andi. r2,r3,0xFFFF
mtspr SPRN_SRR1,r2
mfspr r1,SPRN_DMISS
rlwinm. r2,r2,0,31,31
beq 20f
xori r1,r1,3
20: mtspr SPRN_DAR,r1
mfmsr r0
xoris r0,r0,MSR_TGPR>>16
mtcrf 0x80,r3
mtmsr r0
b DataAccess
. = INTERRUPT_DATA_STORE_TLB_MISS_603
DataStoreTLBMiss:
mfspr r0,SPRN_DMISS
mfspr r2, SPRN_SDR1
rlwinm r1, r2, 28, 0xfffff000
rlwimi r1,r0,12,20,29
lwz r2,0(r1)
rlwinm r3, r0, 4, 0xf
rlwinm. r2,r2,0,0,19
subi r3, r3, NUM_USER_SEGMENTS
beq- 2f
1:
rlwimi r2,r0,22,20,29
lwz r2,0(r2)
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
andc. r1,r1,r2
bne- DataAddressInvalid
rlwimi r2,r3,1,31,31
li r1,0xe06
andc r1,r2,r1
BEGIN_FTR_SECTION
rlwinm r1,r1,0,~_PAGE_COHERENT
END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
mtspr SPRN_RPA,r1
mfspr r2,SPRN_SRR1
mtcrf 0x80,r2
BEGIN_MMU_FTR_SECTION
li r3,1
mfspr r1,SPRN_SPRG_603_LRU
rlwinm r2,r0,20,27,31
slw r3,r3,r2
xor r1,r3,r1
srw r3,r1,r2
mtspr SPRN_SPRG_603_LRU,r1
mfspr r2,SPRN_SRR1
rlwimi r2,r3,31-14,14,14
mtspr SPRN_SRR1,r2
mtcrf 0x80,r2
tlbld r0
rfi
MMU_FTR_SECTION_ELSE
mfspr r2,SPRN_SRR1
mtcrf 0x80,r2
tlbld r0
rfi
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
2: lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l
rlwimi r2,r0,12,20,29
lwz r2,0(r2)
cmpwi cr0,r2,0
beq- DataAddressInvalid
stw r2,0(r1)
rlwinm r2,r2,0,0,19
b 1b
#ifndef CONFIG_ALTIVEC
#define altivec_assist_exception unknown_exception
#endif
#ifndef CONFIG_TAU_INT
#define TAUException unknown_async_exception
#endif
EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception)
EXCEPTION(0x1400, SMI, SMIException)
EXCEPTION(0x1500, Trap_15, unknown_exception)
EXCEPTION(0x1600, Trap_16, altivec_assist_exception)
EXCEPTION(0x1700, Trap_17, TAUException)
EXCEPTION(0x1800, Trap_18, unknown_exception)
EXCEPTION(0x1900, Trap_19, unknown_exception)
EXCEPTION(0x1a00, Trap_1a, unknown_exception)
EXCEPTION(0x1b00, Trap_1b, unknown_exception)
EXCEPTION(0x1c00, Trap_1c, unknown_exception)
EXCEPTION(0x1d00, Trap_1d, unknown_exception)
EXCEPTION(0x1e00, Trap_1e, unknown_exception)
EXCEPTION(0x1f00, Trap_1f, unknown_exception)
EXCEPTION(0x2000, RunMode, RunModeException)
EXCEPTION(0x2100, Trap_21, unknown_exception)
EXCEPTION(0x2200, Trap_22, unknown_exception)
EXCEPTION(0x2300, Trap_23, unknown_exception)
EXCEPTION(0x2400, Trap_24, unknown_exception)
EXCEPTION(0x2500, Trap_25, unknown_exception)
EXCEPTION(0x2600, Trap_26, unknown_exception)
EXCEPTION(0x2700, Trap_27, unknown_exception)
EXCEPTION(0x2800, Trap_28, unknown_exception)
EXCEPTION(0x2900, Trap_29, unknown_exception)
EXCEPTION(0x2a00, Trap_2a, unknown_exception)
EXCEPTION(0x2b00, Trap_2b, unknown_exception)
EXCEPTION(0x2c00, Trap_2c, unknown_exception)
EXCEPTION(0x2d00, Trap_2d, unknown_exception)
EXCEPTION(0x2e00, Trap_2e, unknown_exception)
EXCEPTION(0x2f00, Trap_2f, unknown_exception)
__HEAD
. = 0x3000
#ifdef CONFIG_PPC_BOOK3S_604
.macro save_regs_thread thread
stw r0, THR0(\thread)
stw r3, THR3(\thread)
stw r4, THR4(\thread)
stw r5, THR5(\thread)
stw r6, THR6(\thread)
stw r8, THR8(\thread)
stw r9, THR9(\thread)
mflr r0
stw r0, THLR(\thread)
mfctr r0
stw r0, THCTR(\thread)
.endm
.macro restore_regs_thread thread
lwz r0, THLR(\thread)
mtlr r0
lwz r0, THCTR(\thread)
mtctr r0
lwz r0, THR0(\thread)
lwz r3, THR3(\thread)
lwz r4, THR4(\thread)
lwz r5, THR5(\thread)
lwz r6, THR6(\thread)
lwz r8, THR8(\thread)
lwz r9, THR9(\thread)
.endm
hash_page_dsi:
save_regs_thread r10
mfdsisr r3
mfdar r4
mfsrr0 r5
mfsrr1 r9
rlwinm r3, r3, 32 - 15, _PAGE_WRITE
ori r3, r3, _PAGE_PRESENT | _PAGE_READ
bl hash_page
mfspr r10, SPRN_SPRG_THREAD
restore_regs_thread r10
b .Lhash_page_dsi_cont
hash_page_isi:
mr r11, r10
mfspr r10, SPRN_SPRG_THREAD
save_regs_thread r10
li r3, _PAGE_PRESENT | _PAGE_EXEC
lwz r4, SRR0(r10)
lwz r9, SRR1(r10)
bl hash_page
mfspr r10, SPRN_SPRG_THREAD
restore_regs_thread r10
mr r10, r11
b .Lhash_page_isi_cont
.globl fast_hash_page_return
fast_hash_page_return:
andis. r10, r9, SRR1_ISI_NOPT@h
mfspr r10, SPRN_SPRG_THREAD
restore_regs_thread r10
bne 1f
mtcr r11
lwz r11, THR11(r10)
mfspr r10, SPRN_SPRG_SCRATCH2
rfi
1:
mtcr r11
mfspr r11, SPRN_SPRG_SCRATCH1
mfspr r10, SPRN_SPRG_SCRATCH0
rfi
#endif
#ifdef CONFIG_VMAP_STACK
vmap_stack_overflow_exception
#endif
__HEAD
AltiVecUnavailable:
EXCEPTION_PROLOG 0xf20 AltiVecUnavailable
#ifdef CONFIG_ALTIVEC
beq 1f
bl load_up_altivec
b fast_exception_return
#endif
1: prepare_transfer_to_handler
bl altivec_unavailable_exception
b interrupt_return
__HEAD
PerformanceMonitor:
EXCEPTION_PROLOG 0xf00 PerformanceMonitor
prepare_transfer_to_handler
bl performance_monitor_exception
b interrupt_return
__HEAD
relocate_kernel:
lis r3,PHYSICAL_START@h
li r6,0
li r5,0x4000
bl copy_and_flush
addi r0,r3,4f@l
mtctr r0
bctr
4: lis r5,_end-KERNELBASE@h
ori r5,r5,_end-KERNELBASE@l
bl copy_and_flush
b turn_on_mmu
_GLOBAL(copy_and_flush)
addi r5,r5,-4
addi r6,r6,-4
4: li r0,L1_CACHE_BYTES/4
mtctr r0
3: addi r6,r6,4
lwzx r0,r6,r4
stwx r0,r6,r3
bdnz 3b
dcbst r6,r3
sync
icbi r6,r3
cmplw 0,r6,r5
blt 4b
sync
isync
addi r5,r5,4
addi r6,r6,4
blr
#ifdef CONFIG_SMP
.globl __secondary_start_mpc86xx
__secondary_start_mpc86xx:
mfspr r3, SPRN_PIR
stw r3, __secondary_hold_acknowledge@l(0)
mr r24, r3
b __secondary_start
.globl __secondary_start_pmac_0
__secondary_start_pmac_0:
li r24,0
b 1f
li r24,1
b 1f
li r24,2
b 1f
li r24,3
1:
mfmsr r0
rlwinm r0,r0,0,28,26
mtmsr r0
isync
.globl __secondary_start
__secondary_start:
bl __restore_cpu_setup
lis r3,-KERNELBASE@h
mr r4,r24
bl call_setup_cpu
lis r3,-KERNELBASE@h
bl init_idle_6xx
lis r2,secondary_current@ha
tophys(r2,r2)
lwz r2,secondary_current@l(r2)
tophys(r1,r2)
lwz r1,TASK_STACK(r1)
addi r1,r1,THREAD_SIZE-STACK_FRAME_MIN_SIZE
li r0,0
tophys(r3,r1)
stw r0,0(r3)
bl load_segment_registers
bl load_up_mmu
tophys(r4,r2)
addi r4,r4,THREAD
mtspr SPRN_SPRG_THREAD,r4
BEGIN_MMU_FTR_SECTION
lis r4, (swapper_pg_dir - PAGE_OFFSET)@h
ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l
rlwinm r4, r4, 4, 0xffff01ff
mtspr SPRN_SDR1, r4
END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE)
li r4,MSR_KERNEL
lis r3,start_secondary@h
ori r3,r3,start_secondary@l
mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4
rfi
#endif
#ifdef CONFIG_KVM_BOOK3S_HANDLER
#include "../kvm/book3s_rmhandlers.S"
#endif
SYM_FUNC_START_LOCAL(early_hash_table)
sync
isync
tlbia
sync
TLBSYNC
lis r6, early_hash - PAGE_OFFSET@h
ori r6, r6, 3
mtspr SPRN_SDR1, r6
blr
SYM_FUNC_END(early_hash_table)
SYM_FUNC_START_LOCAL(load_up_mmu)
sync
isync
tlbia
sync
TLBSYNC
BEGIN_MMU_FTR_SECTION
lis r6,_SDR1@ha
tophys(r6,r6)
lwz r6,_SDR1@l(r6)
mtspr SPRN_SDR1,r6
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
lis r3,BATS@ha
addi r3,r3,BATS@l
tophys(r3,r3)
LOAD_BAT(0,r3,r4,r5)
LOAD_BAT(1,r3,r4,r5)
LOAD_BAT(2,r3,r4,r5)
LOAD_BAT(3,r3,r4,r5)
BEGIN_MMU_FTR_SECTION
LOAD_BAT(4,r3,r4,r5)
LOAD_BAT(5,r3,r4,r5)
LOAD_BAT(6,r3,r4,r5)
LOAD_BAT(7,r3,r4,r5)
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
blr
SYM_FUNC_END(load_up_mmu)
_GLOBAL(load_segment_registers)
li r0, NUM_USER_SEGMENTS
mtctr r0
#ifdef CONFIG_PPC_KUEP
lis r3, SR_NX@h
#else
li r3, 0
#endif
li r4, 0
3: mtsrin r3, r4
addi r3, r3, 0x111
addis r4, r4, 0x1000
bdnz 3b
li r0, 16 - NUM_USER_SEGMENTS
mtctr r0
rlwinm r3, r3, 0, ~SR_NX
rlwinm r3, r3, 0, ~SR_KS
oris r3, r3, SR_KP@h
3: mtsrin r3, r4
addi r3, r3, 0x111
addis r4, r4, 0x1000
bdnz 3b
blr
start_here:
lis r2,init_task@h
ori r2,r2,init_task@l
tophys(r4,r2)
addi r4,r4,THREAD
mtspr SPRN_SPRG_THREAD,r4
BEGIN_MMU_FTR_SECTION
lis r4, (swapper_pg_dir - PAGE_OFFSET)@h
ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l
rlwinm r4, r4, 4, 0xffff01ff
mtspr SPRN_SDR1, r4
END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE)
lis r1,init_thread_union@ha
addi r1,r1,init_thread_union@l
li r0,0
stwu r0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1)
#ifdef CONFIG_KASAN
bl kasan_early_init
#endif
li r3,0
mr r4,r31
bl machine_init
bl __save_cpu_setup
bl MMU_init
bl MMU_init_hw_patch
lis r4,2f@h
ori r4,r4,2f@l
tophys(r4,r4)
li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
.align 4
mtspr SPRN_SRR0,r4
mtspr SPRN_SRR1,r3
rfi
2: bl load_up_mmu
#ifdef CONFIG_BDI_SWITCH
lis r5, abatron_pteptrs@h
ori r5, r5, abatron_pteptrs@l
stw r5, 0xf0(0)
lis r6, swapper_pg_dir@h
ori r6, r6, swapper_pg_dir@l
tophys(r5, r5)
stw r6, 0(r5)
#endif
li r4,MSR_KERNEL
lis r3,start_kernel@h
ori r3,r3,start_kernel@l
mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4
rfi
SYM_FUNC_START_LOCAL(clear_bats)
li r10,0
mtspr SPRN_DBAT0U,r10
mtspr SPRN_DBAT0L,r10
mtspr SPRN_DBAT1U,r10
mtspr SPRN_DBAT1L,r10
mtspr SPRN_DBAT2U,r10
mtspr SPRN_DBAT2L,r10
mtspr SPRN_DBAT3U,r10
mtspr SPRN_DBAT3L,r10
mtspr SPRN_IBAT0U,r10
mtspr SPRN_IBAT0L,r10
mtspr SPRN_IBAT1U,r10
mtspr SPRN_IBAT1L,r10
mtspr SPRN_IBAT2U,r10
mtspr SPRN_IBAT2L,r10
mtspr SPRN_IBAT3U,r10
mtspr SPRN_IBAT3L,r10
BEGIN_MMU_FTR_SECTION
mtspr SPRN_DBAT4U,r10
mtspr SPRN_DBAT4L,r10
mtspr SPRN_DBAT5U,r10
mtspr SPRN_DBAT5L,r10
mtspr SPRN_DBAT6U,r10
mtspr SPRN_DBAT6L,r10
mtspr SPRN_DBAT7U,r10
mtspr SPRN_DBAT7L,r10
mtspr SPRN_IBAT4U,r10
mtspr SPRN_IBAT4L,r10
mtspr SPRN_IBAT5U,r10
mtspr SPRN_IBAT5L,r10
mtspr SPRN_IBAT6U,r10
mtspr SPRN_IBAT6L,r10
mtspr SPRN_IBAT7U,r10
mtspr SPRN_IBAT7L,r10
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
blr
SYM_FUNC_END(clear_bats)
_GLOBAL(update_bats)
lis r4, 1f@h
ori r4, r4, 1f@l
tophys(r4, r4)
mfmsr r6
mflr r7
li r3, MSR_KERNEL & ~(MSR_IR | MSR_DR)
rlwinm r0, r6, 0, ~MSR_RI
rlwinm r0, r0, 0, ~MSR_EE
mtmsr r0
.align 4
mtspr SPRN_SRR0, r4
mtspr SPRN_SRR1, r3
rfi
1: bl clear_bats
lis r3, BATS@ha
addi r3, r3, BATS@l
tophys(r3, r3)
LOAD_BAT(0, r3, r4, r5)
LOAD_BAT(1, r3, r4, r5)
LOAD_BAT(2, r3, r4, r5)
LOAD_BAT(3, r3, r4, r5)
BEGIN_MMU_FTR_SECTION
LOAD_BAT(4, r3, r4, r5)
LOAD_BAT(5, r3, r4, r5)
LOAD_BAT(6, r3, r4, r5)
LOAD_BAT(7, r3, r4, r5)
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
li r3, MSR_KERNEL & ~(MSR_IR | MSR_DR | MSR_RI)
mtmsr r3
mtspr SPRN_SRR0, r7
mtspr SPRN_SRR1, r6
rfi
SYM_FUNC_START_LOCAL(flush_tlbs)
lis r10, 0x40
1: addic. r10, r10, -0x1000
tlbie r10
bgt 1b
sync
blr
SYM_FUNC_END(flush_tlbs)
SYM_FUNC_START_LOCAL(mmu_off)
addi r4, r3, __after_mmu_off - _start
mfmsr r3
andi. r0,r3,MSR_DR|MSR_IR
beqlr
andc r3,r3,r0
.align 4
mtspr SPRN_SRR0,r4
mtspr SPRN_SRR1,r3
sync
rfi
SYM_FUNC_END(mmu_off)
SYM_FUNC_START_LOCAL(initial_bats)
lis r11,PAGE_OFFSET@h
tophys(r8,r11)
#ifdef CONFIG_SMP
ori r8,r8,0x12
#else
ori r8,r8,2
#endif
ori r11,r11,BL_256M<<2|0x2
mtspr SPRN_DBAT0L,r8
mtspr SPRN_DBAT0U,r11
mtspr SPRN_IBAT0L,r8
mtspr SPRN_IBAT0U,r11
isync
blr
SYM_FUNC_END(initial_bats)
#ifdef CONFIG_BOOTX_TEXT
SYM_FUNC_START_LOCAL(setup_disp_bat)
mflr r8
bl reloc_offset
mtlr r8
addis r8,r3,disp_BAT@ha
addi r8,r8,disp_BAT@l
cmpwi cr0,r8,0
beqlr
lwz r11,0(r8)
lwz r8,4(r8)
mtspr SPRN_DBAT3L,r8
mtspr SPRN_DBAT3U,r11
blr
SYM_FUNC_END(setup_disp_bat)
#endif
#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
SYM_FUNC_START_LOCAL(setup_cpm_bat)
lis r8, 0xf000
ori r8, r8, 0x002a
mtspr SPRN_DBAT1L, r8
lis r11, 0xf000
ori r11, r11, (BL_1M << 2) | 2
mtspr SPRN_DBAT1U, r11
blr
SYM_FUNC_END(setup_cpm_bat)
#endif
#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
SYM_FUNC_START_LOCAL(setup_usbgecko_bat)
#if defined(CONFIG_GAMECUBE)
lis r8, 0x0c00
#elif defined(CONFIG_WII)
lis r8, 0x0d00
#else
#error Invalid platform for USB Gecko based early debugging.
#endif
lis r11, 0xfffe
ori r8, r8, 0x002a
ori r11, r11, 0x2
mtspr SPRN_DBAT1L, r8
mtspr SPRN_DBAT1U, r11
blr
SYM_FUNC_END(setup_usbgecko_bat)
#endif
.data