misc.S 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. /*
  2. * This file contains miscellaneous low-level functions.
  3. * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  4. *
  5. * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
  6. * and Paul Mackerras.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version
  11. * 2 of the License, or (at your option) any later version.
  12. *
  13. */
  14. #include <linux/sys.h>
  15. #include <asm/unistd.h>
  16. #include <asm/errno.h>
  17. #include <asm/processor.h>
  18. #include <asm/page.h>
  19. #include <asm/cache.h>
  20. #include <asm/cputable.h>
  21. #include <asm/mmu.h>
  22. #include <asm/ppc_asm.h>
  23. #include <asm/thread_info.h>
  24. #include <asm/asm-offsets.h>
  25. #ifdef CONFIG_8xx
  26. #define ISYNC_8xx isync
  27. #else
  28. #define ISYNC_8xx
  29. #endif
  30. .text
  31. .align 5
  32. _GLOBAL(__delay)
  33. cmpwi 0,r3,0
  34. mtctr r3
  35. beqlr
  36. 1: bdnz 1b
  37. blr
  38. /*
  39. * Returns (address we're running at) - (address we were linked at)
  40. * for use before the text and data are mapped to KERNELBASE.
  41. */
  42. _GLOBAL(reloc_offset)
  43. mflr r0
  44. bl 1f
  45. 1: mflr r3
  46. lis r4,1b@ha
  47. addi r4,r4,1b@l
  48. subf r3,r4,r3
  49. mtlr r0
  50. blr
  51. /*
  52. * add_reloc_offset(x) returns x + reloc_offset().
  53. */
  54. _GLOBAL(add_reloc_offset)
  55. mflr r0
  56. bl 1f
  57. 1: mflr r5
  58. lis r4,1b@ha
  59. addi r4,r4,1b@l
  60. subf r5,r4,r5
  61. add r3,r3,r5
  62. mtlr r0
  63. blr
  64. /*
  65. * sub_reloc_offset(x) returns x - reloc_offset().
  66. */
  67. _GLOBAL(sub_reloc_offset)
  68. mflr r0
  69. bl 1f
  70. 1: mflr r5
  71. lis r4,1b@ha
  72. addi r4,r4,1b@l
  73. subf r5,r4,r5
  74. subf r3,r5,r3
  75. mtlr r0
  76. blr
  77. /*
  78. * reloc_got2 runs through the .got2 section adding an offset
  79. * to each entry.
  80. */
  81. _GLOBAL(reloc_got2)
  82. mflr r11
  83. lis r7,__got2_start@ha
  84. addi r7,r7,__got2_start@l
  85. lis r8,__got2_end@ha
  86. addi r8,r8,__got2_end@l
  87. subf r8,r7,r8
  88. srwi. r8,r8,2
  89. beqlr
  90. mtctr r8
  91. bl 1f
  92. 1: mflr r0
  93. lis r4,1b@ha
  94. addi r4,r4,1b@l
  95. subf r0,r4,r0
  96. add r7,r0,r7
  97. 2: lwz r0,0(r7)
  98. add r0,r0,r3
  99. stw r0,0(r7)
  100. addi r7,r7,4
  101. bdnz 2b
  102. mtlr r11
  103. blr
  104. /*
  105. * identify_cpu,
  106. * called with r3 = data offset and r4 = CPU number
  107. * doesn't change r3
  108. */
  109. _GLOBAL(identify_cpu)
  110. addis r8,r3,cpu_specs@ha
  111. addi r8,r8,cpu_specs@l
  112. mfpvr r7
  113. 1:
  114. lwz r5,CPU_SPEC_PVR_MASK(r8)
  115. and r5,r5,r7
  116. lwz r6,CPU_SPEC_PVR_VALUE(r8)
  117. cmplw 0,r6,r5
  118. beq 1f
  119. addi r8,r8,CPU_SPEC_ENTRY_SIZE
  120. b 1b
  121. 1:
  122. addis r6,r3,cur_cpu_spec@ha
  123. addi r6,r6,cur_cpu_spec@l
  124. sub r8,r8,r3
  125. stw r8,0(r6)
  126. blr
  127. /*
  128. * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
  129. * and writes nop's over sections of code that don't apply for this cpu.
  130. * r3 = data offset (not changed)
  131. */
  132. _GLOBAL(do_cpu_ftr_fixups)
  133. /* Get CPU 0 features */
  134. addis r6,r3,cur_cpu_spec@ha
  135. addi r6,r6,cur_cpu_spec@l
  136. lwz r4,0(r6)
  137. add r4,r4,r3
  138. lwz r4,CPU_SPEC_FEATURES(r4)
  139. /* Get the fixup table */
  140. addis r6,r3,__start___ftr_fixup@ha
  141. addi r6,r6,__start___ftr_fixup@l
  142. addis r7,r3,__stop___ftr_fixup@ha
  143. addi r7,r7,__stop___ftr_fixup@l
  144. /* Do the fixup */
  145. 1: cmplw 0,r6,r7
  146. bgelr
  147. addi r6,r6,16
  148. lwz r8,-16(r6) /* mask */
  149. and r8,r8,r4
  150. lwz r9,-12(r6) /* value */
  151. cmplw 0,r8,r9
  152. beq 1b
  153. lwz r8,-8(r6) /* section begin */
  154. lwz r9,-4(r6) /* section end */
  155. subf. r9,r8,r9
  156. beq 1b
  157. /* write nops over the section of code */
  158. /* todo: if large section, add a branch at the start of it */
  159. srwi r9,r9,2
  160. mtctr r9
  161. add r8,r8,r3
  162. lis r0,0x60000000@h /* nop */
  163. 3: stw r0,0(r8)
  164. andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
  165. beq 2f
  166. dcbst 0,r8 /* suboptimal, but simpler */
  167. sync
  168. icbi 0,r8
  169. 2: addi r8,r8,4
  170. bdnz 3b
  171. sync /* additional sync needed on g4 */
  172. isync
  173. b 1b
  174. /*
  175. * call_setup_cpu - call the setup_cpu function for this cpu
  176. * r3 = data offset, r24 = cpu number
  177. *
  178. * Setup function is called with:
  179. * r3 = data offset
  180. * r4 = ptr to CPU spec (relocated)
  181. */
  182. _GLOBAL(call_setup_cpu)
  183. addis r4,r3,cur_cpu_spec@ha
  184. addi r4,r4,cur_cpu_spec@l
  185. lwz r4,0(r4)
  186. add r4,r4,r3
  187. lwz r5,CPU_SPEC_SETUP(r4)
  188. cmpi 0,r5,0
  189. add r5,r5,r3
  190. beqlr
  191. mtctr r5
  192. bctr
  193. /*
  194. * complement mask on the msr then "or" some values on.
  195. * _nmask_and_or_msr(nmask, value_to_or)
  196. */
  197. _GLOBAL(_nmask_and_or_msr)
  198. mfmsr r0 /* Get current msr */
  199. andc r0,r0,r3 /* And off the bits set in r3 (first parm) */
  200. or r0,r0,r4 /* Or on the bits in r4 (second parm) */
  201. SYNC /* Some chip revs have problems here... */
  202. mtmsr r0 /* Update machine state */
  203. isync
  204. blr /* Done */
  205. /*
  206. * Flush MMU TLB
  207. */
  208. _GLOBAL(_tlbia)
  209. #if defined(CONFIG_40x)
  210. sync /* Flush to memory before changing mapping */
  211. tlbia
  212. isync /* Flush shadow TLB */
  213. #elif defined(CONFIG_44x)
  214. li r3,0
  215. sync
  216. /* Load high watermark */
  217. lis r4,tlb_44x_hwater@ha
  218. lwz r5,tlb_44x_hwater@l(r4)
  219. 1: tlbwe r3,r3,PPC44x_TLB_PAGEID
  220. addi r3,r3,1
  221. cmpw 0,r3,r5
  222. ble 1b
  223. isync
  224. #elif defined(CONFIG_FSL_BOOKE)
  225. /* Invalidate all entries in TLB0 */
  226. li r3, 0x04
  227. tlbivax 0,3
  228. /* Invalidate all entries in TLB1 */
  229. li r3, 0x0c
  230. tlbivax 0,3
  231. /* Invalidate all entries in TLB2 */
  232. li r3, 0x14
  233. tlbivax 0,3
  234. /* Invalidate all entries in TLB3 */
  235. li r3, 0x1c
  236. tlbivax 0,3
  237. msync
  238. #ifdef CONFIG_SMP
  239. tlbsync
  240. #endif /* CONFIG_SMP */
  241. #else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
  242. #if defined(CONFIG_SMP)
  243. rlwinm r8,r1,0,0,18
  244. lwz r8,TI_CPU(r8)
  245. oris r8,r8,10
  246. mfmsr r10
  247. SYNC
  248. rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
  249. rlwinm r0,r0,0,28,26 /* clear DR */
  250. mtmsr r0
  251. SYNC_601
  252. isync
  253. lis r9,mmu_hash_lock@h
  254. ori r9,r9,mmu_hash_lock@l
  255. tophys(r9,r9)
  256. 10: lwarx r7,0,r9
  257. cmpwi 0,r7,0
  258. bne- 10b
  259. stwcx. r8,0,r9
  260. bne- 10b
  261. sync
  262. tlbia
  263. sync
  264. TLBSYNC
  265. li r0,0
  266. stw r0,0(r9) /* clear mmu_hash_lock */
  267. mtmsr r10
  268. SYNC_601
  269. isync
  270. #else /* CONFIG_SMP */
  271. sync
  272. tlbia
  273. sync
  274. #endif /* CONFIG_SMP */
  275. #endif /* ! defined(CONFIG_40x) */
  276. blr
  277. /*
  278. * Flush MMU TLB for a particular address
  279. */
  280. _GLOBAL(_tlbie)
  281. #if defined(CONFIG_40x)
  282. tlbsx. r3, 0, r3
  283. bne 10f
  284. sync
  285. /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
  286. * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate
  287. * the TLB entry. */
  288. tlbwe r3, r3, TLB_TAG
  289. isync
  290. 10:
  291. #elif defined(CONFIG_44x)
  292. mfspr r4,SPRN_MMUCR
  293. mfspr r5,SPRN_PID /* Get PID */
  294. rlwimi r4,r5,0,24,31 /* Set TID */
  295. mtspr SPRN_MMUCR,r4
  296. tlbsx. r3, 0, r3
  297. bne 10f
  298. sync
  299. /* There are only 64 TLB entries, so r3 < 64,
  300. * which means bit 22, is clear. Since 22 is
  301. * the V bit in the TLB_PAGEID, loading this
  302. * value will invalidate the TLB entry.
  303. */
  304. tlbwe r3, r3, PPC44x_TLB_PAGEID
  305. isync
  306. 10:
  307. #elif defined(CONFIG_FSL_BOOKE)
  308. rlwinm r4, r3, 0, 0, 19
  309. ori r5, r4, 0x08 /* TLBSEL = 1 */
  310. ori r6, r4, 0x10 /* TLBSEL = 2 */
  311. ori r7, r4, 0x18 /* TLBSEL = 3 */
  312. tlbivax 0, r4
  313. tlbivax 0, r5
  314. tlbivax 0, r6
  315. tlbivax 0, r7
  316. msync
  317. #if defined(CONFIG_SMP)
  318. tlbsync
  319. #endif /* CONFIG_SMP */
  320. #else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
  321. #if defined(CONFIG_SMP)
  322. rlwinm r8,r1,0,0,18
  323. lwz r8,TI_CPU(r8)
  324. oris r8,r8,11
  325. mfmsr r10
  326. SYNC
  327. rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
  328. rlwinm r0,r0,0,28,26 /* clear DR */
  329. mtmsr r0
  330. SYNC_601
  331. isync
  332. lis r9,mmu_hash_lock@h
  333. ori r9,r9,mmu_hash_lock@l
  334. tophys(r9,r9)
  335. 10: lwarx r7,0,r9
  336. cmpwi 0,r7,0
  337. bne- 10b
  338. stwcx. r8,0,r9
  339. bne- 10b
  340. eieio
  341. tlbie r3
  342. sync
  343. TLBSYNC
  344. li r0,0
  345. stw r0,0(r9) /* clear mmu_hash_lock */
  346. mtmsr r10
  347. SYNC_601
  348. isync
  349. #else /* CONFIG_SMP */
  350. tlbie r3
  351. sync
  352. #endif /* CONFIG_SMP */
  353. #endif /* ! CONFIG_40x */
  354. blr
  355. /*
  356. * Flush instruction cache.
  357. * This is a no-op on the 601.
  358. */
  359. _GLOBAL(flush_instruction_cache)
  360. #if defined(CONFIG_8xx)
  361. isync
  362. lis r5, IDC_INVALL@h
  363. mtspr SPRN_IC_CST, r5
  364. #elif defined(CONFIG_4xx)
  365. #ifdef CONFIG_403GCX
  366. li r3, 512
  367. mtctr r3
  368. lis r4, KERNELBASE@h
  369. 1: iccci 0, r4
  370. addi r4, r4, 16
  371. bdnz 1b
  372. #else
  373. lis r3, KERNELBASE@h
  374. iccci 0,r3
  375. #endif
  376. #elif CONFIG_FSL_BOOKE
  377. BEGIN_FTR_SECTION
  378. mfspr r3,SPRN_L1CSR0
  379. ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC
  380. /* msync; isync recommended here */
  381. mtspr SPRN_L1CSR0,r3
  382. isync
  383. blr
  384. END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
  385. mfspr r3,SPRN_L1CSR1
  386. ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
  387. mtspr SPRN_L1CSR1,r3
  388. #else
  389. mfspr r3,SPRN_PVR
  390. rlwinm r3,r3,16,16,31
  391. cmpwi 0,r3,1
  392. beqlr /* for 601, do nothing */
  393. /* 603/604 processor - use invalidate-all bit in HID0 */
  394. mfspr r3,SPRN_HID0
  395. ori r3,r3,HID0_ICFI
  396. mtspr SPRN_HID0,r3
  397. #endif /* CONFIG_8xx/4xx */
  398. isync
  399. blr
  400. /*
  401. * Write any modified data cache blocks out to memory
  402. * and invalidate the corresponding instruction cache blocks.
  403. * This is a no-op on the 601.
  404. *
  405. * __flush_icache_range(unsigned long start, unsigned long stop)
  406. */
  407. _GLOBAL(__flush_icache_range)
  408. BEGIN_FTR_SECTION
  409. blr /* for 601, do nothing */
  410. END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
  411. li r5,L1_CACHE_BYTES-1
  412. andc r3,r3,r5
  413. subf r4,r3,r4
  414. add r4,r4,r5
  415. srwi. r4,r4,L1_CACHE_SHIFT
  416. beqlr
  417. mtctr r4
  418. mr r6,r3
  419. 1: dcbst 0,r3
  420. addi r3,r3,L1_CACHE_BYTES
  421. bdnz 1b
  422. sync /* wait for dcbst's to get to ram */
  423. mtctr r4
  424. 2: icbi 0,r6
  425. addi r6,r6,L1_CACHE_BYTES
  426. bdnz 2b
  427. sync /* additional sync needed on g4 */
  428. isync
  429. blr
  430. /*
  431. * Write any modified data cache blocks out to memory.
  432. * Does not invalidate the corresponding cache lines (especially for
  433. * any corresponding instruction cache).
  434. *
  435. * clean_dcache_range(unsigned long start, unsigned long stop)
  436. */
  437. _GLOBAL(clean_dcache_range)
  438. li r5,L1_CACHE_BYTES-1
  439. andc r3,r3,r5
  440. subf r4,r3,r4
  441. add r4,r4,r5
  442. srwi. r4,r4,L1_CACHE_SHIFT
  443. beqlr
  444. mtctr r4
  445. 1: dcbst 0,r3
  446. addi r3,r3,L1_CACHE_BYTES
  447. bdnz 1b
  448. sync /* wait for dcbst's to get to ram */
  449. blr
  450. /*
  451. * Write any modified data cache blocks out to memory and invalidate them.
  452. * Does not invalidate the corresponding instruction cache blocks.
  453. *
  454. * flush_dcache_range(unsigned long start, unsigned long stop)
  455. */
  456. _GLOBAL(flush_dcache_range)
  457. li r5,L1_CACHE_BYTES-1
  458. andc r3,r3,r5
  459. subf r4,r3,r4
  460. add r4,r4,r5
  461. srwi. r4,r4,L1_CACHE_SHIFT
  462. beqlr
  463. mtctr r4
  464. 1: dcbf 0,r3
  465. addi r3,r3,L1_CACHE_BYTES
  466. bdnz 1b
  467. sync /* wait for dcbst's to get to ram */
  468. blr
  469. /*
  470. * Like above, but invalidate the D-cache. This is used by the 8xx
  471. * to invalidate the cache so the PPC core doesn't get stale data
  472. * from the CPM (no cache snooping here :-).
  473. *
  474. * invalidate_dcache_range(unsigned long start, unsigned long stop)
  475. */
  476. _GLOBAL(invalidate_dcache_range)
  477. li r5,L1_CACHE_BYTES-1
  478. andc r3,r3,r5
  479. subf r4,r3,r4
  480. add r4,r4,r5
  481. srwi. r4,r4,L1_CACHE_SHIFT
  482. beqlr
  483. mtctr r4
  484. 1: dcbi 0,r3
  485. addi r3,r3,L1_CACHE_BYTES
  486. bdnz 1b
  487. sync /* wait for dcbi's to get to ram */
  488. blr
  489. #ifdef CONFIG_NOT_COHERENT_CACHE
  490. /*
  491. * 40x cores have 8K or 16K dcache and 32 byte line size.
  492. * 44x has a 32K dcache and 32 byte line size.
  493. * 8xx has 1, 2, 4, 8K variants.
  494. * For now, cover the worst case of the 44x.
  495. * Must be called with external interrupts disabled.
  496. */
  497. #define CACHE_NWAYS 64
  498. #define CACHE_NLINES 16
  499. _GLOBAL(flush_dcache_all)
  500. li r4, (2 * CACHE_NWAYS * CACHE_NLINES)
  501. mtctr r4
  502. lis r5, KERNELBASE@h
  503. 1: lwz r3, 0(r5) /* Load one word from every line */
  504. addi r5, r5, L1_CACHE_BYTES
  505. bdnz 1b
  506. blr
  507. #endif /* CONFIG_NOT_COHERENT_CACHE */
  508. /*
  509. * Flush a particular page from the data cache to RAM.
  510. * Note: this is necessary because the instruction cache does *not*
  511. * snoop from the data cache.
  512. * This is a no-op on the 601 which has a unified cache.
  513. *
  514. * void __flush_dcache_icache(void *page)
  515. */
  516. _GLOBAL(__flush_dcache_icache)
  517. BEGIN_FTR_SECTION
  518. blr /* for 601, do nothing */
  519. END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
  520. rlwinm r3,r3,0,0,19 /* Get page base address */
  521. li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
  522. mtctr r4
  523. mr r6,r3
  524. 0: dcbst 0,r3 /* Write line to ram */
  525. addi r3,r3,L1_CACHE_BYTES
  526. bdnz 0b
  527. sync
  528. mtctr r4
  529. 1: icbi 0,r6
  530. addi r6,r6,L1_CACHE_BYTES
  531. bdnz 1b
  532. sync
  533. isync
  534. blr
  535. /*
  536. * Flush a particular page from the data cache to RAM, identified
  537. * by its physical address. We turn off the MMU so we can just use
  538. * the physical address (this may be a highmem page without a kernel
  539. * mapping).
  540. *
  541. * void __flush_dcache_icache_phys(unsigned long physaddr)
  542. */
  543. _GLOBAL(__flush_dcache_icache_phys)
  544. BEGIN_FTR_SECTION
  545. blr /* for 601, do nothing */
  546. END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
  547. mfmsr r10
  548. rlwinm r0,r10,0,28,26 /* clear DR */
  549. mtmsr r0
  550. isync
  551. rlwinm r3,r3,0,0,19 /* Get page base address */
  552. li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
  553. mtctr r4
  554. mr r6,r3
  555. 0: dcbst 0,r3 /* Write line to ram */
  556. addi r3,r3,L1_CACHE_BYTES
  557. bdnz 0b
  558. sync
  559. mtctr r4
  560. 1: icbi 0,r6
  561. addi r6,r6,L1_CACHE_BYTES
  562. bdnz 1b
  563. sync
  564. mtmsr r10 /* restore DR */
  565. isync
  566. blr
  567. /*
  568. * Clear pages using the dcbz instruction, which doesn't cause any
  569. * memory traffic (except to write out any cache lines which get
  570. * displaced). This only works on cacheable memory.
  571. *
  572. * void clear_pages(void *page, int order) ;
  573. */
  574. _GLOBAL(clear_pages)
  575. li r0,4096/L1_CACHE_BYTES
  576. slw r0,r0,r4
  577. mtctr r0
  578. #ifdef CONFIG_8xx
  579. li r4, 0
  580. 1: stw r4, 0(r3)
  581. stw r4, 4(r3)
  582. stw r4, 8(r3)
  583. stw r4, 12(r3)
  584. #else
  585. 1: dcbz 0,r3
  586. #endif
  587. addi r3,r3,L1_CACHE_BYTES
  588. bdnz 1b
  589. blr
  590. /*
  591. * Copy a whole page. We use the dcbz instruction on the destination
  592. * to reduce memory traffic (it eliminates the unnecessary reads of
  593. * the destination into cache). This requires that the destination
  594. * is cacheable.
  595. */
  596. #define COPY_16_BYTES \
  597. lwz r6,4(r4); \
  598. lwz r7,8(r4); \
  599. lwz r8,12(r4); \
  600. lwzu r9,16(r4); \
  601. stw r6,4(r3); \
  602. stw r7,8(r3); \
  603. stw r8,12(r3); \
  604. stwu r9,16(r3)
  605. _GLOBAL(copy_page)
  606. addi r3,r3,-4
  607. addi r4,r4,-4
  608. #ifdef CONFIG_8xx
  609. /* don't use prefetch on 8xx */
  610. li r0,4096/L1_CACHE_BYTES
  611. mtctr r0
  612. 1: COPY_16_BYTES
  613. bdnz 1b
  614. blr
  615. #else /* not 8xx, we can prefetch */
  616. li r5,4
  617. #if MAX_COPY_PREFETCH > 1
  618. li r0,MAX_COPY_PREFETCH
  619. li r11,4
  620. mtctr r0
  621. 11: dcbt r11,r4
  622. addi r11,r11,L1_CACHE_BYTES
  623. bdnz 11b
  624. #else /* MAX_COPY_PREFETCH == 1 */
  625. dcbt r5,r4
  626. li r11,L1_CACHE_BYTES+4
  627. #endif /* MAX_COPY_PREFETCH */
  628. li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
  629. crclr 4*cr0+eq
  630. 2:
  631. mtctr r0
  632. 1:
  633. dcbt r11,r4
  634. dcbz r5,r3
  635. COPY_16_BYTES
  636. #if L1_CACHE_BYTES >= 32
  637. COPY_16_BYTES
  638. #if L1_CACHE_BYTES >= 64
  639. COPY_16_BYTES
  640. COPY_16_BYTES
  641. #if L1_CACHE_BYTES >= 128
  642. COPY_16_BYTES
  643. COPY_16_BYTES
  644. COPY_16_BYTES
  645. COPY_16_BYTES
  646. #endif
  647. #endif
  648. #endif
  649. bdnz 1b
  650. beqlr
  651. crnot 4*cr0+eq,4*cr0+eq
  652. li r0,MAX_COPY_PREFETCH
  653. li r11,4
  654. b 2b
  655. #endif /* CONFIG_8xx */
  656. /*
  657. * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
  658. * void atomic_set_mask(atomic_t mask, atomic_t *addr);
  659. */
  660. _GLOBAL(atomic_clear_mask)
  661. 10: lwarx r5,0,r4
  662. andc r5,r5,r3
  663. PPC405_ERR77(0,r4)
  664. stwcx. r5,0,r4
  665. bne- 10b
  666. blr
  667. _GLOBAL(atomic_set_mask)
  668. 10: lwarx r5,0,r4
  669. or r5,r5,r3
  670. PPC405_ERR77(0,r4)
  671. stwcx. r5,0,r4
  672. bne- 10b
  673. blr
  674. /*
  675. * I/O string operations
  676. *
  677. * insb(port, buf, len)
  678. * outsb(port, buf, len)
  679. * insw(port, buf, len)
  680. * outsw(port, buf, len)
  681. * insl(port, buf, len)
  682. * outsl(port, buf, len)
  683. * insw_ns(port, buf, len)
  684. * outsw_ns(port, buf, len)
  685. * insl_ns(port, buf, len)
  686. * outsl_ns(port, buf, len)
  687. *
  688. * The *_ns versions don't do byte-swapping.
  689. */
  690. _GLOBAL(_insb)
  691. cmpwi 0,r5,0
  692. mtctr r5
  693. subi r4,r4,1
  694. blelr-
  695. 00: lbz r5,0(r3)
  696. 01: eieio
  697. 02: stbu r5,1(r4)
  698. ISYNC_8xx
  699. .section .fixup,"ax"
  700. 03: blr
  701. .text
  702. .section __ex_table, "a"
  703. .align 2
  704. .long 00b, 03b
  705. .long 01b, 03b
  706. .long 02b, 03b
  707. .text
  708. bdnz 00b
  709. blr
  710. _GLOBAL(_outsb)
  711. cmpwi 0,r5,0
  712. mtctr r5
  713. subi r4,r4,1
  714. blelr-
  715. 00: lbzu r5,1(r4)
  716. 01: stb r5,0(r3)
  717. 02: eieio
  718. ISYNC_8xx
  719. .section .fixup,"ax"
  720. 03: blr
  721. .text
  722. .section __ex_table, "a"
  723. .align 2
  724. .long 00b, 03b
  725. .long 01b, 03b
  726. .long 02b, 03b
  727. .text
  728. bdnz 00b
  729. blr
  730. _GLOBAL(_insw_ns)
  731. cmpwi 0,r5,0
  732. mtctr r5
  733. subi r4,r4,2
  734. blelr-
  735. 00: lhz r5,0(r3)
  736. 01: eieio
  737. 02: sthu r5,2(r4)
  738. ISYNC_8xx
  739. .section .fixup,"ax"
  740. 03: blr
  741. .text
  742. .section __ex_table, "a"
  743. .align 2
  744. .long 00b, 03b
  745. .long 01b, 03b
  746. .long 02b, 03b
  747. .text
  748. bdnz 00b
  749. blr
  750. _GLOBAL(_outsw_ns)
  751. cmpwi 0,r5,0
  752. mtctr r5
  753. subi r4,r4,2
  754. blelr-
  755. 00: lhzu r5,2(r4)
  756. 01: sth r5,0(r3)
  757. 02: eieio
  758. ISYNC_8xx
  759. .section .fixup,"ax"
  760. 03: blr
  761. .text
  762. .section __ex_table, "a"
  763. .align 2
  764. .long 00b, 03b
  765. .long 01b, 03b
  766. .long 02b, 03b
  767. .text
  768. bdnz 00b
  769. blr
  770. _GLOBAL(_insl_ns)
  771. cmpwi 0,r5,0
  772. mtctr r5
  773. subi r4,r4,4
  774. blelr-
  775. 00: lwz r5,0(r3)
  776. 01: eieio
  777. 02: stwu r5,4(r4)
  778. ISYNC_8xx
  779. .section .fixup,"ax"
  780. 03: blr
  781. .text
  782. .section __ex_table, "a"
  783. .align 2
  784. .long 00b, 03b
  785. .long 01b, 03b
  786. .long 02b, 03b
  787. .text
  788. bdnz 00b
  789. blr
  790. _GLOBAL(_outsl_ns)
  791. cmpwi 0,r5,0
  792. mtctr r5
  793. subi r4,r4,4
  794. blelr-
  795. 00: lwzu r5,4(r4)
  796. 01: stw r5,0(r3)
  797. 02: eieio
  798. ISYNC_8xx
  799. .section .fixup,"ax"
  800. 03: blr
  801. .text
  802. .section __ex_table, "a"
  803. .align 2
  804. .long 00b, 03b
  805. .long 01b, 03b
  806. .long 02b, 03b
  807. .text
  808. bdnz 00b
  809. blr
  810. /*
  811. * Extended precision shifts.
  812. *
  813. * Updated to be valid for shift counts from 0 to 63 inclusive.
  814. * -- Gabriel
  815. *
  816. * R3/R4 has 64 bit value
  817. * R5 has shift count
  818. * result in R3/R4
  819. *
  820. * ashrdi3: arithmetic right shift (sign propagation)
  821. * lshrdi3: logical right shift
  822. * ashldi3: left shift
  823. */
  824. _GLOBAL(__ashrdi3)
  825. subfic r6,r5,32
  826. srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
  827. addi r7,r5,32 # could be xori, or addi with -32
  828. slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
  829. rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0
  830. sraw r7,r3,r7 # t2 = MSW >> (count-32)
  831. or r4,r4,r6 # LSW |= t1
  832. slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2
  833. sraw r3,r3,r5 # MSW = MSW >> count
  834. or r4,r4,r7 # LSW |= t2
  835. blr
  836. _GLOBAL(__ashldi3)
  837. subfic r6,r5,32
  838. slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count
  839. addi r7,r5,32 # could be xori, or addi with -32
  840. srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count)
  841. slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32)
  842. or r3,r3,r6 # MSW |= t1
  843. slw r4,r4,r5 # LSW = LSW << count
  844. or r3,r3,r7 # MSW |= t2
  845. blr
  846. _GLOBAL(__lshrdi3)
  847. subfic r6,r5,32
  848. srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
  849. addi r7,r5,32 # could be xori, or addi with -32
  850. slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
  851. srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32)
  852. or r4,r4,r6 # LSW |= t1
  853. srw r3,r3,r5 # MSW = MSW >> count
  854. or r4,r4,r7 # LSW |= t2
  855. blr
  856. _GLOBAL(abs)
  857. srawi r4,r3,31
  858. xor r3,r3,r4
  859. sub r3,r3,r4
  860. blr
  861. _GLOBAL(_get_SP)
  862. mr r3,r1 /* Close enough */
  863. blr
  864. /*
  865. * Create a kernel thread
  866. * kernel_thread(fn, arg, flags)
  867. */
  868. _GLOBAL(kernel_thread)
  869. stwu r1,-16(r1)
  870. stw r30,8(r1)
  871. stw r31,12(r1)
  872. mr r30,r3 /* function */
  873. mr r31,r4 /* argument */
  874. ori r3,r5,CLONE_VM /* flags */
  875. oris r3,r3,CLONE_UNTRACED>>16
  876. li r4,0 /* new sp (unused) */
  877. li r0,__NR_clone
  878. sc
  879. cmpwi 0,r3,0 /* parent or child? */
  880. bne 1f /* return if parent */
  881. li r0,0 /* make top-level stack frame */
  882. stwu r0,-16(r1)
  883. mtlr r30 /* fn addr in lr */
  884. mr r3,r31 /* load arg and call fn */
  885. PPC440EP_ERR42
  886. blrl
  887. li r0,__NR_exit /* exit if function returns */
  888. li r3,0
  889. sc
  890. 1: lwz r30,8(r1)
  891. lwz r31,12(r1)
  892. addi r1,r1,16
  893. blr
  894. _GLOBAL(kernel_execve)
  895. li r0,__NR_execve
  896. sc
  897. bnslr
  898. neg r3,r3
  899. blr
  900. /*
  901. * This routine is just here to keep GCC happy - sigh...
  902. */
  903. _GLOBAL(__main)
  904. blr