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 14*726da2f8SDavid 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 405b3b1688SDavid Daney # Read the processor ID register 415b3b1688SDavid Daney mfc0 v1, CP0_PRID_REG 425b3b1688SDavid Daney # Disable instruction prefetching (Octeon Pass1 errata) 435b3b1688SDavid Daney or v0, v0, 0x2000 445b3b1688SDavid Daney # Skip reenable of prefetching for Octeon Pass1 455b3b1688SDavid Daney beq v1, CP0_PRID_OCTEON_PASS1, skip 465b3b1688SDavid Daney nop 475b3b1688SDavid Daney # Reenable instruction prefetching, not on Pass1 485b3b1688SDavid Daney xor v0, v0, 0x2000 495b3b1688SDavid Daney # Strip off pass number off of processor id 505b3b1688SDavid Daney srl v1, 8 515b3b1688SDavid Daney sll v1, 8 525b3b1688SDavid Daney # CN30XX needs some extra stuff turned off for better performance 535b3b1688SDavid Daney bne v1, CP0_PRID_OCTEON_CN30XX, skip 545b3b1688SDavid Daney nop 555b3b1688SDavid Daney # CN30XX Use random Icache replacement 565b3b1688SDavid Daney or v0, v0, 0x400 575b3b1688SDavid Daney # CN30XX Disable instruction prefetching 585b3b1688SDavid Daney or v0, v0, 0x2000 595b3b1688SDavid Daney skip: 607716e654SChandrakala Chavva # First clear off CvmCtl[IPPCI] bit and move the performance 617716e654SChandrakala Chavva # counters interrupt to IRQ 6 62*726da2f8SDavid Daney dli v1, ~(7 << 7) 637716e654SChandrakala Chavva and v0, v0, v1 647716e654SChandrakala Chavva ori v0, v0, (6 << 7) 65664d699aSDavid Daney 66664d699aSDavid Daney mfc0 v1, CP0_PRID_REG 67664d699aSDavid Daney and t1, v1, 0xfff8 68664d699aSDavid Daney xor t1, t1, 0x9000 # 63-P1 69664d699aSDavid Daney beqz t1, 4f 70664d699aSDavid Daney and t1, v1, 0xfff8 71664d699aSDavid Daney xor t1, t1, 0x9008 # 63-P2 72664d699aSDavid Daney beqz t1, 4f 73664d699aSDavid Daney and t1, v1, 0xfff8 74664d699aSDavid Daney xor t1, t1, 0x9100 # 68-P1 75664d699aSDavid Daney beqz t1, 4f 76664d699aSDavid Daney and t1, v1, 0xff00 77664d699aSDavid Daney xor t1, t1, 0x9200 # 66-PX 78664d699aSDavid Daney bnez t1, 5f # Skip WAR for others. 79664d699aSDavid Daney and t1, v1, 0x00ff 80664d699aSDavid Daney slti t1, t1, 2 # 66-P1.2 and later good. 81664d699aSDavid Daney beqz t1, 5f 82664d699aSDavid Daney 83664d699aSDavid Daney 4: # core-16057 work around 84664d699aSDavid Daney or v0, v0, 0x2000 # Set IPREF bit. 85664d699aSDavid Daney 86664d699aSDavid Daney 5: # No core-16057 work around 875b3b1688SDavid Daney # Write the cavium control register 885b3b1688SDavid Daney dmtc0 v0, CP0_CVMCTL_REG 895b3b1688SDavid Daney sync 905b3b1688SDavid Daney # Flush dcache after config change 915b3b1688SDavid Daney cache 9, 0($0) 92*726da2f8SDavid Daney # Zero all of CVMSEG to make sure parity is correct 93*726da2f8SDavid Daney dli v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE 94*726da2f8SDavid Daney dsll v0, 7 95*726da2f8SDavid Daney beqz v0, 2f 96*726da2f8SDavid Daney 1: dsubu v0, 8 97*726da2f8SDavid Daney sd $0, -32768(v0) 98*726da2f8SDavid Daney bnez v0, 1b 99*726da2f8SDavid Daney 2: 100*726da2f8SDavid Daney mfc0 v0, CP0_PRID_REG 101*726da2f8SDavid Daney bbit0 v0, 15, 1f 102*726da2f8SDavid Daney # OCTEON II or better have bit 15 set. Clear the error bits. 103*726da2f8SDavid Daney dli v0, 0x27 104*726da2f8SDavid Daney dmtc0 v0, CP0_DCACHE_ERR_REG 105*726da2f8SDavid Daney 1: 1065b3b1688SDavid Daney # Get my core id 1075b3b1688SDavid Daney rdhwr v0, $0 1085b3b1688SDavid Daney # Jump the master to kernel_entry 1095b3b1688SDavid Daney bne a2, zero, octeon_main_processor 1105b3b1688SDavid Daney nop 1115b3b1688SDavid Daney 1125b3b1688SDavid Daney #ifdef CONFIG_SMP 1135b3b1688SDavid Daney 1145b3b1688SDavid Daney # 1155b3b1688SDavid Daney # All cores other than the master need to wait here for SMP bootstrap 1165b3b1688SDavid Daney # to begin 1175b3b1688SDavid Daney # 1185b3b1688SDavid Daney 1195b3b1688SDavid Daney # This is the variable where the next core to boot os stored 1205b3b1688SDavid Daney PTR_LA t0, octeon_processor_boot 1215b3b1688SDavid Daney octeon_spin_wait_boot: 1225b3b1688SDavid Daney # Get the core id of the next to be booted 1235b3b1688SDavid Daney LONG_L t1, (t0) 1245b3b1688SDavid Daney # Keep looping if it isn't me 1255b3b1688SDavid Daney bne t1, v0, octeon_spin_wait_boot 1265b3b1688SDavid Daney nop 1275b3b1688SDavid Daney # Get my GP from the global variable 1285b3b1688SDavid Daney PTR_LA t0, octeon_processor_gp 1295b3b1688SDavid Daney LONG_L gp, (t0) 1305b3b1688SDavid Daney # Get my SP from the global variable 1315b3b1688SDavid Daney PTR_LA t0, octeon_processor_sp 1325b3b1688SDavid Daney LONG_L sp, (t0) 1335b3b1688SDavid Daney # Set the SP global variable to zero so the master knows we've started 1345b3b1688SDavid Daney LONG_S zero, (t0) 1355b3b1688SDavid Daney #ifdef __OCTEON__ 1365b3b1688SDavid Daney syncw 1375b3b1688SDavid Daney syncw 1385b3b1688SDavid Daney #else 1395b3b1688SDavid Daney sync 1405b3b1688SDavid Daney #endif 1415b3b1688SDavid Daney # Jump to the normal Linux SMP entry point 1425b3b1688SDavid Daney j smp_bootstrap 1435b3b1688SDavid Daney nop 1445b3b1688SDavid Daney #else /* CONFIG_SMP */ 1455b3b1688SDavid Daney 1465b3b1688SDavid Daney # 1475b3b1688SDavid Daney # Someone tried to boot SMP with a non SMP kernel. All extra cores 1485b3b1688SDavid Daney # will halt here. 1495b3b1688SDavid Daney # 1505b3b1688SDavid Daney octeon_wait_forever: 1515b3b1688SDavid Daney wait 1525b3b1688SDavid Daney b octeon_wait_forever 1535b3b1688SDavid Daney nop 1545b3b1688SDavid Daney 1555b3b1688SDavid Daney #endif /* CONFIG_SMP */ 1565b3b1688SDavid Daney octeon_main_processor: 1575b3b1688SDavid Daney .set pop 1585b3b1688SDavid Daney .endm 1595b3b1688SDavid Daney 1605b3b1688SDavid Daney /* 1615b3b1688SDavid Daney * Do SMP slave processor setup necessary before we can savely execute C code. 1625b3b1688SDavid Daney */ 1635b3b1688SDavid Daney .macro smp_slave_setup 1645b3b1688SDavid Daney .endm 1655b3b1688SDavid Daney 1665b3b1688SDavid Daney #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */ 167