1 /* 1 /* 2 * This file is subject to the terms and condi !! 2 * linux/arch/i386/kernel/head.S -- the 32-bit startup code. 3 * License. See the file "COPYING" in the mai !! 3 * 4 * for more details. !! 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * !! 5 * 6 * Copyright (C) 1994, 1995 Waldorf Electronic !! 6 * Enhanced CPU detection and feature setting code by Mike Jagdis 7 * Written by Ralf Baechle and Andreas Busse !! 7 * and Martin Mares, November 1997. 8 * Copyright (C) 1994 - 99, 2003, 06 Ralf Baec << 9 * Copyright (C) 1996 Paul M. Antoine << 10 * Modified for DECStation and hence R3000 sup << 11 * Further modifications by David S. Miller an << 12 * Copyright (C) 1999 Silicon Graphics, Inc. << 13 * Kevin Kissell, kevink@mips.com and Carsten << 14 * Copyright (C) 2000 MIPS Technologies, Inc. << 15 */ 8 */ 16 #include <linux/init.h> !! 9 >> 10 .text >> 11 #include <linux/config.h> 17 #include <linux/threads.h> 12 #include <linux/threads.h> >> 13 #include <linux/linkage.h> >> 14 #include <asm/segment.h> >> 15 #include <asm/page.h> >> 16 #include <asm/pgtable.h> >> 17 #include <asm/desc.h> >> 18 #include <asm/cache.h> >> 19 >> 20 #define OLD_CL_MAGIC_ADDR 0x90020 >> 21 #define OLD_CL_MAGIC 0xA33F >> 22 #define OLD_CL_BASE_ADDR 0x90000 >> 23 #define OLD_CL_OFFSET 0x90022 >> 24 #define NEW_CL_POINTER 0x228 /* Relative to real mode data */ 18 25 19 #include <asm/addrspace.h> !! 26 /* 20 #include <asm/asm.h> !! 27 * References to members of the new_cpu_data structure. 21 #include <asm/asmmacro.h> !! 28 */ 22 #include <asm/irqflags.h> << 23 #include <asm/regdef.h> << 24 #include <asm/mipsregs.h> << 25 #include <asm/stackframe.h> << 26 29 27 #include <kernel-entry-init.h> !! 30 #define CPU_PARAMS new_cpu_data >> 31 #define X86 CPU_PARAMS+0 >> 32 #define X86_VENDOR CPU_PARAMS+1 >> 33 #define X86_MODEL CPU_PARAMS+2 >> 34 #define X86_MASK CPU_PARAMS+3 >> 35 #define X86_HARD_MATH CPU_PARAMS+6 >> 36 #define X86_CPUID CPU_PARAMS+8 >> 37 #define X86_CAPABILITY CPU_PARAMS+12 >> 38 #define X86_VENDOR_ID CPU_PARAMS+36 /* offset dependent on NCAPINTS */ 28 39 29 /* !! 40 /* 30 * For the moment disable interrupts, !! 41 * Initialize page tables 31 * set ST0_KX so that the CPU does not !! 42 */ 32 * 64-bit addresses. A full initializ !! 43 #define INIT_PAGE_TABLES \ 33 * register is done later in per_cpu_t !! 44 movl $pg0 - __PAGE_OFFSET, %edi; \ 34 */ !! 45 /* "007" doesn't mean with license to kill, but PRESENT+RW+USER */ \ 35 .macro setup_c0_status set clr !! 46 movl $007, %eax; \ 36 .set push !! 47 2: stosl; \ 37 mfc0 t0, CP0_STATUS !! 48 add $0x1000, %eax; \ 38 or t0, ST0_KERNEL_CUMASK|\set|0x1 !! 49 cmp $empty_zero_page - __PAGE_OFFSET, %edi; \ 39 xor t0, 0x1f|\clr !! 50 jne 2b; 40 mtc0 t0, CP0_STATUS !! 51 41 .set noreorder !! 52 /* 42 sll zero,3 !! 53 * swapper_pg_dir is the main page directory, address 0x00101000 43 .set pop !! 54 * 44 .endm !! 55 * On entry, %esi points to the real-mode code as a 32-bit pointer. 45 !! 56 */ 46 .macro setup_c0_status_pri !! 57 ENTRY(startup_32) 47 #ifdef CONFIG_64BIT !! 58 48 setup_c0_status ST0_KX 0 !! 59 #ifdef CONFIG_X86_VISWS 49 #else !! 60 /* 50 setup_c0_status 0 0 !! 61 * On SGI Visual Workstations boot CPU starts in protected mode. >> 62 */ >> 63 orw %bx, %bx >> 64 jnz 1f >> 65 INIT_PAGE_TABLES >> 66 movl $swapper_pg_dir - __PAGE_OFFSET, %eax >> 67 movl %eax, %cr3 >> 68 lgdt boot_gdt >> 69 1: 51 #endif 70 #endif 52 .endm << 53 71 54 .macro setup_c0_status_sec !! 72 /* 55 #ifdef CONFIG_64BIT !! 73 * Set segments to known values 56 setup_c0_status ST0_KX ST0_BEV !! 74 */ 57 #else !! 75 cld 58 setup_c0_status 0 ST0_BEV !! 76 movl $(__BOOT_DS),%eax >> 77 movl %eax,%ds >> 78 movl %eax,%es >> 79 movl %eax,%fs >> 80 movl %eax,%gs >> 81 #ifdef CONFIG_SMP >> 82 orw %bx,%bx >> 83 jz 1f >> 84 >> 85 /* >> 86 * New page tables may be in 4Mbyte page mode and may >> 87 * be using the global pages. >> 88 * >> 89 * NOTE! If we are on a 486 we may have no cr4 at all! >> 90 * So we do not try to touch it unless we really have >> 91 * some bits in it to set. This won't work if the BSP >> 92 * implements cr4 but this AP does not -- very unlikely >> 93 * but be warned! The same applies to the pse feature >> 94 * if not equally supported. --macro >> 95 * >> 96 * NOTE! We have to correct for the fact that we're >> 97 * not yet offset PAGE_OFFSET.. >> 98 */ >> 99 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET >> 100 cmpl $0,cr4_bits >> 101 je 3f >> 102 movl %cr4,%eax # Turn on paging options (PSE,PAE,..) >> 103 orl cr4_bits,%eax >> 104 movl %eax,%cr4 >> 105 jmp 3f >> 106 1: 59 #endif 107 #endif 60 .endm !! 108 INIT_PAGE_TABLES >> 109 /* >> 110 * Enable paging >> 111 */ >> 112 3: >> 113 movl $swapper_pg_dir-__PAGE_OFFSET,%eax >> 114 movl %eax,%cr3 /* set the page table pointer.. */ >> 115 movl %cr0,%eax >> 116 orl $0x80000000,%eax >> 117 movl %eax,%cr0 /* ..and set paging (PG) bit */ >> 118 jmp 1f /* flush the prefetch-queue */ >> 119 1: >> 120 movl $1f,%eax >> 121 jmp *%eax /* make sure eip is relocated */ >> 122 1: >> 123 /* Set up the stack pointer */ >> 124 lss stack_start,%esp 61 125 62 #ifndef CONFIG_NO_EXCEPT_FILL !! 126 #ifdef CONFIG_SMP 63 /* !! 127 orw %bx,%bx 64 * Reserved space for exception handle !! 128 jz 1f /* Initial CPU cleans BSS */ 65 * Necessary for machines which link t !! 129 pushl $0 66 */ !! 130 popfl 67 .fill 0x400 !! 131 jmp checkCPUtype >> 132 1: >> 133 #endif /* CONFIG_SMP */ >> 134 >> 135 /* >> 136 * Clear BSS first so that there are no surprises... >> 137 * No need to cld as DF is already clear from cld above... >> 138 */ >> 139 xorl %eax,%eax >> 140 movl $__bss_start,%edi >> 141 movl $__bss_stop,%ecx >> 142 subl %edi,%ecx >> 143 rep >> 144 stosb >> 145 >> 146 /* >> 147 * start system 32-bit setup. We need to re-do some of the things done >> 148 * in 16-bit mode for the "real" operations. >> 149 */ >> 150 call setup_idt >> 151 /* >> 152 * Initialize eflags. Some BIOS's leave bits like NT set. This would >> 153 * confuse the debugger if this code is traced. >> 154 * XXX - best to initialize before switching to protected mode. >> 155 */ >> 156 pushl $0 >> 157 popfl >> 158 /* >> 159 * Copy bootup parameters out of the way. First 2kB of >> 160 * _empty_zero_page is for boot parameters, second 2kB >> 161 * is for the command line. >> 162 * >> 163 * Note: %esi still has the pointer to the real-mode data. >> 164 */ >> 165 movl $empty_zero_page,%edi >> 166 movl $512,%ecx >> 167 cld >> 168 rep >> 169 movsl >> 170 xorl %eax,%eax >> 171 movl $512,%ecx >> 172 rep >> 173 stosl >> 174 movl empty_zero_page+NEW_CL_POINTER,%esi >> 175 andl %esi,%esi >> 176 jnz 2f # New command line protocol >> 177 cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR >> 178 jne 1f >> 179 movzwl OLD_CL_OFFSET,%esi >> 180 addl $(OLD_CL_BASE_ADDR),%esi >> 181 2: >> 182 movl $empty_zero_page+2048,%edi >> 183 movl $512,%ecx >> 184 rep >> 185 movsl >> 186 1: >> 187 checkCPUtype: >> 188 >> 189 movl $-1,X86_CPUID # -1 for no CPUID initially >> 190 >> 191 /* check if it is 486 or 386. */ >> 192 /* >> 193 * XXX - this does a lot of unnecessary setup. Alignment checks don't >> 194 * apply at our cpl of 0 and the stack ought to be aligned already, and >> 195 * we don't need to preserve eflags. >> 196 */ >> 197 >> 198 movb $3,X86 # at least 386 >> 199 pushfl # push EFLAGS >> 200 popl %eax # get EFLAGS >> 201 movl %eax,%ecx # save original EFLAGS >> 202 xorl $0x240000,%eax # flip AC and ID bits in EFLAGS >> 203 pushl %eax # copy to EFLAGS >> 204 popfl # set EFLAGS >> 205 pushfl # get new EFLAGS >> 206 popl %eax # put it in eax >> 207 xorl %ecx,%eax # change in flags >> 208 pushl %ecx # restore original EFLAGS >> 209 popfl >> 210 testl $0x40000,%eax # check if AC bit changed >> 211 je is386 >> 212 >> 213 movb $4,X86 # at least 486 >> 214 testl $0x200000,%eax # check if ID bit changed >> 215 je is486 >> 216 >> 217 /* get vendor info */ >> 218 xorl %eax,%eax # call CPUID with 0 -> return vendor ID >> 219 cpuid >> 220 movl %eax,X86_CPUID # save CPUID level >> 221 movl %ebx,X86_VENDOR_ID # lo 4 chars >> 222 movl %edx,X86_VENDOR_ID+4 # next 4 chars >> 223 movl %ecx,X86_VENDOR_ID+8 # last 4 chars >> 224 >> 225 orl %eax,%eax # do we have processor info as well? >> 226 je is486 >> 227 >> 228 movl $1,%eax # Use the CPUID instruction to get CPU type >> 229 cpuid >> 230 movb %al,%cl # save reg for future use >> 231 andb $0x0f,%ah # mask processor family >> 232 movb %ah,X86 >> 233 andb $0xf0,%al # mask model >> 234 shrb $4,%al >> 235 movb %al,X86_MODEL >> 236 andb $0x0f,%cl # mask mask revision >> 237 movb %cl,X86_MASK >> 238 movl %edx,X86_CAPABILITY >> 239 >> 240 is486: movl $0x50022,%ecx # set AM, WP, NE and MP >> 241 jmp 2f >> 242 >> 243 is386: movl $2,%ecx # set MP >> 244 2: movl %cr0,%eax >> 245 andl $0x80000011,%eax # Save PG,PE,ET >> 246 orl %ecx,%eax >> 247 movl %eax,%cr0 >> 248 >> 249 call check_x87 >> 250 incb ready >> 251 lgdt cpu_gdt_descr >> 252 lidt idt_descr >> 253 ljmp $(__KERNEL_CS),$1f >> 254 1: movl $(__KERNEL_DS),%eax # reload all the segment registers >> 255 movl %eax,%ss # after changing gdt. >> 256 >> 257 movl $(__USER_DS),%eax # DS/ES contains default USER segment >> 258 movl %eax,%ds >> 259 movl %eax,%es >> 260 >> 261 xorl %eax,%eax # Clear FS/GS and LDT >> 262 movl %eax,%fs >> 263 movl %eax,%gs >> 264 lldt %ax >> 265 cld # gcc2 wants the direction flag cleared at all times >> 266 #ifdef CONFIG_SMP >> 267 movb ready, %cl >> 268 cmpb $1,%cl >> 269 je 1f # the first CPU calls start_kernel >> 270 # all other CPUs call initialize_secondary >> 271 call initialize_secondary >> 272 jmp L6 >> 273 1: 68 #endif 274 #endif >> 275 call start_kernel >> 276 L6: >> 277 jmp L6 # main should never return here, but >> 278 # just in case, we know what happens. 69 279 70 EXPORT(_stext) !! 280 ready: .byte 0 71 281 72 #ifdef CONFIG_BOOT_RAW !! 282 /* 73 /* !! 283 * We depend on ET to be correct. This checks for 287/387. 74 * Give us a fighting chance of runnin !! 284 */ 75 * kernel load address. This is neede !! 285 check_x87: 76 * not have a ELF loader yet. !! 286 movb $0,X86_HARD_MATH 77 */ !! 287 clts 78 FEXPORT(__kernel_entry) !! 288 fninit 79 j kernel_entry !! 289 fstsw %ax 80 #endif /* CONFIG_BOOT_RAW */ !! 290 cmpb $0,%al >> 291 je 1f >> 292 movl %cr0,%eax /* no coprocessor: have to set bits */ >> 293 xorl $4,%eax /* set EM */ >> 294 movl %eax,%cr0 >> 295 ret >> 296 ALIGN >> 297 1: movb $1,X86_HARD_MATH >> 298 .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ >> 299 ret 81 300 82 __REF !! 301 /* >> 302 * setup_idt >> 303 * >> 304 * sets up a idt with 256 entries pointing to >> 305 * ignore_int, interrupt gates. It doesn't actually load >> 306 * idt - that can be done only after paging has been enabled >> 307 * and the kernel moved to PAGE_OFFSET. Interrupts >> 308 * are enabled elsewhere, when we can be relatively >> 309 * sure everything is ok. >> 310 */ >> 311 setup_idt: >> 312 lea ignore_int,%edx >> 313 movl $(__KERNEL_CS << 16),%eax >> 314 movw %dx,%ax /* selector = 0x0010 = cs */ >> 315 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ >> 316 >> 317 lea idt_table,%edi >> 318 mov $256,%ecx >> 319 rp_sidt: >> 320 movl %eax,(%edi) >> 321 movl %edx,4(%edi) >> 322 addl $8,%edi >> 323 dec %ecx >> 324 jne rp_sidt >> 325 ret >> 326 >> 327 ENTRY(stack_start) >> 328 .long init_thread_union+8192 >> 329 .long __BOOT_DS >> 330 >> 331 /* This is the default interrupt "handler" :-) */ >> 332 int_msg: >> 333 .asciz "Unknown interrupt\n" >> 334 ALIGN >> 335 ignore_int: >> 336 cld >> 337 pushl %eax >> 338 pushl %ecx >> 339 pushl %edx >> 340 pushl %es >> 341 pushl %ds >> 342 movl $(__KERNEL_DS),%eax >> 343 movl %eax,%ds >> 344 movl %eax,%es >> 345 pushl $int_msg >> 346 call printk >> 347 popl %eax >> 348 popl %ds >> 349 popl %es >> 350 popl %edx >> 351 popl %ecx >> 352 popl %eax >> 353 iret 83 354 84 NESTED(kernel_entry, 16, sp) !! 355 /* >> 356 * The IDT and GDT 'descriptors' are a strange 48-bit object >> 357 * only used by the lidt and lgdt instructions. They are not >> 358 * like usual segment descriptors - they consist of a 16-bit >> 359 * segment size, and 32-bit linear address value: >> 360 */ 85 361 86 kernel_entry_setup !! 362 .globl idt_descr >> 363 .globl cpu_gdt_descr 87 364 88 setup_c0_status_pri !! 365 ALIGN >> 366 .word 0 # 32-bit align idt_desc.address >> 367 idt_descr: >> 368 .word IDT_ENTRIES*8-1 # idt contains 256 entries >> 369 .long idt_table >> 370 >> 371 # boot GDT descriptor (later on used by CPU#0): >> 372 .word 0 # 32 bit align gdt_desc.address >> 373 cpu_gdt_descr: >> 374 .word GDT_ENTRIES*8-1 >> 375 .long cpu_gdt_table 89 376 90 /* We might not get launched at the ad !! 377 .fill NR_CPUS-1,8,0 # space for the other GDT descriptors 91 so we jump there. */ << 92 PTR_LA t0, 0f << 93 jr t0 << 94 0: << 95 378 96 PTR_LA t0, __bss_start !! 379 /* 97 LONG_S zero, (t0) !! 380 * This is initialized to create an identity-mapping at 0-8M (for bootup 98 PTR_LA t1, __bss_stop - LONGS !! 381 * purposes) and another mapping of the 0-8M area at virtual address 99 1: !! 382 * PAGE_OFFSET. 100 PTR_ADDIU t0, LONGSIZE !! 383 */ 101 LONG_S zero, (t0) !! 384 .org 0x1000 102 bne t0, t1, 1b !! 385 ENTRY(swapper_pg_dir) >> 386 .long 0x00102007 >> 387 .long 0x00103007 >> 388 .fill BOOT_USER_PGD_PTRS-2,4,0 >> 389 /* default: 766 entries */ >> 390 .long 0x00102007 >> 391 .long 0x00103007 >> 392 /* default: 254 entries */ >> 393 .fill BOOT_KERNEL_PGD_PTRS-2,4,0 103 394 104 LONG_S a0, fw_arg0 !! 395 /* 105 LONG_S a1, fw_arg1 !! 396 * The page tables are initialized to only 8MB here - the final page 106 LONG_S a2, fw_arg2 !! 397 * tables are set up later depending on memory size. 107 LONG_S a3, fw_arg3 !! 398 */ >> 399 .org 0x2000 >> 400 ENTRY(pg0) 108 401 109 MTC0 zero, CP0_CONTEXT !! 402 .org 0x3000 110 #ifdef CONFIG_64BIT !! 403 ENTRY(pg1) 111 MTC0 zero, CP0_XCONTEXT !! 404 112 #endif !! 405 /* 113 PTR_LA $28, init_thread_union !! 406 * empty_zero_page must immediately follow the page tables ! (The 114 /* Set the SP after an empty pt_regs. !! 407 * initialization loop counts until empty_zero_page) 115 PTR_LI sp, _THREAD_SIZE - 32 !! 408 */ 116 PTR_ADDU sp, $28 !! 409 117 back_to_back_c0_hazard !! 410 .org 0x4000 118 set_saved_sp sp, t0, t1 !! 411 ENTRY(empty_zero_page) 119 PTR_SUBU sp, 4 * SZREG !! 412 120 !! 413 .org 0x5000 121 #ifdef CONFIG_RELOCATABLE !! 414 122 /* Copy kernel and apply the relocatio !! 415 /* 123 jal relocate_kernel !! 416 * Real beginning of normal "text" segment 124 !! 417 */ 125 /* Repoint the sp into the new kernel !! 418 ENTRY(stext) 126 PTR_LI sp, _THREAD_SIZE - 32 !! 419 ENTRY(_stext) 127 PTR_ADDU sp, $28 !! 420 128 set_saved_sp sp, t0, t1 !! 421 /* 129 PTR_SUBU sp, 4 * SZREG !! 422 * This starts the data section. Note that the above is all >> 423 * in the text section because it has alignment requirements >> 424 * that we cannot fulfill any other way. >> 425 */ >> 426 .data 130 427 >> 428 /* >> 429 * The Global Descriptor Table contains 28 quadwords, per-CPU. >> 430 */ >> 431 #if defined(CONFIG_SMP) || defined(CONFIG_X86_VISWS) >> 432 /* >> 433 * The boot_gdt_table must mirror the equivalent in setup.S and is >> 434 * used only by the trampoline for booting other CPUs >> 435 */ >> 436 .align L1_CACHE_BYTES >> 437 ENTRY(boot_gdt_table) >> 438 .fill GDT_ENTRY_BOOT_CS,8,0 >> 439 .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ >> 440 .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ >> 441 #endif >> 442 .align L1_CACHE_BYTES >> 443 ENTRY(cpu_gdt_table) >> 444 .quad 0x0000000000000000 /* NULL descriptor */ >> 445 .quad 0x0000000000000000 /* 0x0b reserved */ >> 446 .quad 0x0000000000000000 /* 0x13 reserved */ >> 447 .quad 0x0000000000000000 /* 0x1b reserved */ >> 448 .quad 0x0000000000000000 /* 0x20 unused */ >> 449 .quad 0x0000000000000000 /* 0x28 unused */ >> 450 .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ >> 451 .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ >> 452 .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ >> 453 .quad 0x0000000000000000 /* 0x4b reserved */ >> 454 .quad 0x0000000000000000 /* 0x53 reserved */ >> 455 .quad 0x0000000000000000 /* 0x5b reserved */ >> 456 >> 457 .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ >> 458 .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ >> 459 .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */ >> 460 .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */ >> 461 >> 462 .quad 0x0000000000000000 /* 0x80 TSS descriptor */ >> 463 .quad 0x0000000000000000 /* 0x88 LDT descriptor */ >> 464 >> 465 /* Segments used for calling PnP BIOS */ >> 466 .quad 0x00c09a0000000000 /* 0x90 32-bit code */ >> 467 .quad 0x00809a0000000000 /* 0x98 16-bit code */ >> 468 .quad 0x0080920000000000 /* 0xa0 16-bit data */ >> 469 .quad 0x0080920000000000 /* 0xa8 16-bit data */ >> 470 .quad 0x0080920000000000 /* 0xb0 16-bit data */ 131 /* 471 /* 132 * relocate_kernel returns the entry p !! 472 * The APM segments have byte granularity and their bases 133 * in the relocated kernel or the orig !! 473 * and limits are set at run time. 134 * some reason relocation failed - jum << 135 * with instruction hazard barrier bec << 136 * newly sync'd icache. << 137 */ 474 */ 138 jr.hb v0 !! 475 .quad 0x00409a0000000000 /* 0xb8 APM CS code */ 139 #else /* !CONFIG_RELOCATABLE */ !! 476 .quad 0x00009a0000000000 /* 0xc0 APM CS 16 code (16 bit) */ 140 j start_kernel !! 477 .quad 0x0040920000000000 /* 0xc8 APM DS data */ 141 #endif /* !CONFIG_RELOCATABLE */ !! 478 142 END(kernel_entry) !! 479 .quad 0x0000000000000000 /* 0xd0 - unused */ >> 480 .quad 0x0000000000000000 /* 0xd8 - unused */ >> 481 .quad 0x0000000000000000 /* 0xe0 - unused */ >> 482 .quad 0x0000000000000000 /* 0xe8 - unused */ >> 483 .quad 0x0000000000000000 /* 0xf0 - unused */ >> 484 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ 143 485 144 #ifdef CONFIG_SMP 486 #ifdef CONFIG_SMP 145 /* !! 487 .fill (NR_CPUS-1)*GDT_ENTRIES,8,0 /* other CPU's GDT */ 146 * SMP slave cpus entry point. Board specific !! 488 #endif 147 * function after setting up the stack and gp !! 489 148 */ << 149 NESTED(smp_bootstrap, 16, sp) << 150 smp_slave_setup << 151 setup_c0_status_sec << 152 j start_secondary << 153 END(smp_bootstrap) << 154 #endif /* CONFIG_SMP */ <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.