15b3b1688SDavid Daney /* 25b3b1688SDavid Daney * This file is subject to the terms and conditions of the GNU General Public 35b3b1688SDavid Daney * License. See the file "COPYING" in the main directory of this archive 45b3b1688SDavid Daney * for more details. 55b3b1688SDavid Daney * 65b3b1688SDavid Daney * Copyright (C) 2005-2008 Cavium Networks, Inc 75b3b1688SDavid Daney */ 85b3b1688SDavid Daney #ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H 95b3b1688SDavid Daney #define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H 105b3b1688SDavid Daney 115b3b1688SDavid Daney #define CP0_CVMCTL_REG $9, 7 125b3b1688SDavid Daney #define CP0_CVMMEMCTL_REG $11,7 135b3b1688SDavid Daney #define CP0_PRID_REG $15, 0 14726da2f8SDavid Daney #define CP0_DCACHE_ERR_REG $27, 1 155b3b1688SDavid Daney #define CP0_PRID_OCTEON_PASS1 0x000d0000 165b3b1688SDavid Daney #define CP0_PRID_OCTEON_CN30XX 0x000d0200 175b3b1688SDavid Daney 185b3b1688SDavid Daney .macro kernel_entry_setup 195b3b1688SDavid Daney # Registers set by bootloader: 205b3b1688SDavid Daney # (only 32 bits set by bootloader, all addresses are physical 215b3b1688SDavid Daney # addresses, and need to have the appropriate memory region set 225b3b1688SDavid Daney # by the kernel 235b3b1688SDavid Daney # a0 = argc 245b3b1688SDavid Daney # a1 = argv (kseg0 compat addr) 255b3b1688SDavid Daney # a2 = 1 if init core, zero otherwise 265b3b1688SDavid Daney # a3 = address of boot descriptor block 275b3b1688SDavid Daney .set push 285b3b1688SDavid Daney .set arch=octeon 295b3b1688SDavid Daney # Read the cavium mem control register 305b3b1688SDavid Daney dmfc0 v0, CP0_CVMMEMCTL_REG 315b3b1688SDavid Daney # Clear the lower 6 bits, the CVMSEG size 325b3b1688SDavid Daney dins v0, $0, 0, 6 335b3b1688SDavid Daney ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE 345b3b1688SDavid Daney dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register 355b3b1688SDavid Daney dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register 365b3b1688SDavid Daney # Disable unaligned load/store support but leave HW fixup enabled 370ec31512SDavid Daney # Needed for octeon specific memcpy 385b3b1688SDavid Daney or v0, v0, 0x5001 395b3b1688SDavid Daney xor v0, v0, 0x1001 407716e654SChandrakala Chavva # First clear off CvmCtl[IPPCI] bit and move the performance 417716e654SChandrakala Chavva # counters interrupt to IRQ 6 42726da2f8SDavid Daney dli v1, ~(7 << 7) 437716e654SChandrakala Chavva and v0, v0, v1 447716e654SChandrakala Chavva ori v0, v0, (6 << 7) 45664d699aSDavid Daney 46664d699aSDavid Daney mfc0 v1, CP0_PRID_REG 47664d699aSDavid Daney and t1, v1, 0xfff8 48664d699aSDavid Daney xor t1, t1, 0x9000 # 63-P1 49664d699aSDavid Daney beqz t1, 4f 50664d699aSDavid Daney and t1, v1, 0xfff8 51664d699aSDavid Daney xor t1, t1, 0x9008 # 63-P2 52664d699aSDavid Daney beqz t1, 4f 53664d699aSDavid Daney and t1, v1, 0xfff8 54664d699aSDavid Daney xor t1, t1, 0x9100 # 68-P1 55664d699aSDavid Daney beqz t1, 4f 56664d699aSDavid Daney and t1, v1, 0xff00 57664d699aSDavid Daney xor t1, t1, 0x9200 # 66-PX 58664d699aSDavid Daney bnez t1, 5f # Skip WAR for others. 59664d699aSDavid Daney and t1, v1, 0x00ff 60664d699aSDavid Daney slti t1, t1, 2 # 66-P1.2 and later good. 61664d699aSDavid Daney beqz t1, 5f 62664d699aSDavid Daney 63664d699aSDavid Daney 4: # core-16057 work around 64664d699aSDavid Daney or v0, v0, 0x2000 # Set IPREF bit. 65664d699aSDavid Daney 66664d699aSDavid Daney 5: # No core-16057 work around 675b3b1688SDavid Daney # Write the cavium control register 685b3b1688SDavid Daney dmtc0 v0, CP0_CVMCTL_REG 695b3b1688SDavid Daney sync 705b3b1688SDavid Daney # Flush dcache after config change 715b3b1688SDavid Daney cache 9, 0($0) 72726da2f8SDavid Daney # Zero all of CVMSEG to make sure parity is correct 73726da2f8SDavid Daney dli v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE 74726da2f8SDavid Daney dsll v0, 7 75726da2f8SDavid Daney beqz v0, 2f 76726da2f8SDavid Daney 1: dsubu v0, 8 77726da2f8SDavid Daney sd $0, -32768(v0) 78726da2f8SDavid Daney bnez v0, 1b 79726da2f8SDavid Daney 2: 80726da2f8SDavid Daney mfc0 v0, CP0_PRID_REG 81726da2f8SDavid Daney bbit0 v0, 15, 1f 82726da2f8SDavid Daney # OCTEON II or better have bit 15 set. Clear the error bits. 83ac6d9b3aSChandrakala Chavva and t1, v0, 0xff00 84ac6d9b3aSChandrakala Chavva dli v0, 0x9500 85ac6d9b3aSChandrakala Chavva bge t1, v0, 1f # OCTEON III has no DCACHE_ERR_REG COP0 86726da2f8SDavid Daney dli v0, 0x27 87726da2f8SDavid Daney dmtc0 v0, CP0_DCACHE_ERR_REG 88726da2f8SDavid Daney 1: 895b3b1688SDavid Daney # Get my core id 905b3b1688SDavid Daney rdhwr v0, $0 915b3b1688SDavid Daney # Jump the master to kernel_entry 925b3b1688SDavid Daney bne a2, zero, octeon_main_processor 935b3b1688SDavid Daney nop 945b3b1688SDavid Daney 955b3b1688SDavid Daney #ifdef CONFIG_SMP 965b3b1688SDavid Daney 975b3b1688SDavid Daney # 985b3b1688SDavid Daney # All cores other than the master need to wait here for SMP bootstrap 995b3b1688SDavid Daney # to begin 1005b3b1688SDavid Daney # 1015b3b1688SDavid Daney 1025b3b1688SDavid Daney octeon_spin_wait_boot: 1033ff72be4SSteven J. Hill #ifdef CONFIG_RELOCATABLE 1043ff72be4SSteven J. Hill PTR_LA t0, octeon_processor_relocated_kernel_entry 1053ff72be4SSteven J. Hill LONG_L t0, (t0) 1063ff72be4SSteven J. Hill beq zero, t0, 1f 1073ff72be4SSteven J. Hill nop 1083ff72be4SSteven J. Hill 1093ff72be4SSteven J. Hill jr t0 1103ff72be4SSteven J. Hill nop 1113ff72be4SSteven J. Hill 1: 1123ff72be4SSteven J. Hill #endif /* CONFIG_RELOCATABLE */ 1133ff72be4SSteven J. Hill 1143ff72be4SSteven J. Hill # This is the variable where the next core to boot is stored 1153ff72be4SSteven J. Hill PTR_LA t0, octeon_processor_boot 1165b3b1688SDavid Daney # Get the core id of the next to be booted 1175b3b1688SDavid Daney LONG_L t1, (t0) 1185b3b1688SDavid Daney # Keep looping if it isn't me 1195b3b1688SDavid Daney bne t1, v0, octeon_spin_wait_boot 1205b3b1688SDavid Daney nop 1215b3b1688SDavid Daney # Get my GP from the global variable 1225b3b1688SDavid Daney PTR_LA t0, octeon_processor_gp 1235b3b1688SDavid Daney LONG_L gp, (t0) 1245b3b1688SDavid Daney # Get my SP from the global variable 1255b3b1688SDavid Daney PTR_LA t0, octeon_processor_sp 1265b3b1688SDavid Daney LONG_L sp, (t0) 1275b3b1688SDavid Daney # Set the SP global variable to zero so the master knows we've started 1285b3b1688SDavid Daney LONG_S zero, (t0) 1295b3b1688SDavid Daney #ifdef __OCTEON__ 1305b3b1688SDavid Daney syncw 1315b3b1688SDavid Daney syncw 1325b3b1688SDavid Daney #else 1335b3b1688SDavid Daney sync 1345b3b1688SDavid Daney #endif 1355b3b1688SDavid Daney # Jump to the normal Linux SMP entry point 1365b3b1688SDavid Daney j smp_bootstrap 1375b3b1688SDavid Daney nop 1385b3b1688SDavid Daney #else /* CONFIG_SMP */ 1395b3b1688SDavid Daney 1405b3b1688SDavid Daney # 1415b3b1688SDavid Daney # Someone tried to boot SMP with a non SMP kernel. All extra cores 1425b3b1688SDavid Daney # will halt here. 1435b3b1688SDavid Daney # 1445b3b1688SDavid Daney octeon_wait_forever: 1455b3b1688SDavid Daney wait 1465b3b1688SDavid Daney b octeon_wait_forever 1475b3b1688SDavid Daney nop 1485b3b1688SDavid Daney 1495b3b1688SDavid Daney #endif /* CONFIG_SMP */ 1505b3b1688SDavid Daney octeon_main_processor: 1515b3b1688SDavid Daney .set pop 1525b3b1688SDavid Daney .endm 1535b3b1688SDavid Daney 1545b3b1688SDavid Daney /* 15592a76f6dSAdam Buchbinder * Do SMP slave processor setup necessary before we can safely execute C code. 1565b3b1688SDavid Daney */ 1575b3b1688SDavid Daney .macro smp_slave_setup 1585b3b1688SDavid Daney .endm 1595b3b1688SDavid Daney 160*6ce48897SHuacai Chen #define USE_KEXEC_SMP_WAIT_FINAL 161*6ce48897SHuacai Chen .macro kexec_smp_wait_final 162*6ce48897SHuacai Chen .set push 163*6ce48897SHuacai Chen .set noreorder 164*6ce48897SHuacai Chen synci 0($0) 165*6ce48897SHuacai Chen .set pop 166*6ce48897SHuacai Chen .endm 167*6ce48897SHuacai Chen 1685b3b1688SDavid Daney #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */ 169