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 125b3b1688SDavid Daney #define CP0_CYCLE_COUNTER $9, 6 135b3b1688SDavid Daney #define CP0_CVMCTL_REG $9, 7 145b3b1688SDavid Daney #define CP0_CVMMEMCTL_REG $11,7 155b3b1688SDavid Daney #define CP0_PRID_REG $15, 0 165b3b1688SDavid Daney #define CP0_PRID_OCTEON_PASS1 0x000d0000 175b3b1688SDavid Daney #define CP0_PRID_OCTEON_CN30XX 0x000d0200 185b3b1688SDavid Daney 195b3b1688SDavid Daney .macro kernel_entry_setup 205b3b1688SDavid Daney # Registers set by bootloader: 215b3b1688SDavid Daney # (only 32 bits set by bootloader, all addresses are physical 225b3b1688SDavid Daney # addresses, and need to have the appropriate memory region set 235b3b1688SDavid Daney # by the kernel 245b3b1688SDavid Daney # a0 = argc 255b3b1688SDavid Daney # a1 = argv (kseg0 compat addr) 265b3b1688SDavid Daney # a2 = 1 if init core, zero otherwise 275b3b1688SDavid Daney # a3 = address of boot descriptor block 285b3b1688SDavid Daney .set push 295b3b1688SDavid Daney .set arch=octeon 305b3b1688SDavid Daney # Read the cavium mem control register 315b3b1688SDavid Daney dmfc0 v0, CP0_CVMMEMCTL_REG 325b3b1688SDavid Daney # Clear the lower 6 bits, the CVMSEG size 335b3b1688SDavid Daney dins v0, $0, 0, 6 345b3b1688SDavid Daney ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE 355b3b1688SDavid Daney dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register 365b3b1688SDavid Daney dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register 375b3b1688SDavid Daney # Disable unaligned load/store support but leave HW fixup enabled 380ec31512SDavid Daney # Needed for octeon specific memcpy 395b3b1688SDavid Daney or v0, v0, 0x5001 405b3b1688SDavid Daney xor v0, v0, 0x1001 415b3b1688SDavid Daney # Read the processor ID register 425b3b1688SDavid Daney mfc0 v1, CP0_PRID_REG 435b3b1688SDavid Daney # Disable instruction prefetching (Octeon Pass1 errata) 445b3b1688SDavid Daney or v0, v0, 0x2000 455b3b1688SDavid Daney # Skip reenable of prefetching for Octeon Pass1 465b3b1688SDavid Daney beq v1, CP0_PRID_OCTEON_PASS1, skip 475b3b1688SDavid Daney nop 485b3b1688SDavid Daney # Reenable instruction prefetching, not on Pass1 495b3b1688SDavid Daney xor v0, v0, 0x2000 505b3b1688SDavid Daney # Strip off pass number off of processor id 515b3b1688SDavid Daney srl v1, 8 525b3b1688SDavid Daney sll v1, 8 535b3b1688SDavid Daney # CN30XX needs some extra stuff turned off for better performance 545b3b1688SDavid Daney bne v1, CP0_PRID_OCTEON_CN30XX, skip 555b3b1688SDavid Daney nop 565b3b1688SDavid Daney # CN30XX Use random Icache replacement 575b3b1688SDavid Daney or v0, v0, 0x400 585b3b1688SDavid Daney # CN30XX Disable instruction prefetching 595b3b1688SDavid Daney or v0, v0, 0x2000 605b3b1688SDavid Daney skip: 617716e654SChandrakala Chavva # First clear off CvmCtl[IPPCI] bit and move the performance 627716e654SChandrakala Chavva # counters interrupt to IRQ 6 637716e654SChandrakala Chavva li v1, ~(7 << 7) 647716e654SChandrakala Chavva and v0, v0, v1 657716e654SChandrakala Chavva ori v0, v0, (6 << 7) 66*664d699aSDavid Daney 67*664d699aSDavid Daney mfc0 v1, CP0_PRID_REG 68*664d699aSDavid Daney and t1, v1, 0xfff8 69*664d699aSDavid Daney xor t1, t1, 0x9000 # 63-P1 70*664d699aSDavid Daney beqz t1, 4f 71*664d699aSDavid Daney and t1, v1, 0xfff8 72*664d699aSDavid Daney xor t1, t1, 0x9008 # 63-P2 73*664d699aSDavid Daney beqz t1, 4f 74*664d699aSDavid Daney and t1, v1, 0xfff8 75*664d699aSDavid Daney xor t1, t1, 0x9100 # 68-P1 76*664d699aSDavid Daney beqz t1, 4f 77*664d699aSDavid Daney and t1, v1, 0xff00 78*664d699aSDavid Daney xor t1, t1, 0x9200 # 66-PX 79*664d699aSDavid Daney bnez t1, 5f # Skip WAR for others. 80*664d699aSDavid Daney and t1, v1, 0x00ff 81*664d699aSDavid Daney slti t1, t1, 2 # 66-P1.2 and later good. 82*664d699aSDavid Daney beqz t1, 5f 83*664d699aSDavid Daney 84*664d699aSDavid Daney 4: # core-16057 work around 85*664d699aSDavid Daney or v0, v0, 0x2000 # Set IPREF bit. 86*664d699aSDavid Daney 87*664d699aSDavid Daney 5: # No core-16057 work around 885b3b1688SDavid Daney # Write the cavium control register 895b3b1688SDavid Daney dmtc0 v0, CP0_CVMCTL_REG 905b3b1688SDavid Daney sync 915b3b1688SDavid Daney # Flush dcache after config change 925b3b1688SDavid Daney cache 9, 0($0) 935b3b1688SDavid Daney # Get my core id 945b3b1688SDavid Daney rdhwr v0, $0 955b3b1688SDavid Daney # Jump the master to kernel_entry 965b3b1688SDavid Daney bne a2, zero, octeon_main_processor 975b3b1688SDavid Daney nop 985b3b1688SDavid Daney 995b3b1688SDavid Daney #ifdef CONFIG_SMP 1005b3b1688SDavid Daney 1015b3b1688SDavid Daney # 1025b3b1688SDavid Daney # All cores other than the master need to wait here for SMP bootstrap 1035b3b1688SDavid Daney # to begin 1045b3b1688SDavid Daney # 1055b3b1688SDavid Daney 1065b3b1688SDavid Daney # This is the variable where the next core to boot os stored 1075b3b1688SDavid Daney PTR_LA t0, octeon_processor_boot 1085b3b1688SDavid Daney octeon_spin_wait_boot: 1095b3b1688SDavid Daney # Get the core id of the next to be booted 1105b3b1688SDavid Daney LONG_L t1, (t0) 1115b3b1688SDavid Daney # Keep looping if it isn't me 1125b3b1688SDavid Daney bne t1, v0, octeon_spin_wait_boot 1135b3b1688SDavid Daney nop 1145b3b1688SDavid Daney # Get my GP from the global variable 1155b3b1688SDavid Daney PTR_LA t0, octeon_processor_gp 1165b3b1688SDavid Daney LONG_L gp, (t0) 1175b3b1688SDavid Daney # Get my SP from the global variable 1185b3b1688SDavid Daney PTR_LA t0, octeon_processor_sp 1195b3b1688SDavid Daney LONG_L sp, (t0) 1205b3b1688SDavid Daney # Set the SP global variable to zero so the master knows we've started 1215b3b1688SDavid Daney LONG_S zero, (t0) 1225b3b1688SDavid Daney #ifdef __OCTEON__ 1235b3b1688SDavid Daney syncw 1245b3b1688SDavid Daney syncw 1255b3b1688SDavid Daney #else 1265b3b1688SDavid Daney sync 1275b3b1688SDavid Daney #endif 1285b3b1688SDavid Daney # Jump to the normal Linux SMP entry point 1295b3b1688SDavid Daney j smp_bootstrap 1305b3b1688SDavid Daney nop 1315b3b1688SDavid Daney #else /* CONFIG_SMP */ 1325b3b1688SDavid Daney 1335b3b1688SDavid Daney # 1345b3b1688SDavid Daney # Someone tried to boot SMP with a non SMP kernel. All extra cores 1355b3b1688SDavid Daney # will halt here. 1365b3b1688SDavid Daney # 1375b3b1688SDavid Daney octeon_wait_forever: 1385b3b1688SDavid Daney wait 1395b3b1688SDavid Daney b octeon_wait_forever 1405b3b1688SDavid Daney nop 1415b3b1688SDavid Daney 1425b3b1688SDavid Daney #endif /* CONFIG_SMP */ 1435b3b1688SDavid Daney octeon_main_processor: 1445b3b1688SDavid Daney .set pop 1455b3b1688SDavid Daney .endm 1465b3b1688SDavid Daney 1475b3b1688SDavid Daney /* 1485b3b1688SDavid Daney * Do SMP slave processor setup necessary before we can savely execute C code. 1495b3b1688SDavid Daney */ 1505b3b1688SDavid Daney .macro smp_slave_setup 1515b3b1688SDavid Daney .endm 1525b3b1688SDavid Daney 1535b3b1688SDavid Daney #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */ 154