sun4c.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:61k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: sun4c.c,v 1.210 2001/11/13 03:27:47 davem Exp $
  2.  * sun4c.c: Doing in software what should be done in hardware.
  3.  *
  4.  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  5.  * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
  6.  * Copyright (C) 1996 Andrew Tridgell (Andrew.Tridgell@anu.edu.au)
  7.  * Copyright (C) 1997-2000 Anton Blanchard (anton@samba.org)
  8.  * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  9.  */
  10. #define NR_TASK_BUCKETS 512
  11. #include <linux/config.h>
  12. #include <linux/kernel.h>
  13. #include <linux/mm.h>
  14. #include <linux/init.h>
  15. #include <linux/bootmem.h>
  16. #include <linux/highmem.h>
  17. #include <linux/fs.h>
  18. #include <linux/seq_file.h>
  19. #include <asm/scatterlist.h>
  20. #include <asm/page.h>
  21. #include <asm/pgalloc.h>
  22. #include <asm/pgtable.h>
  23. #include <asm/vaddrs.h>
  24. #include <asm/idprom.h>
  25. #include <asm/machines.h>
  26. #include <asm/memreg.h>
  27. #include <asm/processor.h>
  28. #include <asm/auxio.h>
  29. #include <asm/io.h>
  30. #include <asm/oplib.h>
  31. #include <asm/openprom.h>
  32. #include <asm/mmu_context.h>
  33. #include <asm/sun4paddr.h>
  34. #include <asm/highmem.h>
  35. #include <asm/btfixup.h>
  36. /* Because of our dynamic kernel TLB miss strategy, and how
  37.  * our DVMA mapping allocation works, you _MUST_:
  38.  *
  39.  * 1) Disable interrupts _and_ not touch any dynamic kernel
  40.  *    memory while messing with kernel MMU state.  By
  41.  *    dynamic memory I mean any object which is not in
  42.  *    the kernel image itself or a task_struct (both of
  43.  *    which are locked into the MMU).
  44.  * 2) Disable interrupts while messing with user MMU state.
  45.  */
  46. extern int num_segmaps, num_contexts;
  47. extern unsigned long page_kernel;
  48. #ifdef CONFIG_SUN4
  49. #define SUN4C_VAC_SIZE sun4c_vacinfo.num_bytes
  50. #else
  51. /* That's it, we prom_halt() on sun4c if the cache size is something other than 65536.
  52.  * So let's save some cycles and just use that everywhere except for that bootup
  53.  * sanity check.
  54.  */
  55. #define SUN4C_VAC_SIZE 65536
  56. #endif
  57. #define SUN4C_KERNEL_BUCKETS 32
  58. /* Flushing the cache. */
  59. struct sun4c_vac_props sun4c_vacinfo;
  60. unsigned long sun4c_kernel_faults;
  61. /* Invalidate every sun4c cache line tag. */
  62. static void __init sun4c_flush_all(void)
  63. {
  64. unsigned long begin, end;
  65. if (sun4c_vacinfo.on)
  66. panic("SUN4C: AIEEE, trying to invalidate vac while it is on.");
  67. /* Clear 'valid' bit in all cache line tags */
  68. begin = AC_CACHETAGS;
  69. end = (AC_CACHETAGS + SUN4C_VAC_SIZE);
  70. while (begin < end) {
  71. __asm__ __volatile__("sta %%g0, [%0] %1nt" : :
  72.      "r" (begin), "i" (ASI_CONTROL));
  73. begin += sun4c_vacinfo.linesize;
  74. }
  75. }
  76. static void sun4c_flush_context_hw(void)
  77. {
  78. unsigned long end = SUN4C_VAC_SIZE;
  79. __asm__ __volatile__(
  80. "1: addcc %0, -4096, %0nt"
  81. " bne 1bnt"
  82. "  sta %%g0, [%0] %2"
  83. : "=&r" (end)
  84. : "0" (end), "i" (ASI_HWFLUSHCONTEXT)
  85. : "cc");
  86. }
  87. /* Must be called minimally with IRQs disabled. */
  88. static void sun4c_flush_segment_hw(unsigned long addr)
  89. {
  90. if (sun4c_get_segmap(addr) != invalid_segment) {
  91. unsigned long vac_size = SUN4C_VAC_SIZE;
  92. __asm__ __volatile__(
  93. "1: addcc %0, -4096, %0nt"
  94. " bne 1bnt"
  95. "  sta %%g0, [%2 + %0] %3"
  96. : "=&r" (vac_size)
  97. : "0" (vac_size), "r" (addr), "i" (ASI_HWFLUSHSEG)
  98. : "cc");
  99. }
  100. }
  101. /* File local boot time fixups. */
  102. BTFIXUPDEF_CALL(void, sun4c_flush_page, unsigned long)
  103. BTFIXUPDEF_CALL(void, sun4c_flush_segment, unsigned long)
  104. BTFIXUPDEF_CALL(void, sun4c_flush_context, void)
  105. #define sun4c_flush_page(addr) BTFIXUP_CALL(sun4c_flush_page)(addr)
  106. #define sun4c_flush_segment(addr) BTFIXUP_CALL(sun4c_flush_segment)(addr)
  107. #define sun4c_flush_context() BTFIXUP_CALL(sun4c_flush_context)()
  108. /* Must be called minimally with interrupts disabled. */
  109. static void sun4c_flush_page_hw(unsigned long addr)
  110. {
  111. addr &= PAGE_MASK;
  112. if ((int)sun4c_get_pte(addr) < 0)
  113. __asm__ __volatile__("sta %%g0, [%0] %1"
  114.      : : "r" (addr), "i" (ASI_HWFLUSHPAGE));
  115. }
  116. /* Don't inline the software version as it eats too many cache lines if expanded. */
  117. static void sun4c_flush_context_sw(void)
  118. {
  119. unsigned long nbytes = SUN4C_VAC_SIZE;
  120. unsigned long lsize = sun4c_vacinfo.linesize;
  121. __asm__ __volatile__(
  122. "add %2, %2, %%g1nt"
  123. "add %2, %%g1, %%g2nt"
  124. "add %2, %%g2, %%g3nt"
  125. "add %2, %%g3, %%g4nt"
  126. "add %2, %%g4, %%g5nt"
  127. "add %2, %%g5, %%o4nt"
  128. "add %2, %%o4, %%o5n"
  129. "1:nt"
  130. "subcc %0, %%o5, %0nt"
  131. "sta %%g0, [%0] %3nt"
  132. "sta %%g0, [%0 + %2] %3nt"
  133. "sta %%g0, [%0 + %%g1] %3nt"
  134. "sta %%g0, [%0 + %%g2] %3nt"
  135. "sta %%g0, [%0 + %%g3] %3nt"
  136. "sta %%g0, [%0 + %%g4] %3nt"
  137. "sta %%g0, [%0 + %%g5] %3nt"
  138. "bg 1bnt"
  139. " sta %%g0, [%1 + %%o4] %3n"
  140. : "=&r" (nbytes)
  141. : "0" (nbytes), "r" (lsize), "i" (ASI_FLUSHCTX)
  142. : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc");
  143. }
  144. /* Don't inline the software version as it eats too many cache lines if expanded. */
  145. static void sun4c_flush_segment_sw(unsigned long addr)
  146. {
  147. if (sun4c_get_segmap(addr) != invalid_segment) {
  148. unsigned long nbytes = SUN4C_VAC_SIZE;
  149. unsigned long lsize = sun4c_vacinfo.linesize;
  150. __asm__ __volatile__(
  151. "add %2, %2, %%g1nt"
  152. "add %2, %%g1, %%g2nt"
  153. "add %2, %%g2, %%g3nt"
  154. "add %2, %%g3, %%g4nt"
  155. "add %2, %%g4, %%g5nt"
  156. "add %2, %%g5, %%o4nt"
  157. "add %2, %%o4, %%o5n"
  158. "1:nt"
  159. "subcc %1, %%o5, %1nt"
  160. "sta %%g0, [%0] %6nt"
  161. "sta %%g0, [%0 + %2] %6nt"
  162. "sta %%g0, [%0 + %%g1] %6nt"
  163. "sta %%g0, [%0 + %%g2] %6nt"
  164. "sta %%g0, [%0 + %%g3] %6nt"
  165. "sta %%g0, [%0 + %%g4] %6nt"
  166. "sta %%g0, [%0 + %%g5] %6nt"
  167. "sta %%g0, [%0 + %%o4] %6nt"
  168. "bg 1bnt"
  169. " add %0, %%o5, %0n"
  170. : "=&r" (addr), "=&r" (nbytes), "=&r" (lsize)
  171. : "0" (addr), "1" (nbytes), "2" (lsize),
  172.   "i" (ASI_FLUSHSEG)
  173. : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc");
  174. }
  175. }
  176. /* Don't inline the software version as it eats too many cache lines if expanded. */
  177. static void sun4c_flush_page_sw(unsigned long addr)
  178. {
  179. addr &= PAGE_MASK;
  180. if ((sun4c_get_pte(addr) & (_SUN4C_PAGE_NOCACHE | _SUN4C_PAGE_VALID)) ==
  181.     _SUN4C_PAGE_VALID) {
  182. unsigned long left = PAGE_SIZE;
  183. unsigned long lsize = sun4c_vacinfo.linesize;
  184. __asm__ __volatile__(
  185. "add %2, %2, %%g1nt"
  186. "add %2, %%g1, %%g2nt"
  187. "add %2, %%g2, %%g3nt"
  188. "add %2, %%g3, %%g4nt"
  189. "add %2, %%g4, %%g5nt"
  190. "add %2, %%g5, %%o4nt"
  191. "add %2, %%o4, %%o5n"
  192. "1:nt"
  193. "subcc %1, %%o5, %1nt"
  194. "sta %%g0, [%0] %6nt"
  195. "sta %%g0, [%0 + %2] %6nt"
  196. "sta %%g0, [%0 + %%g1] %6nt"
  197. "sta %%g0, [%0 + %%g2] %6nt"
  198. "sta %%g0, [%0 + %%g3] %6nt"
  199. "sta %%g0, [%0 + %%g4] %6nt"
  200. "sta %%g0, [%0 + %%g5] %6nt"
  201. "sta %%g0, [%0 + %%o4] %6nt"
  202. "bg 1bnt"
  203. " add %0, %%o5, %0n"
  204. : "=&r" (addr), "=&r" (left), "=&r" (lsize)
  205. : "0" (addr), "1" (left), "2" (lsize),
  206.   "i" (ASI_FLUSHPG)
  207. : "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc");
  208. }
  209. }
  210. /* The sun4c's do have an on chip store buffer.  And the way you
  211.  * clear them out isn't so obvious.  The only way I can think of
  212.  * to accomplish this is to read the current context register,
  213.  * store the same value there, then read an external hardware
  214.  * register.
  215.  */
  216. void sun4c_complete_all_stores(void)
  217. {
  218. volatile int _unused;
  219. _unused = sun4c_get_context();
  220. sun4c_set_context(_unused);
  221. #ifdef CONFIG_SUN_AUXIO
  222. _unused = *AUXREG;
  223. #endif
  224. }
  225. /* Bootup utility functions. */
  226. static inline void sun4c_init_clean_segmap(unsigned char pseg)
  227. {
  228. unsigned long vaddr;
  229. sun4c_put_segmap(0, pseg);
  230. for (vaddr = 0; vaddr < SUN4C_REAL_PGDIR_SIZE; vaddr += PAGE_SIZE)
  231. sun4c_put_pte(vaddr, 0);
  232. sun4c_put_segmap(0, invalid_segment);
  233. }
  234. static inline void sun4c_init_clean_mmu(unsigned long kernel_end)
  235. {
  236. unsigned long vaddr;
  237. unsigned char savectx, ctx;
  238. savectx = sun4c_get_context();
  239. kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end);
  240. for (ctx = 0; ctx < num_contexts; ctx++) {
  241. sun4c_set_context(ctx);
  242. for (vaddr = 0; vaddr < 0x20000000; vaddr += SUN4C_REAL_PGDIR_SIZE)
  243. sun4c_put_segmap(vaddr, invalid_segment);
  244. for (vaddr = 0xe0000000; vaddr < KERNBASE; vaddr += SUN4C_REAL_PGDIR_SIZE)
  245. sun4c_put_segmap(vaddr, invalid_segment);
  246. for (vaddr = kernel_end; vaddr < KADB_DEBUGGER_BEGVM; vaddr += SUN4C_REAL_PGDIR_SIZE)
  247. sun4c_put_segmap(vaddr, invalid_segment);
  248. for (vaddr = LINUX_OPPROM_ENDVM; vaddr; vaddr += SUN4C_REAL_PGDIR_SIZE)
  249. sun4c_put_segmap(vaddr, invalid_segment);
  250. }
  251. sun4c_set_context(savectx);
  252. }
  253. void __init sun4c_probe_vac(void)
  254. {
  255. sun4c_disable_vac();
  256. if (ARCH_SUN4) {
  257. switch (idprom->id_machtype) {
  258. case (SM_SUN4|SM_4_110):
  259. sun4c_vacinfo.type = NONE;
  260. sun4c_vacinfo.num_bytes = 0;
  261. sun4c_vacinfo.linesize = 0;
  262. sun4c_vacinfo.do_hwflushes = 0;
  263. prom_printf("No VAC. Get some bucks and buy a real computer.");
  264. prom_halt();
  265. break;
  266. case (SM_SUN4|SM_4_260):
  267. sun4c_vacinfo.type = WRITE_BACK;
  268. sun4c_vacinfo.num_bytes = 128 * 1024;
  269. sun4c_vacinfo.linesize = 16;
  270. sun4c_vacinfo.do_hwflushes = 0;
  271. break;
  272. case (SM_SUN4|SM_4_330):
  273. sun4c_vacinfo.type = WRITE_THROUGH;
  274. sun4c_vacinfo.num_bytes = 128 * 1024;
  275. sun4c_vacinfo.linesize = 16;
  276. sun4c_vacinfo.do_hwflushes = 0;
  277. break;
  278. case (SM_SUN4|SM_4_470):
  279. sun4c_vacinfo.type = WRITE_BACK;
  280. sun4c_vacinfo.num_bytes = 128 * 1024;
  281. sun4c_vacinfo.linesize = 32;
  282. sun4c_vacinfo.do_hwflushes = 0;
  283. break;
  284. default:
  285. prom_printf("Cannot initialize VAC - weird sun4 model idprom->id_machtype = %d", idprom->id_machtype);
  286. prom_halt();
  287. };
  288. } else {
  289. sun4c_vacinfo.type = WRITE_THROUGH;
  290. if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
  291.     (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
  292. /* PROM on SS1 lacks this info, to be super safe we
  293.  * hard code it here since this arch is cast in stone.
  294.  */
  295. sun4c_vacinfo.num_bytes = 65536;
  296. sun4c_vacinfo.linesize = 16;
  297. } else {
  298. sun4c_vacinfo.num_bytes =
  299.  prom_getintdefault(prom_root_node, "vac-size", 65536);
  300. sun4c_vacinfo.linesize =
  301.  prom_getintdefault(prom_root_node, "vac-linesize", 16);
  302. }
  303. sun4c_vacinfo.do_hwflushes =
  304.  prom_getintdefault(prom_root_node, "vac-hwflush", 0);
  305. if (sun4c_vacinfo.do_hwflushes == 0)
  306. sun4c_vacinfo.do_hwflushes =
  307.  prom_getintdefault(prom_root_node, "vac_hwflush", 0);
  308. if (sun4c_vacinfo.num_bytes != 65536) {
  309. prom_printf("WEIRD Sun4C VAC cache size, "
  310.     "tell sparclinux@vger.kernel.org");
  311. prom_halt();
  312. }
  313. }
  314. sun4c_vacinfo.num_lines =
  315. (sun4c_vacinfo.num_bytes / sun4c_vacinfo.linesize);
  316. switch (sun4c_vacinfo.linesize) {
  317. case 16:
  318. sun4c_vacinfo.log2lsize = 4;
  319. break;
  320. case 32:
  321. sun4c_vacinfo.log2lsize = 5;
  322. break;
  323. default:
  324. prom_printf("probe_vac: Didn't expect vac-linesize of %d, haltingn",
  325.     sun4c_vacinfo.linesize);
  326. prom_halt();
  327. };
  328. sun4c_flush_all();
  329. sun4c_enable_vac();
  330. }
  331. /* Patch instructions for the low level kernel fault handler. */
  332. extern unsigned long invalid_segment_patch1, invalid_segment_patch1_ff;
  333. extern unsigned long invalid_segment_patch2, invalid_segment_patch2_ff;
  334. extern unsigned long invalid_segment_patch1_1ff, invalid_segment_patch2_1ff;
  335. extern unsigned long num_context_patch1, num_context_patch1_16;
  336. extern unsigned long num_context_patch2, num_context_patch2_16;
  337. extern unsigned long vac_linesize_patch, vac_linesize_patch_32;
  338. extern unsigned long vac_hwflush_patch1, vac_hwflush_patch1_on;
  339. extern unsigned long vac_hwflush_patch2, vac_hwflush_patch2_on;
  340. #define PATCH_INSN(src, dst) do {
  341. daddr = &(dst);
  342. iaddr = &(src);
  343. *daddr = *iaddr;
  344. } while (0);
  345. static void __init patch_kernel_fault_handler(void)
  346. {
  347. unsigned long *iaddr, *daddr;
  348. switch (num_segmaps) {
  349. case 128:
  350. /* Default, nothing to do. */
  351. break;
  352. case 256:
  353. PATCH_INSN(invalid_segment_patch1_ff,
  354.    invalid_segment_patch1);
  355. PATCH_INSN(invalid_segment_patch2_ff,
  356.    invalid_segment_patch2);
  357. break;
  358. case 512:
  359. PATCH_INSN(invalid_segment_patch1_1ff,
  360.    invalid_segment_patch1);
  361. PATCH_INSN(invalid_segment_patch2_1ff,
  362.    invalid_segment_patch2);
  363. break;
  364. default:
  365. prom_printf("Unhandled number of segmaps: %dn",
  366.     num_segmaps);
  367. prom_halt();
  368. };
  369. switch (num_contexts) {
  370. case 8:
  371. /* Default, nothing to do. */
  372. break;
  373. case 16:
  374. PATCH_INSN(num_context_patch1_16,
  375.    num_context_patch1);
  376. break;
  377. default:
  378. prom_printf("Unhandled number of contexts: %dn",
  379.     num_contexts);
  380. prom_halt();
  381. };
  382. if (sun4c_vacinfo.do_hwflushes != 0) {
  383. PATCH_INSN(vac_hwflush_patch1_on, vac_hwflush_patch1);
  384. PATCH_INSN(vac_hwflush_patch2_on, vac_hwflush_patch2);
  385. } else {
  386. switch (sun4c_vacinfo.linesize) {
  387. case 16:
  388. /* Default, nothing to do. */
  389. break;
  390. case 32:
  391. PATCH_INSN(vac_linesize_patch_32, vac_linesize_patch);
  392. break;
  393. default:
  394. prom_printf("Impossible VAC linesize %d, halting...n",
  395.     sun4c_vacinfo.linesize);
  396. prom_halt();
  397. };
  398. }
  399. }
  400. static void __init sun4c_probe_mmu(void)
  401. {
  402. if (ARCH_SUN4) {
  403. switch (idprom->id_machtype) {
  404. case (SM_SUN4|SM_4_110):
  405. prom_printf("No support for 4100 yetn");
  406. prom_halt();
  407. num_segmaps = 256;
  408. num_contexts = 8;
  409. break;
  410. case (SM_SUN4|SM_4_260):
  411. /* should be 512 segmaps. when it get fixed */
  412. num_segmaps = 256;
  413. num_contexts = 16;
  414. break;
  415. case (SM_SUN4|SM_4_330):
  416. num_segmaps = 256;
  417. num_contexts = 16;
  418. break;
  419. case (SM_SUN4|SM_4_470):
  420. /* should be 1024 segmaps. when it get fixed */
  421. num_segmaps = 256;
  422. num_contexts = 64;
  423. break;
  424. default:
  425. prom_printf("Invalid SUN4 modeln");
  426. prom_halt();
  427. };
  428. } else {
  429. if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
  430.     (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
  431. /* Hardcode these just to be safe, PROM on SS1 does
  432.   * not have this info available in the root node.
  433.   */
  434. num_segmaps = 128;
  435. num_contexts = 8;
  436. } else {
  437. num_segmaps =
  438.     prom_getintdefault(prom_root_node, "mmu-npmg", 128);
  439. num_contexts =
  440.     prom_getintdefault(prom_root_node, "mmu-nctx", 0x8);
  441. }
  442. }
  443. patch_kernel_fault_handler();
  444. }
  445. volatile unsigned long *sun4c_memerr_reg = 0;
  446. void __init sun4c_probe_memerr_reg(void)
  447. {
  448. int node;
  449. struct linux_prom_registers regs[1];
  450. if (ARCH_SUN4) {
  451. sun4c_memerr_reg = ioremap(sun4_memreg_physaddr, PAGE_SIZE);
  452. } else {
  453. node = prom_getchild(prom_root_node);
  454. node = prom_searchsiblings(prom_root_node, "memory-error");
  455. if (!node)
  456. return;
  457. prom_getproperty(node, "reg", (char *)regs, sizeof(regs));
  458. /* hmm I think regs[0].which_io is zero here anyways */
  459. sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size);
  460. }
  461. }
  462. static inline void sun4c_init_ss2_cache_bug(void)
  463. {
  464. extern unsigned long start;
  465. if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) ||
  466.     (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) ||
  467.     (idprom->id_machtype == (SM_SUN4 | SM_4_330)) ||
  468.     (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) {
  469. /* Whee.. */
  470. printk("SS2 cache bug detected, uncaching trap table pagen");
  471. sun4c_flush_page((unsigned int) &start);
  472. sun4c_put_pte(((unsigned long) &start),
  473. (sun4c_get_pte((unsigned long) &start) | _SUN4C_PAGE_NOCACHE));
  474. }
  475. }
  476. /* Addr is always aligned on a page boundry for us already. */
  477. static void sun4c_map_dma_area(unsigned long va, u32 addr, int len)
  478. {
  479. unsigned long page, end;
  480. end = PAGE_ALIGN((addr + len));
  481. while (addr < end) {
  482. page = va;
  483. sun4c_flush_page(page);
  484. page -= PAGE_OFFSET;
  485. page >>= PAGE_SHIFT;
  486. page |= (_SUN4C_PAGE_VALID | _SUN4C_PAGE_DIRTY |
  487.  _SUN4C_PAGE_NOCACHE | _SUN4C_PAGE_PRIV);
  488. sun4c_put_pte(addr, page);
  489. addr += PAGE_SIZE;
  490. va += PAGE_SIZE;
  491. }
  492. }
  493. static unsigned long sun4c_translate_dvma(unsigned long busa)
  494. {
  495. /* Fortunately for us, bus_addr == uncached_virt in sun4c. */
  496. unsigned long pte = sun4c_get_pte(busa);
  497. return (pte << PAGE_SHIFT) + PAGE_OFFSET;
  498. }
  499. static void sun4c_unmap_dma_area(unsigned long busa, int len)
  500. {
  501. /* Fortunately for us, bus_addr == uncached_virt in sun4c. */
  502. /* XXX Implement this */
  503. }
  504. /* TLB management. */
  505. /* Don't change this struct without changing entry.S. This is used
  506.  * in the in-window kernel fault handler, and you don't want to mess
  507.  * with that. (See sun4c_fault in entry.S).
  508.  */
  509. struct sun4c_mmu_entry {
  510. struct sun4c_mmu_entry *next;
  511. struct sun4c_mmu_entry *prev;
  512. unsigned long vaddr;
  513. unsigned char pseg;
  514. unsigned char locked;
  515. /* For user mappings only, and completely hidden from kernel
  516.  * TLB miss code.
  517.  */
  518. unsigned char ctx;
  519. struct sun4c_mmu_entry *lru_next;
  520. struct sun4c_mmu_entry *lru_prev;
  521. };
  522. static struct sun4c_mmu_entry mmu_entry_pool[SUN4C_MAX_SEGMAPS];
  523. static void __init sun4c_init_mmu_entry_pool(void)
  524. {
  525. int i;
  526. for (i=0; i < SUN4C_MAX_SEGMAPS; i++) {
  527. mmu_entry_pool[i].pseg = i;
  528. mmu_entry_pool[i].next = 0;
  529. mmu_entry_pool[i].prev = 0;
  530. mmu_entry_pool[i].vaddr = 0;
  531. mmu_entry_pool[i].locked = 0;
  532. mmu_entry_pool[i].ctx = 0;
  533. mmu_entry_pool[i].lru_next = 0;
  534. mmu_entry_pool[i].lru_prev = 0;
  535. }
  536. mmu_entry_pool[invalid_segment].locked = 1;
  537. }
  538. static inline void fix_permissions(unsigned long vaddr, unsigned long bits_on,
  539.    unsigned long bits_off)
  540. {
  541. unsigned long start, end;
  542. end = vaddr + SUN4C_REAL_PGDIR_SIZE;
  543. for (start = vaddr; start < end; start += PAGE_SIZE)
  544. if (sun4c_get_pte(start) & _SUN4C_PAGE_VALID)
  545. sun4c_put_pte(start, (sun4c_get_pte(start) | bits_on) &
  546.       ~bits_off);
  547. }
  548. static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)
  549. {
  550. unsigned long vaddr;
  551. unsigned char pseg, ctx;
  552. #ifdef CONFIG_SUN4
  553. /* sun4/110 and 260 have no kadb. */
  554. if ((idprom->id_machtype != (SM_SUN4 | SM_4_260)) && 
  555.     (idprom->id_machtype != (SM_SUN4 | SM_4_110))) {
  556. #endif
  557. for (vaddr = KADB_DEBUGGER_BEGVM;
  558.      vaddr < LINUX_OPPROM_ENDVM;
  559.      vaddr += SUN4C_REAL_PGDIR_SIZE) {
  560. pseg = sun4c_get_segmap(vaddr);
  561. if (pseg != invalid_segment) {
  562. mmu_entry_pool[pseg].locked = 1;
  563. for (ctx = 0; ctx < num_contexts; ctx++)
  564. prom_putsegment(ctx, vaddr, pseg);
  565. fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0);
  566. }
  567. }
  568. #ifdef CONFIG_SUN4
  569. }
  570. #endif
  571. for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) {
  572. pseg = sun4c_get_segmap(vaddr);
  573. mmu_entry_pool[pseg].locked = 1;
  574. for (ctx = 0; ctx < num_contexts; ctx++)
  575. prom_putsegment(ctx, vaddr, pseg);
  576. fix_permissions(vaddr, _SUN4C_PAGE_PRIV, _SUN4C_PAGE_NOCACHE);
  577. }
  578. }
  579. static void __init sun4c_init_lock_area(unsigned long start, unsigned long end)
  580. {
  581. int i, ctx;
  582. while (start < end) {
  583. for (i = 0; i < invalid_segment; i++)
  584. if (!mmu_entry_pool[i].locked)
  585. break;
  586. mmu_entry_pool[i].locked = 1;
  587. sun4c_init_clean_segmap(i);
  588. for (ctx = 0; ctx < num_contexts; ctx++)
  589. prom_putsegment(ctx, start, mmu_entry_pool[i].pseg);
  590. start += SUN4C_REAL_PGDIR_SIZE;
  591. }
  592. }
  593. /* Don't change this struct without changing entry.S. This is used
  594.  * in the in-window kernel fault handler, and you don't want to mess
  595.  * with that. (See sun4c_fault in entry.S).
  596.  */
  597. struct sun4c_mmu_ring {
  598. struct sun4c_mmu_entry ringhd;
  599. int num_entries;
  600. };
  601. static struct sun4c_mmu_ring sun4c_context_ring[SUN4C_MAX_CONTEXTS]; /* used user entries */
  602. static struct sun4c_mmu_ring sun4c_ufree_ring;       /* free user entries */
  603. static struct sun4c_mmu_ring sun4c_ulru_ring;      /* LRU user entries */
  604. struct sun4c_mmu_ring sun4c_kernel_ring;      /* used kernel entries */
  605. struct sun4c_mmu_ring sun4c_kfree_ring;       /* free kernel entries */
  606. static inline void sun4c_init_rings(void)
  607. {
  608. int i;
  609. for (i = 0; i < SUN4C_MAX_CONTEXTS; i++) {
  610. sun4c_context_ring[i].ringhd.next =
  611. sun4c_context_ring[i].ringhd.prev =
  612. &sun4c_context_ring[i].ringhd;
  613. sun4c_context_ring[i].num_entries = 0;
  614. }
  615. sun4c_ufree_ring.ringhd.next = sun4c_ufree_ring.ringhd.prev =
  616. &sun4c_ufree_ring.ringhd;
  617. sun4c_ufree_ring.num_entries = 0;
  618. sun4c_ulru_ring.ringhd.lru_next = sun4c_ulru_ring.ringhd.lru_prev =
  619. &sun4c_ulru_ring.ringhd;
  620. sun4c_ulru_ring.num_entries = 0;
  621. sun4c_kernel_ring.ringhd.next = sun4c_kernel_ring.ringhd.prev =
  622. &sun4c_kernel_ring.ringhd;
  623. sun4c_kernel_ring.num_entries = 0;
  624. sun4c_kfree_ring.ringhd.next = sun4c_kfree_ring.ringhd.prev =
  625. &sun4c_kfree_ring.ringhd;
  626. sun4c_kfree_ring.num_entries = 0;
  627. }
  628. static void add_ring(struct sun4c_mmu_ring *ring,
  629.      struct sun4c_mmu_entry *entry)
  630. {
  631. struct sun4c_mmu_entry *head = &ring->ringhd;
  632. entry->prev = head;
  633. (entry->next = head->next)->prev = entry;
  634. head->next = entry;
  635. ring->num_entries++;
  636. }
  637. static __inline__ void add_lru(struct sun4c_mmu_entry *entry)
  638. {
  639. struct sun4c_mmu_ring *ring = &sun4c_ulru_ring;
  640. struct sun4c_mmu_entry *head = &ring->ringhd;
  641. entry->lru_next = head;
  642. (entry->lru_prev = head->lru_prev)->lru_next = entry;
  643. head->lru_prev = entry;
  644. }
  645. static void add_ring_ordered(struct sun4c_mmu_ring *ring,
  646.      struct sun4c_mmu_entry *entry)
  647. {
  648. struct sun4c_mmu_entry *head = &ring->ringhd;
  649. unsigned long addr = entry->vaddr;
  650. while ((head->next != &ring->ringhd) && (head->next->vaddr < addr))
  651. head = head->next;
  652. entry->prev = head;
  653. (entry->next = head->next)->prev = entry;
  654. head->next = entry;
  655. ring->num_entries++;
  656. add_lru(entry);
  657. }
  658. static __inline__ void remove_ring(struct sun4c_mmu_ring *ring,
  659.    struct sun4c_mmu_entry *entry)
  660. {
  661. struct sun4c_mmu_entry *next = entry->next;
  662. (next->prev = entry->prev)->next = next;
  663. ring->num_entries--;
  664. }
  665. static void remove_lru(struct sun4c_mmu_entry *entry)
  666. {
  667. struct sun4c_mmu_entry *next = entry->lru_next;
  668. (next->lru_prev = entry->lru_prev)->lru_next = next;
  669. }
  670. static void free_user_entry(int ctx, struct sun4c_mmu_entry *entry)
  671. {
  672.         remove_ring(sun4c_context_ring+ctx, entry);
  673. remove_lru(entry);
  674.         add_ring(&sun4c_ufree_ring, entry);
  675. }
  676. static void free_kernel_entry(struct sun4c_mmu_entry *entry,
  677.       struct sun4c_mmu_ring *ring)
  678. {
  679.         remove_ring(ring, entry);
  680.         add_ring(&sun4c_kfree_ring, entry);
  681. }
  682. static void __init sun4c_init_fill_kernel_ring(int howmany)
  683. {
  684. int i;
  685. while (howmany) {
  686. for (i = 0; i < invalid_segment; i++)
  687. if (!mmu_entry_pool[i].locked)
  688. break;
  689. mmu_entry_pool[i].locked = 1;
  690. sun4c_init_clean_segmap(i);
  691. add_ring(&sun4c_kfree_ring, &mmu_entry_pool[i]);
  692. howmany--;
  693. }
  694. }
  695. static void __init sun4c_init_fill_user_ring(void)
  696. {
  697. int i;
  698. for (i = 0; i < invalid_segment; i++) {
  699. if (mmu_entry_pool[i].locked)
  700. continue;
  701. sun4c_init_clean_segmap(i);
  702. add_ring(&sun4c_ufree_ring, &mmu_entry_pool[i]);
  703. }
  704. }
  705. static void sun4c_kernel_unmap(struct sun4c_mmu_entry *kentry)
  706. {
  707. int savectx, ctx;
  708. savectx = sun4c_get_context();
  709. for (ctx = 0; ctx < num_contexts; ctx++) {
  710. sun4c_set_context(ctx);
  711. sun4c_put_segmap(kentry->vaddr, invalid_segment);
  712. }
  713. sun4c_set_context(savectx);
  714. }
  715. static void sun4c_kernel_map(struct sun4c_mmu_entry *kentry)
  716. {
  717. int savectx, ctx;
  718. savectx = sun4c_get_context();
  719. for (ctx = 0; ctx < num_contexts; ctx++) {
  720. sun4c_set_context(ctx);
  721. sun4c_put_segmap(kentry->vaddr, kentry->pseg);
  722. }
  723. sun4c_set_context(savectx);
  724. }
  725. #define sun4c_user_unmap(__entry) 
  726. sun4c_put_segmap((__entry)->vaddr, invalid_segment)
  727. static void sun4c_demap_context(struct sun4c_mmu_ring *crp, unsigned char ctx)
  728. {
  729. struct sun4c_mmu_entry *head = &crp->ringhd;
  730. unsigned long flags;
  731. save_and_cli(flags);
  732. if (head->next != head) {
  733. struct sun4c_mmu_entry *entry = head->next;
  734. int savectx = sun4c_get_context();
  735. flush_user_windows();
  736. sun4c_set_context(ctx);
  737. sun4c_flush_context();
  738. do {
  739. struct sun4c_mmu_entry *next = entry->next;
  740. sun4c_user_unmap(entry);
  741. free_user_entry(ctx, entry);
  742. entry = next;
  743. } while (entry != head);
  744. sun4c_set_context(savectx);
  745. }
  746. restore_flags(flags);
  747. }
  748. static int sun4c_user_taken_entries;  /* This is how much we have.             */
  749. static int max_user_taken_entries;    /* This limits us and prevents deadlock. */
  750. static struct sun4c_mmu_entry *sun4c_kernel_strategy(void)
  751. {
  752. struct sun4c_mmu_entry *this_entry;
  753. /* If some are free, return first one. */
  754. if (sun4c_kfree_ring.num_entries) {
  755. this_entry = sun4c_kfree_ring.ringhd.next;
  756. return this_entry;
  757. }
  758. /* Else free one up. */
  759. this_entry = sun4c_kernel_ring.ringhd.prev;
  760. sun4c_flush_segment(this_entry->vaddr);
  761. sun4c_kernel_unmap(this_entry);
  762. free_kernel_entry(this_entry, &sun4c_kernel_ring);
  763. this_entry = sun4c_kfree_ring.ringhd.next;
  764. return this_entry;
  765. }
  766. /* Using this method to free up mmu entries eliminates a lot of
  767.  * potential races since we have a kernel that incurs tlb
  768.  * replacement faults.  There may be performance penalties.
  769.  *
  770.  * NOTE: Must be called with interrupts disabled.
  771.  */
  772. static struct sun4c_mmu_entry *sun4c_user_strategy(void)
  773. {
  774. struct sun4c_mmu_entry *entry;
  775. unsigned char ctx;
  776. int savectx;
  777. /* If some are free, return first one. */
  778. if (sun4c_ufree_ring.num_entries) {
  779. entry = sun4c_ufree_ring.ringhd.next;
  780. goto unlink_out;
  781. }
  782. if (sun4c_user_taken_entries) {
  783. entry = sun4c_kernel_strategy();
  784. sun4c_user_taken_entries--;
  785. goto kunlink_out;
  786. }
  787. /* Grab from the beginning of the LRU list. */
  788. entry = sun4c_ulru_ring.ringhd.lru_next;
  789. ctx = entry->ctx;
  790. savectx = sun4c_get_context();
  791. flush_user_windows();
  792. sun4c_set_context(ctx);
  793. sun4c_flush_segment(entry->vaddr);
  794. sun4c_user_unmap(entry);
  795. remove_ring(sun4c_context_ring + ctx, entry);
  796. remove_lru(entry);
  797. sun4c_set_context(savectx);
  798. return entry;
  799. unlink_out:
  800. remove_ring(&sun4c_ufree_ring, entry);
  801. return entry;
  802. kunlink_out:
  803. remove_ring(&sun4c_kfree_ring, entry);
  804. return entry;
  805. }
  806. /* NOTE: Must be called with interrupts disabled. */
  807. void sun4c_grow_kernel_ring(void)
  808. {
  809. struct sun4c_mmu_entry *entry;
  810. /* Prevent deadlock condition. */
  811. if (sun4c_user_taken_entries >= max_user_taken_entries)
  812. return;
  813. if (sun4c_ufree_ring.num_entries) {
  814. entry = sun4c_ufree_ring.ringhd.next;
  815.          remove_ring(&sun4c_ufree_ring, entry);
  816. add_ring(&sun4c_kfree_ring, entry);
  817. sun4c_user_taken_entries++;
  818. }
  819. }
  820. /* 2 page buckets for task struct and kernel stack allocation.
  821.  *
  822.  * TASK_STACK_BEGIN
  823.  * bucket[0]
  824.  * bucket[1]
  825.  *   [ ... ]
  826.  * bucket[NR_TASK_BUCKETS-1]
  827.  * TASK_STACK_BEGIN + (sizeof(struct task_bucket) * NR_TASK_BUCKETS)
  828.  *
  829.  * Each slot looks like:
  830.  *
  831.  *  page 1 --  task struct + beginning of kernel stack
  832.  *  page 2 --  rest of kernel stack
  833.  */
  834. union task_union *sun4c_bucket[NR_TASK_BUCKETS];
  835. static int sun4c_lowbucket_avail;
  836. #define BUCKET_EMPTY     ((union task_union *) 0)
  837. #define BUCKET_SHIFT     (PAGE_SHIFT + 1)        /* log2(sizeof(struct task_bucket)) */
  838. #define BUCKET_SIZE      (1 << BUCKET_SHIFT)
  839. #define BUCKET_NUM(addr) ((((addr) - SUN4C_LOCK_VADDR) >> BUCKET_SHIFT))
  840. #define BUCKET_ADDR(num) (((num) << BUCKET_SHIFT) + SUN4C_LOCK_VADDR)
  841. #define BUCKET_PTE(page)       
  842.         ((((page) - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(SUN4C_PAGE_KERNEL))
  843. #define BUCKET_PTE_PAGE(pte)   
  844.         (PAGE_OFFSET + (((pte) & SUN4C_PFN_MASK) << PAGE_SHIFT))
  845. static void get_locked_segment(unsigned long addr)
  846. {
  847. struct sun4c_mmu_entry *stolen;
  848. unsigned long flags;
  849. save_and_cli(flags);
  850. addr &= SUN4C_REAL_PGDIR_MASK;
  851. stolen = sun4c_user_strategy();
  852. max_user_taken_entries--;
  853. stolen->vaddr = addr;
  854. flush_user_windows();
  855. sun4c_kernel_map(stolen);
  856. restore_flags(flags);
  857. }
  858. static void free_locked_segment(unsigned long addr)
  859. {
  860. struct sun4c_mmu_entry *entry;
  861. unsigned long flags;
  862. unsigned char pseg;
  863. save_and_cli(flags);
  864. addr &= SUN4C_REAL_PGDIR_MASK;
  865. pseg = sun4c_get_segmap(addr);
  866. entry = &mmu_entry_pool[pseg];
  867. flush_user_windows();
  868. sun4c_flush_segment(addr);
  869. sun4c_kernel_unmap(entry);
  870. add_ring(&sun4c_ufree_ring, entry);
  871. max_user_taken_entries++;
  872. restore_flags(flags);
  873. }
  874. static inline void garbage_collect(int entry)
  875. {
  876. int start, end;
  877. /* 32 buckets per segment... */
  878. entry &= ~31;
  879. start = entry;
  880. for (end = (start + 32); start < end; start++)
  881. if (sun4c_bucket[start] != BUCKET_EMPTY)
  882. return;
  883. /* Entire segment empty, release it. */
  884. free_locked_segment(BUCKET_ADDR(entry));
  885. }
  886. #ifdef CONFIG_SUN4
  887. #define TASK_STRUCT_ORDER 0
  888. #else
  889. #define TASK_STRUCT_ORDER 1
  890. #endif
  891. static struct task_struct *sun4c_alloc_task_struct(void)
  892. {
  893. unsigned long addr, pages;
  894. int entry;
  895. pages = __get_free_pages(GFP_KERNEL, TASK_STRUCT_ORDER);
  896. if (!pages)
  897. return (struct task_struct *) 0;
  898. for (entry = sun4c_lowbucket_avail; entry < NR_TASK_BUCKETS; entry++)
  899. if (sun4c_bucket[entry] == BUCKET_EMPTY)
  900. break;
  901. if (entry == NR_TASK_BUCKETS) {
  902. free_pages(pages, TASK_STRUCT_ORDER);
  903. return (struct task_struct *) 0;
  904. }
  905. if (entry >= sun4c_lowbucket_avail)
  906. sun4c_lowbucket_avail = entry + 1;
  907. addr = BUCKET_ADDR(entry);
  908. sun4c_bucket[entry] = (union task_union *) addr;
  909. if(sun4c_get_segmap(addr) == invalid_segment)
  910. get_locked_segment(addr);
  911. /* We are changing the virtual color of the page(s)
  912.  * so we must flush the cache to guarentee consistancy.
  913.  */
  914. sun4c_flush_page(pages);
  915. #ifndef CONFIG_SUN4
  916. sun4c_flush_page(pages + PAGE_SIZE);
  917. #endif
  918. sun4c_put_pte(addr, BUCKET_PTE(pages));
  919. #ifndef CONFIG_SUN4
  920. sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE));
  921. #endif
  922. return (struct task_struct *) addr;
  923. }
  924. static void sun4c_free_task_struct(struct task_struct *tsk)
  925. {
  926. unsigned long tsaddr = (unsigned long) tsk;
  927. unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tsaddr));
  928. int entry = BUCKET_NUM(tsaddr);
  929. if (atomic_dec_and_test(&(tsk)->thread.refcount)) {
  930. /* We are deleting a mapping, so the flush here is mandatory. */
  931. sun4c_flush_page(tsaddr);
  932. #ifndef CONFIG_SUN4
  933. sun4c_flush_page(tsaddr + PAGE_SIZE);
  934. #endif
  935. sun4c_put_pte(tsaddr, 0);
  936. #ifndef CONFIG_SUN4
  937. sun4c_put_pte(tsaddr + PAGE_SIZE, 0);
  938. #endif
  939. sun4c_bucket[entry] = BUCKET_EMPTY;
  940. if (entry < sun4c_lowbucket_avail)
  941. sun4c_lowbucket_avail = entry;
  942. free_pages(pages, TASK_STRUCT_ORDER);
  943. garbage_collect(entry);
  944. }
  945. }
  946. static void sun4c_get_task_struct(struct task_struct *tsk)
  947. {
  948. atomic_inc(&(tsk)->thread.refcount);
  949. }
  950. static void __init sun4c_init_buckets(void)
  951. {
  952. int entry;
  953. if (sizeof(union task_union) != (PAGE_SIZE << TASK_STRUCT_ORDER)) {
  954. prom_printf("task union not %d page(s)!n", 1 << TASK_STRUCT_ORDER);
  955. }
  956. for (entry = 0; entry < NR_TASK_BUCKETS; entry++)
  957. sun4c_bucket[entry] = BUCKET_EMPTY;
  958. sun4c_lowbucket_avail = 0;
  959. }
  960. static unsigned long sun4c_iobuffer_start;
  961. static unsigned long sun4c_iobuffer_end;
  962. static unsigned long sun4c_iobuffer_high;
  963. static unsigned long *sun4c_iobuffer_map;
  964. static int iobuffer_map_size;
  965. /*
  966.  * Alias our pages so they do not cause a trap.
  967.  * Also one page may be aliased into several I/O areas and we may
  968.  * finish these I/O separately.
  969.  */
  970. static char *sun4c_lockarea(char *vaddr, unsigned long size)
  971. {
  972. unsigned long base, scan;
  973. unsigned long npages;
  974. unsigned long vpage;
  975. unsigned long pte;
  976. unsigned long apage;
  977. unsigned long high;
  978. unsigned long flags;
  979. npages = (((unsigned long)vaddr & ~PAGE_MASK) +
  980.   size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
  981. scan = 0;
  982. save_and_cli(flags);
  983. for (;;) {
  984. scan = find_next_zero_bit(sun4c_iobuffer_map,
  985.   iobuffer_map_size, scan);
  986. if ((base = scan) + npages > iobuffer_map_size) goto abend;
  987. for (;;) {
  988. if (scan >= base + npages) goto found;
  989. if (test_bit(scan, sun4c_iobuffer_map)) break;
  990. scan++;
  991. }
  992. }
  993. found:
  994. high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start;
  995. high = SUN4C_REAL_PGDIR_ALIGN(high);
  996. while (high > sun4c_iobuffer_high) {
  997. get_locked_segment(sun4c_iobuffer_high);
  998. sun4c_iobuffer_high += SUN4C_REAL_PGDIR_SIZE;
  999. }
  1000. vpage = ((unsigned long) vaddr) & PAGE_MASK;
  1001. for (scan = base; scan < base+npages; scan++) {
  1002. pte = ((vpage-PAGE_OFFSET) >> PAGE_SHIFT);
  1003.   pte |= pgprot_val(SUN4C_PAGE_KERNEL);
  1004. pte |= _SUN4C_PAGE_NOCACHE;
  1005. set_bit(scan, sun4c_iobuffer_map);
  1006. apage = (scan << PAGE_SHIFT) + sun4c_iobuffer_start;
  1007. /* Flush original mapping so we see the right things later. */
  1008. sun4c_flush_page(vpage);
  1009. sun4c_put_pte(apage, pte);
  1010. vpage += PAGE_SIZE;
  1011. }
  1012. restore_flags(flags);
  1013. return (char *) ((base << PAGE_SHIFT) + sun4c_iobuffer_start +
  1014.  (((unsigned long) vaddr) & ~PAGE_MASK));
  1015. abend:
  1016. restore_flags(flags);
  1017. printk("DMA vaddr=0x%p size=%08lxn", vaddr, size);
  1018. panic("Out of iobuffer table");
  1019. return 0;
  1020. }
  1021. static void sun4c_unlockarea(char *vaddr, unsigned long size)
  1022. {
  1023. unsigned long vpage, npages;
  1024. unsigned long flags;
  1025. int scan, high;
  1026. vpage = (unsigned long)vaddr & PAGE_MASK;
  1027. npages = (((unsigned long)vaddr & ~PAGE_MASK) +
  1028.   size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
  1029. save_and_cli(flags);
  1030. while (npages != 0) {
  1031. --npages;
  1032. /* This mapping is marked non-cachable, no flush necessary. */
  1033. sun4c_put_pte(vpage, 0);
  1034. clear_bit((vpage - sun4c_iobuffer_start) >> PAGE_SHIFT,
  1035.   sun4c_iobuffer_map);
  1036. vpage += PAGE_SIZE;
  1037. }
  1038. /* garbage collect */
  1039. scan = (sun4c_iobuffer_high - sun4c_iobuffer_start) >> PAGE_SHIFT;
  1040. while (scan >= 0 && !sun4c_iobuffer_map[scan >> 5])
  1041. scan -= 32;
  1042. scan += 32;
  1043. high = sun4c_iobuffer_start + (scan << PAGE_SHIFT);
  1044. high = SUN4C_REAL_PGDIR_ALIGN(high) + SUN4C_REAL_PGDIR_SIZE;
  1045. while (high < sun4c_iobuffer_high) {
  1046. sun4c_iobuffer_high -= SUN4C_REAL_PGDIR_SIZE;
  1047. free_locked_segment(sun4c_iobuffer_high);
  1048. }
  1049. restore_flags(flags);
  1050. }
  1051. /* Note the scsi code at init time passes to here buffers
  1052.  * which sit on the kernel stack, those are already locked
  1053.  * by implication and fool the page locking code above
  1054.  * if passed to by mistake.
  1055.  */
  1056. static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus *sbus)
  1057. {
  1058. unsigned long page;
  1059. page = ((unsigned long)bufptr) & PAGE_MASK;
  1060. if (!VALID_PAGE(virt_to_page(page))) {
  1061. sun4c_flush_page(page);
  1062. return (__u32)bufptr; /* already locked */
  1063. }
  1064. return (__u32)sun4c_lockarea(bufptr, len);
  1065. }
  1066. static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus)
  1067. {
  1068. while (sz != 0) {
  1069. sz--;
  1070. sg[sz].dvma_address = (__u32)sun4c_lockarea(sg[sz].address, sg[sz].length);
  1071. sg[sz].dvma_length = sg[sz].length;
  1072. }
  1073. }
  1074. static void sun4c_release_scsi_one(__u32 bufptr, unsigned long len, struct sbus_bus *sbus)
  1075. {
  1076. if (bufptr < sun4c_iobuffer_start)
  1077. return; /* On kernel stack or similar, see above */
  1078. sun4c_unlockarea((char *)bufptr, len);
  1079. }
  1080. static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus)
  1081. {
  1082. while (sz != 0) {
  1083. --sz;
  1084. sun4c_unlockarea((char *)sg[sz].dvma_address, sg[sz].length);
  1085. }
  1086. }
  1087. #define TASK_ENTRY_SIZE    BUCKET_SIZE /* see above */
  1088. #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
  1089. struct vm_area_struct sun4c_kstack_vma;
  1090. static void __init sun4c_init_lock_areas(void)
  1091. {
  1092. unsigned long sun4c_taskstack_start;
  1093. unsigned long sun4c_taskstack_end;
  1094. int bitmap_size;
  1095. sun4c_init_buckets();
  1096. sun4c_taskstack_start = SUN4C_LOCK_VADDR;
  1097. sun4c_taskstack_end = (sun4c_taskstack_start +
  1098.        (TASK_ENTRY_SIZE * NR_TASK_BUCKETS));
  1099. if (sun4c_taskstack_end >= SUN4C_LOCK_END) {
  1100. prom_printf("Too many tasks, decrease NR_TASK_BUCKETS please.n");
  1101. prom_halt();
  1102. }
  1103. sun4c_iobuffer_start = sun4c_iobuffer_high =
  1104. SUN4C_REAL_PGDIR_ALIGN(sun4c_taskstack_end);
  1105. sun4c_iobuffer_end = SUN4C_LOCK_END;
  1106. bitmap_size = (sun4c_iobuffer_end - sun4c_iobuffer_start) >> PAGE_SHIFT;
  1107. bitmap_size = (bitmap_size + 7) >> 3;
  1108. bitmap_size = LONG_ALIGN(bitmap_size);
  1109. iobuffer_map_size = bitmap_size << 3;
  1110. sun4c_iobuffer_map = __alloc_bootmem(bitmap_size, SMP_CACHE_BYTES, 0UL);
  1111. memset((void *) sun4c_iobuffer_map, 0, bitmap_size);
  1112. sun4c_kstack_vma.vm_mm = &init_mm;
  1113. sun4c_kstack_vma.vm_start = sun4c_taskstack_start;
  1114. sun4c_kstack_vma.vm_end = sun4c_taskstack_end;
  1115. sun4c_kstack_vma.vm_page_prot = PAGE_SHARED;
  1116. sun4c_kstack_vma.vm_flags = VM_READ | VM_WRITE | VM_EXEC;
  1117. insert_vm_struct(&init_mm, &sun4c_kstack_vma);
  1118. }
  1119. /* Cache flushing on the sun4c. */
  1120. static void sun4c_flush_cache_all(void)
  1121. {
  1122. unsigned long begin, end;
  1123. flush_user_windows();
  1124. begin = (KERNBASE + SUN4C_REAL_PGDIR_SIZE);
  1125. end = (begin + SUN4C_VAC_SIZE);
  1126. if (sun4c_vacinfo.linesize == 32) {
  1127. while (begin < end) {
  1128. __asm__ __volatile__(
  1129. "ld [%0 + 0x00], %%g0nt"
  1130. "ld [%0 + 0x20], %%g0nt"
  1131. "ld [%0 + 0x40], %%g0nt"
  1132. "ld [%0 + 0x60], %%g0nt"
  1133. "ld [%0 + 0x80], %%g0nt"
  1134. "ld [%0 + 0xa0], %%g0nt"
  1135. "ld [%0 + 0xc0], %%g0nt"
  1136. "ld [%0 + 0xe0], %%g0nt"
  1137. "ld [%0 + 0x100], %%g0nt"
  1138. "ld [%0 + 0x120], %%g0nt"
  1139. "ld [%0 + 0x140], %%g0nt"
  1140. "ld [%0 + 0x160], %%g0nt"
  1141. "ld [%0 + 0x180], %%g0nt"
  1142. "ld [%0 + 0x1a0], %%g0nt"
  1143. "ld [%0 + 0x1c0], %%g0nt"
  1144. "ld [%0 + 0x1e0], %%g0n"
  1145. : : "r" (begin));
  1146. begin += 512;
  1147. }
  1148. } else {
  1149. while (begin < end) {
  1150. __asm__ __volatile__(
  1151. "ld [%0 + 0x00], %%g0nt"
  1152. "ld [%0 + 0x10], %%g0nt"
  1153. "ld [%0 + 0x20], %%g0nt"
  1154. "ld [%0 + 0x30], %%g0nt"
  1155. "ld [%0 + 0x40], %%g0nt"
  1156. "ld [%0 + 0x50], %%g0nt"
  1157. "ld [%0 + 0x60], %%g0nt"
  1158. "ld [%0 + 0x70], %%g0nt"
  1159. "ld [%0 + 0x80], %%g0nt"
  1160. "ld [%0 + 0x90], %%g0nt"
  1161. "ld [%0 + 0xa0], %%g0nt"
  1162. "ld [%0 + 0xb0], %%g0nt"
  1163. "ld [%0 + 0xc0], %%g0nt"
  1164. "ld [%0 + 0xd0], %%g0nt"
  1165. "ld [%0 + 0xe0], %%g0nt"
  1166. "ld [%0 + 0xf0], %%g0n"
  1167. : : "r" (begin));
  1168. begin += 256;
  1169. }
  1170. }
  1171. }
  1172. static void sun4c_flush_cache_mm(struct mm_struct *mm)
  1173. {
  1174. int new_ctx = mm->context;
  1175. if (new_ctx != NO_CONTEXT) {
  1176. flush_user_windows();
  1177. if (sun4c_context_ring[new_ctx].num_entries) {
  1178. struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
  1179. unsigned long flags;
  1180. save_and_cli(flags);
  1181. if (head->next != head) {
  1182. struct sun4c_mmu_entry *entry = head->next;
  1183. int savectx = sun4c_get_context();
  1184. sun4c_set_context(new_ctx);
  1185. sun4c_flush_context();
  1186. do {
  1187. struct sun4c_mmu_entry *next = entry->next;
  1188. sun4c_user_unmap(entry);
  1189. free_user_entry(new_ctx, entry);
  1190. entry = next;
  1191. } while (entry != head);
  1192. sun4c_set_context(savectx);
  1193. }
  1194. restore_flags(flags);
  1195. }
  1196. }
  1197. }
  1198. static void sun4c_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end)
  1199. {
  1200. int new_ctx = mm->context;
  1201. if (new_ctx != NO_CONTEXT) {
  1202. struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
  1203. struct sun4c_mmu_entry *entry;
  1204. unsigned long flags;
  1205. flush_user_windows();
  1206. save_and_cli(flags);
  1207. /* All user segmap chains are ordered on entry->vaddr. */
  1208. for (entry = head->next;
  1209.      (entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start);
  1210.      entry = entry->next)
  1211. ;
  1212. /* Tracing various job mixtures showed that this conditional
  1213.  * only passes ~35% of the time for most worse case situations,
  1214.  * therefore we avoid all of this gross overhead ~65% of the time.
  1215.  */
  1216. if ((entry != head) && (entry->vaddr < end)) {
  1217. int octx = sun4c_get_context();
  1218. sun4c_set_context(new_ctx);
  1219. /* At this point, always, (start >= entry->vaddr) and
  1220.  * (entry->vaddr < end), once the latter condition
  1221.  * ceases to hold, or we hit the end of the list, we
  1222.  * exit the loop.  The ordering of all user allocated
  1223.  * segmaps makes this all work out so beautifully.
  1224.  */
  1225. do {
  1226. struct sun4c_mmu_entry *next = entry->next;
  1227. unsigned long realend;
  1228. /* "realstart" is always >= entry->vaddr */
  1229. realend = entry->vaddr + SUN4C_REAL_PGDIR_SIZE;
  1230. if (end < realend)
  1231. realend = end;
  1232. if ((realend - entry->vaddr) <= (PAGE_SIZE << 3)) {
  1233. unsigned long page = entry->vaddr;
  1234. while (page < realend) {
  1235. sun4c_flush_page(page);
  1236. page += PAGE_SIZE;
  1237. }
  1238. } else {
  1239. sun4c_flush_segment(entry->vaddr);
  1240. sun4c_user_unmap(entry);
  1241. free_user_entry(new_ctx, entry);
  1242. }
  1243. entry = next;
  1244. } while ((entry != head) && (entry->vaddr < end));
  1245. sun4c_set_context(octx);
  1246. }
  1247. restore_flags(flags);
  1248. }
  1249. }
  1250. static void sun4c_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
  1251. {
  1252. struct mm_struct *mm = vma->vm_mm;
  1253. int new_ctx = mm->context;
  1254. /* Sun4c has no separate I/D caches so cannot optimize for non
  1255.  * text page flushes.
  1256.  */
  1257. if (new_ctx != NO_CONTEXT) {
  1258. int octx = sun4c_get_context();
  1259. unsigned long flags;
  1260. flush_user_windows();
  1261. save_and_cli(flags);
  1262. sun4c_set_context(new_ctx);
  1263. sun4c_flush_page(page);
  1264. sun4c_set_context(octx);
  1265. restore_flags(flags);
  1266. }
  1267. }
  1268. static void sun4c_flush_page_to_ram(unsigned long page)
  1269. {
  1270. unsigned long flags;
  1271. save_and_cli(flags);
  1272. sun4c_flush_page(page);
  1273. restore_flags(flags);
  1274. }
  1275. /* Sun4c cache is unified, both instructions and data live there, so
  1276.  * no need to flush the on-stack instructions for new signal handlers.
  1277.  */
  1278. static void sun4c_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
  1279. {
  1280. }
  1281. /* TLB flushing on the sun4c.  These routines count on the cache
  1282.  * flushing code to flush the user register windows so that we need
  1283.  * not do so when we get here.
  1284.  */
  1285. static void sun4c_flush_tlb_all(void)
  1286. {
  1287. struct sun4c_mmu_entry *this_entry, *next_entry;
  1288. unsigned long flags;
  1289. int savectx, ctx;
  1290. save_and_cli(flags);
  1291. this_entry = sun4c_kernel_ring.ringhd.next;
  1292. savectx = sun4c_get_context();
  1293. flush_user_windows();
  1294. while (sun4c_kernel_ring.num_entries) {
  1295. next_entry = this_entry->next;
  1296. sun4c_flush_segment(this_entry->vaddr);
  1297. for (ctx = 0; ctx < num_contexts; ctx++) {
  1298. sun4c_set_context(ctx);
  1299. sun4c_put_segmap(this_entry->vaddr, invalid_segment);
  1300. }
  1301. free_kernel_entry(this_entry, &sun4c_kernel_ring);
  1302. this_entry = next_entry;
  1303. }
  1304. sun4c_set_context(savectx);
  1305. restore_flags(flags);
  1306. }
  1307. static void sun4c_flush_tlb_mm(struct mm_struct *mm)
  1308. {
  1309. int new_ctx = mm->context;
  1310. if (new_ctx != NO_CONTEXT) {
  1311. struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
  1312. unsigned long flags;
  1313. save_and_cli(flags);
  1314. if (head->next != head) {
  1315. struct sun4c_mmu_entry *entry = head->next;
  1316. int savectx = sun4c_get_context();
  1317. sun4c_set_context(new_ctx);
  1318. sun4c_flush_context();
  1319. do {
  1320. struct sun4c_mmu_entry *next = entry->next;
  1321. sun4c_user_unmap(entry);
  1322. free_user_entry(new_ctx, entry);
  1323. entry = next;
  1324. } while (entry != head);
  1325. sun4c_set_context(savectx);
  1326. }
  1327. restore_flags(flags);
  1328. }
  1329. }
  1330. static void sun4c_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
  1331. {
  1332. int new_ctx = mm->context;
  1333. if (new_ctx != NO_CONTEXT) {
  1334. struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
  1335. struct sun4c_mmu_entry *entry;
  1336. unsigned long flags;
  1337. save_and_cli(flags);
  1338. /* See commentary in sun4c_flush_cache_range(). */
  1339. for (entry = head->next;
  1340.      (entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start);
  1341.      entry = entry->next)
  1342. ;
  1343. if ((entry != head) && (entry->vaddr < end)) {
  1344. int octx = sun4c_get_context();
  1345. sun4c_set_context(new_ctx);
  1346. do {
  1347. struct sun4c_mmu_entry *next = entry->next;
  1348. sun4c_flush_segment(entry->vaddr);
  1349. sun4c_user_unmap(entry);
  1350. free_user_entry(new_ctx, entry);
  1351. entry = next;
  1352. } while ((entry != head) && (entry->vaddr < end));
  1353. sun4c_set_context(octx);
  1354. }
  1355. restore_flags(flags);
  1356. }
  1357. }
  1358. static void sun4c_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
  1359. {
  1360. struct mm_struct *mm = vma->vm_mm;
  1361. int new_ctx = mm->context;
  1362. if (new_ctx != NO_CONTEXT) {
  1363. int savectx = sun4c_get_context();
  1364. unsigned long flags;
  1365. save_and_cli(flags);
  1366. sun4c_set_context(new_ctx);
  1367. page &= PAGE_MASK;
  1368. sun4c_flush_page(page);
  1369. sun4c_put_pte(page, 0);
  1370. sun4c_set_context(savectx);
  1371. restore_flags(flags);
  1372. }
  1373. }
  1374. void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr,
  1375.      int bus_type, int rdonly)
  1376. {
  1377. unsigned long page_entry;
  1378. page_entry = ((physaddr >> PAGE_SHIFT) & SUN4C_PFN_MASK);
  1379. page_entry |= ((pg_iobits | _SUN4C_PAGE_PRIV) & ~(_SUN4C_PAGE_PRESENT));
  1380. if (rdonly)
  1381. page_entry &= ~_SUN4C_WRITEABLE;
  1382. sun4c_put_pte(virt_addr, page_entry);
  1383. }
  1384. void sun4c_unmapioaddr(unsigned long virt_addr)
  1385. {
  1386. sun4c_put_pte(virt_addr, 0);
  1387. }
  1388. static void sun4c_alloc_context(struct mm_struct *old_mm, struct mm_struct *mm)
  1389. {
  1390. struct ctx_list *ctxp;
  1391. ctxp = ctx_free.next;
  1392. if (ctxp != &ctx_free) {
  1393. remove_from_ctx_list(ctxp);
  1394. add_to_used_ctxlist(ctxp);
  1395. mm->context = ctxp->ctx_number;
  1396. ctxp->ctx_mm = mm;
  1397. return;
  1398. }
  1399. ctxp = ctx_used.next;
  1400. if (ctxp->ctx_mm == old_mm)
  1401. ctxp = ctxp->next;
  1402. remove_from_ctx_list(ctxp);
  1403. add_to_used_ctxlist(ctxp);
  1404. ctxp->ctx_mm->context = NO_CONTEXT;
  1405. ctxp->ctx_mm = mm;
  1406. mm->context = ctxp->ctx_number;
  1407. sun4c_demap_context(&sun4c_context_ring[ctxp->ctx_number],
  1408.        ctxp->ctx_number);
  1409. }
  1410. /* Switch the current MM context. */
  1411. static void sun4c_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk, int cpu)
  1412. {
  1413. struct ctx_list *ctx;
  1414. int dirty = 0;
  1415. if (mm->context == NO_CONTEXT) {
  1416. dirty = 1;
  1417. sun4c_alloc_context(old_mm, mm);
  1418. } else {
  1419. /* Update the LRU ring of contexts. */
  1420. ctx = ctx_list_pool + mm->context;
  1421. remove_from_ctx_list(ctx);
  1422. add_to_used_ctxlist(ctx);
  1423. }
  1424. if (dirty || old_mm != mm)
  1425. sun4c_set_context(mm->context);
  1426. }
  1427. static void sun4c_destroy_context(struct mm_struct *mm)
  1428. {
  1429. struct ctx_list *ctx_old;
  1430. if (mm->context != NO_CONTEXT) {
  1431. sun4c_demap_context(&sun4c_context_ring[mm->context], mm->context);
  1432. ctx_old = ctx_list_pool + mm->context;
  1433. remove_from_ctx_list(ctx_old);
  1434. add_to_free_ctxlist(ctx_old);
  1435. mm->context = NO_CONTEXT;
  1436. }
  1437. }
  1438. static void sun4c_mmu_info(struct seq_file *m)
  1439. {
  1440. int used_user_entries, i;
  1441. used_user_entries = 0;
  1442. for (i = 0; i < num_contexts; i++)
  1443. used_user_entries += sun4c_context_ring[i].num_entries;
  1444. seq_printf(m, 
  1445.    "vacsizett: %d bytesn"
  1446.    "vachwflusht: %sn"
  1447.    "vaclinesizet: %d bytesn"
  1448.    "mmuctxstt: %dn"
  1449.    "mmupsegst: %dn"
  1450.    "kernelpsegst: %dn"
  1451.    "kfreepsegst: %dn"
  1452.    "usedpsegst: %dn"
  1453.    "ufreepsegst: %dn"
  1454.    "user_takent: %dn"
  1455.    "max_takent: %dn",
  1456.    sun4c_vacinfo.num_bytes,
  1457.    (sun4c_vacinfo.do_hwflushes ? "yes" : "no"),
  1458.    sun4c_vacinfo.linesize,
  1459.    num_contexts,
  1460.    (invalid_segment + 1),
  1461.    sun4c_kernel_ring.num_entries,
  1462.    sun4c_kfree_ring.num_entries,
  1463.    used_user_entries,
  1464.    sun4c_ufree_ring.num_entries,
  1465.    sun4c_user_taken_entries,
  1466.    max_user_taken_entries);
  1467. }
  1468. /* Nothing below here should touch the mmu hardware nor the mmu_entry
  1469.  * data structures.
  1470.  */
  1471. /* First the functions which the mid-level code uses to directly
  1472.  * manipulate the software page tables.  Some defines since we are
  1473.  * emulating the i386 page directory layout.
  1474.  */
  1475. #define PGD_PRESENT  0x001
  1476. #define PGD_RW       0x002
  1477. #define PGD_USER     0x004
  1478. #define PGD_ACCESSED 0x020
  1479. #define PGD_DIRTY    0x040
  1480. #define PGD_TABLE    (PGD_PRESENT | PGD_RW | PGD_USER | PGD_ACCESSED | PGD_DIRTY)
  1481. static void sun4c_set_pte(pte_t *ptep, pte_t pte)
  1482. {
  1483. *ptep = pte;
  1484. }
  1485. static void sun4c_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
  1486. {
  1487. }
  1488. static void sun4c_pmd_set(pmd_t * pmdp, pte_t * ptep)
  1489. {
  1490. *pmdp = __pmd(PGD_TABLE | (unsigned long) ptep);
  1491. }
  1492. static int sun4c_pte_present(pte_t pte)
  1493. {
  1494. return ((pte_val(pte) & (_SUN4C_PAGE_PRESENT | _SUN4C_PAGE_PRIV)) != 0);
  1495. }
  1496. static void sun4c_pte_clear(pte_t *ptep) { *ptep = __pte(0); }
  1497. static int sun4c_pmd_bad(pmd_t pmd)
  1498. {
  1499. return (((pmd_val(pmd) & ~PAGE_MASK) != PGD_TABLE) ||
  1500. (!VALID_PAGE(virt_to_page(pmd_val(pmd)))));
  1501. }
  1502. static int sun4c_pmd_present(pmd_t pmd)
  1503. {
  1504. return ((pmd_val(pmd) & PGD_PRESENT) != 0);
  1505. }
  1506. static void sun4c_pmd_clear(pmd_t *pmdp) { *pmdp = __pmd(0); }
  1507. static int sun4c_pgd_none(pgd_t pgd) { return 0; }
  1508. static int sun4c_pgd_bad(pgd_t pgd) { return 0; }
  1509. static int sun4c_pgd_present(pgd_t pgd)         { return 1; }
  1510. static void sun4c_pgd_clear(pgd_t * pgdp) { }
  1511. /*
  1512.  * The following only work if pte_present() is true.
  1513.  * Undefined behaviour if not..
  1514.  */
  1515. static pte_t sun4c_pte_mkwrite(pte_t pte)
  1516. {
  1517. pte = __pte(pte_val(pte) | _SUN4C_PAGE_WRITE);
  1518. if (pte_val(pte) & _SUN4C_PAGE_MODIFIED)
  1519. pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE);
  1520. return pte;
  1521. }
  1522. static pte_t sun4c_pte_mkdirty(pte_t pte)
  1523. {
  1524. pte = __pte(pte_val(pte) | _SUN4C_PAGE_MODIFIED);
  1525. if (pte_val(pte) & _SUN4C_PAGE_WRITE)
  1526. pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE);
  1527. return pte;
  1528. }
  1529. static pte_t sun4c_pte_mkyoung(pte_t pte)
  1530. {
  1531. pte = __pte(pte_val(pte) | _SUN4C_PAGE_ACCESSED);
  1532. if (pte_val(pte) & _SUN4C_PAGE_READ)
  1533. pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_READ);
  1534. return pte;
  1535. }
  1536. /*
  1537.  * Conversion functions: convert a page and protection to a page entry,
  1538.  * and a page entry and page directory to the page they refer to.
  1539.  */
  1540. static pte_t sun4c_mk_pte(struct page *page, pgprot_t pgprot)
  1541. {
  1542. return __pte((page - mem_map) | pgprot_val(pgprot));
  1543. }
  1544. static pte_t sun4c_mk_pte_phys(unsigned long phys_page, pgprot_t pgprot)
  1545. {
  1546. return __pte((phys_page >> PAGE_SHIFT) | pgprot_val(pgprot));
  1547. }
  1548. static pte_t sun4c_mk_pte_io(unsigned long page, pgprot_t pgprot, int space)
  1549. {
  1550. return __pte(((page - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(pgprot));
  1551. }
  1552. static struct page *sun4c_pte_page(pte_t pte)
  1553. {
  1554. return (mem_map + (unsigned long)(pte_val(pte) & SUN4C_PFN_MASK));
  1555. }
  1556. static inline unsigned long sun4c_pmd_page(pmd_t pmd)
  1557. {
  1558. return (pmd_val(pmd) & PAGE_MASK);
  1559. }
  1560. static unsigned long sun4c_pgd_page(pgd_t pgd) { return 0; }
  1561. /* to find an entry in a page-table-directory */
  1562. static inline pgd_t *sun4c_pgd_offset(struct mm_struct * mm, unsigned long address)
  1563. {
  1564. return mm->pgd + (address >> SUN4C_PGDIR_SHIFT);
  1565. }
  1566. /* Find an entry in the second-level page table.. */
  1567. static pmd_t *sun4c_pmd_offset(pgd_t * dir, unsigned long address)
  1568. {
  1569. return (pmd_t *) dir;
  1570. }
  1571. /* Find an entry in the third-level page table.. */ 
  1572. pte_t *sun4c_pte_offset(pmd_t * dir, unsigned long address)
  1573. {
  1574. return (pte_t *) sun4c_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (SUN4C_PTRS_PER_PTE - 1));
  1575. }
  1576. static void sun4c_free_pte_slow(pte_t *pte)
  1577. {
  1578. free_page((unsigned long)pte);
  1579. }
  1580. static void sun4c_free_pgd_slow(pgd_t *pgd)
  1581. {
  1582. free_page((unsigned long)pgd);
  1583. }
  1584. static pgd_t *sun4c_get_pgd_fast(void)
  1585. {
  1586. unsigned long *ret;
  1587. if ((ret = pgd_quicklist) != NULL) {
  1588. pgd_quicklist = (unsigned long *)(*ret);
  1589. ret[0] = ret[1];
  1590. pgtable_cache_size--;
  1591. } else {
  1592. pgd_t *init;
  1593. ret = (unsigned long *)__get_free_page(GFP_KERNEL);
  1594. memset (ret, 0, (KERNBASE / SUN4C_PGDIR_SIZE) * sizeof(pgd_t));
  1595. init = sun4c_pgd_offset(&init_mm, 0);
  1596. memcpy (((pgd_t *)ret) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
  1597. (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
  1598. }
  1599. return (pgd_t *)ret;
  1600. }
  1601. static void sun4c_free_pgd_fast(pgd_t *pgd)
  1602. {
  1603. *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
  1604. pgd_quicklist = (unsigned long *) pgd;
  1605. pgtable_cache_size++;
  1606. }
  1607. static pte_t *sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long address)
  1608. {
  1609. pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL);
  1610. if (pte)
  1611. memset(pte, 0, PAGE_SIZE);
  1612. return pte;
  1613. }
  1614. pte_t *sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
  1615. {
  1616. unsigned long *ret;
  1617. if ((ret = (unsigned long *)pte_quicklist) != NULL) {
  1618. pte_quicklist = (unsigned long *)(*ret);
  1619. ret[0] = ret[1];
  1620. pgtable_cache_size--;
  1621. }
  1622. return (pte_t *)ret;
  1623. }
  1624. static __inline__ void sun4c_free_pte_fast(pte_t *pte)
  1625. {
  1626. *(unsigned long *)pte = (unsigned long) pte_quicklist;
  1627. pte_quicklist = (unsigned long *) pte;
  1628. pgtable_cache_size++;
  1629. }
  1630. /*
  1631.  * allocating and freeing a pmd is trivial: the 1-entry pmd is
  1632.  * inside the pgd, so has no extra memory associated with it.
  1633.  */
  1634. static pmd_t *sun4c_pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address)
  1635. {
  1636. BUG();
  1637. return NULL;
  1638. }
  1639. static void sun4c_free_pmd_fast(pmd_t * pmd) { }
  1640. static int sun4c_check_pgt_cache(int low, int high)
  1641. {
  1642. int freed = 0;
  1643. if (pgtable_cache_size > high) {
  1644. do {
  1645. if (pgd_quicklist)
  1646. sun4c_free_pgd_slow(sun4c_get_pgd_fast()), freed++;
  1647. if (pte_quicklist)
  1648. sun4c_free_pte_slow(sun4c_pte_alloc_one_fast(NULL, 0)), freed++;
  1649. } while (pgtable_cache_size > low);
  1650. }
  1651. return freed;
  1652. }
  1653. /* An experiment, turn off by default for now... -DaveM */
  1654. #define SUN4C_PRELOAD_PSEG
  1655. void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
  1656. {
  1657. unsigned long flags;
  1658. int pseg;
  1659. save_and_cli(flags);
  1660. address &= PAGE_MASK;
  1661. if ((pseg = sun4c_get_segmap(address)) == invalid_segment) {
  1662. struct sun4c_mmu_entry *entry = sun4c_user_strategy();
  1663. struct mm_struct *mm = vma->vm_mm;
  1664. unsigned long start, end;
  1665. entry->vaddr = start = (address & SUN4C_REAL_PGDIR_MASK);
  1666. entry->ctx = mm->context;
  1667. add_ring_ordered(sun4c_context_ring + mm->context, entry);
  1668. sun4c_put_segmap(entry->vaddr, entry->pseg);
  1669. end = start + SUN4C_REAL_PGDIR_SIZE;
  1670. while (start < end) {
  1671. #ifdef SUN4C_PRELOAD_PSEG
  1672. pgd_t *pgdp = sun4c_pgd_offset(mm, start);
  1673. pte_t *ptep;
  1674. if (!pgdp)
  1675. goto no_mapping;
  1676. ptep = sun4c_pte_offset((pmd_t *) pgdp, start);
  1677. if (!ptep || !(pte_val(*ptep) & _SUN4C_PAGE_PRESENT))
  1678. goto no_mapping;
  1679. sun4c_put_pte(start, pte_val(*ptep));
  1680. goto next;
  1681. no_mapping:
  1682. #endif
  1683. sun4c_put_pte(start, 0);
  1684. #ifdef SUN4C_PRELOAD_PSEG
  1685. next:
  1686. #endif
  1687. start += PAGE_SIZE;
  1688. }
  1689. #ifndef SUN4C_PRELOAD_PSEG
  1690. sun4c_put_pte(address, pte_val(pte));
  1691. #endif
  1692. restore_flags(flags);
  1693. return;
  1694. } else {
  1695. struct sun4c_mmu_entry *entry = &mmu_entry_pool[pseg];
  1696. remove_lru(entry);
  1697. add_lru(entry);
  1698. }
  1699. sun4c_put_pte(address, pte_val(pte));
  1700. restore_flags(flags);
  1701. }
  1702. extern void sparc_context_init(int);
  1703. extern unsigned long end;
  1704. extern unsigned long bootmem_init(unsigned long *pages_avail);
  1705. extern unsigned long last_valid_pfn;
  1706. extern void sun_serial_setup(void);
  1707. extern unsigned long fix_kmap_begin;
  1708. extern unsigned long fix_kmap_end;
  1709. void __init sun4c_paging_init(void)
  1710. {
  1711. int i, cnt;
  1712. unsigned long kernel_end, vaddr;
  1713. extern struct resource sparc_iomap;
  1714. unsigned long end_pfn, pages_avail;
  1715. fix_kmap_begin = KERNBASE + SRMMU_MAXMEM; /* Why bother with SRMMU_MAXMEM? */
  1716. fix_kmap_end = fix_kmap_begin + ((KM_TYPE_NR*NR_CPUS)-1)*PAGE_SIZE;
  1717. kernel_end = (unsigned long) &end;
  1718. kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4);
  1719. kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end);
  1720. pages_avail = 0;
  1721. last_valid_pfn = bootmem_init(&pages_avail);
  1722. end_pfn = last_valid_pfn;
  1723. /* This does not logically belong here, but we need to
  1724.  * call it at the moment we are able to use the bootmem
  1725.  * allocator.
  1726.  */
  1727. sun_serial_setup();
  1728. sun4c_probe_mmu();
  1729. invalid_segment = (num_segmaps - 1);
  1730. sun4c_init_mmu_entry_pool();
  1731. sun4c_init_rings();
  1732. sun4c_init_map_kernelprom(kernel_end);
  1733. sun4c_init_clean_mmu(kernel_end);
  1734. sun4c_init_fill_kernel_ring(SUN4C_KERNEL_BUCKETS);
  1735. sun4c_init_lock_area(sparc_iomap.start, IOBASE_END);
  1736. sun4c_init_lock_area(DVMA_VADDR, DVMA_END);
  1737. sun4c_init_lock_areas();
  1738. sun4c_init_fill_user_ring();
  1739. sun4c_set_context(0);
  1740. memset(swapper_pg_dir, 0, PAGE_SIZE);
  1741. memset(pg0, 0, PAGE_SIZE);
  1742. memset(pg1, 0, PAGE_SIZE);
  1743. memset(pg2, 0, PAGE_SIZE);
  1744. memset(pg3, 0, PAGE_SIZE);
  1745. /* Save work later. */
  1746. vaddr = VMALLOC_START;
  1747. swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg0);
  1748. vaddr += SUN4C_PGDIR_SIZE;
  1749. swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg1);
  1750. vaddr += SUN4C_PGDIR_SIZE;
  1751. swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg2);
  1752. vaddr += SUN4C_PGDIR_SIZE;
  1753. swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg3);
  1754. sun4c_init_ss2_cache_bug();
  1755. sparc_context_init(num_contexts);
  1756. {
  1757. unsigned long zones_size[MAX_NR_ZONES];
  1758. unsigned long zholes_size[MAX_NR_ZONES];
  1759. unsigned long npages;
  1760. int znum;
  1761. for (znum = 0; znum < MAX_NR_ZONES; znum++)
  1762. zones_size[znum] = zholes_size[znum] = 0;
  1763. npages = max_low_pfn - (phys_base >> PAGE_SHIFT);
  1764. zones_size[ZONE_DMA] = npages;
  1765. zholes_size[ZONE_DMA] = npages - pages_avail;
  1766. npages = highend_pfn - max_low_pfn;
  1767. zones_size[ZONE_HIGHMEM] = npages;
  1768. zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
  1769. free_area_init_node(0, NULL, NULL, zones_size,
  1770.     phys_base, zholes_size);
  1771. }
  1772. cnt = 0;
  1773. for (i = 0; i < num_segmaps; i++)
  1774. if (mmu_entry_pool[i].locked)
  1775. cnt++;
  1776. max_user_taken_entries = num_segmaps - cnt - 40 - 1;
  1777. printk("SUN4C: %d mmu entries for the kerneln", cnt);
  1778. }
  1779. /* Load up routines and constants for sun4c mmu */
  1780. void __init ld_mmu_sun4c(void)
  1781. {
  1782. extern void ___xchg32_sun4c(void);
  1783. printk("Loading sun4c MMU routinesn");
  1784. /* First the constants */
  1785. BTFIXUPSET_SIMM13(pmd_shift, SUN4C_PMD_SHIFT);
  1786. BTFIXUPSET_SETHI(pmd_size, SUN4C_PMD_SIZE);
  1787. BTFIXUPSET_SETHI(pmd_mask, SUN4C_PMD_MASK);
  1788. BTFIXUPSET_SIMM13(pgdir_shift, SUN4C_PGDIR_SHIFT);
  1789. BTFIXUPSET_SETHI(pgdir_size, SUN4C_PGDIR_SIZE);
  1790. BTFIXUPSET_SETHI(pgdir_mask, SUN4C_PGDIR_MASK);
  1791. BTFIXUPSET_SIMM13(ptrs_per_pte, SUN4C_PTRS_PER_PTE);
  1792. BTFIXUPSET_SIMM13(ptrs_per_pmd, SUN4C_PTRS_PER_PMD);
  1793. BTFIXUPSET_SIMM13(ptrs_per_pgd, SUN4C_PTRS_PER_PGD);
  1794. BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE);
  1795. BTFIXUPSET_INT(page_none, pgprot_val(SUN4C_PAGE_NONE));
  1796. BTFIXUPSET_INT(page_shared, pgprot_val(SUN4C_PAGE_SHARED));
  1797. BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY));
  1798. BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY));
  1799. BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL));
  1800. page_kernel = pgprot_val(SUN4C_PAGE_KERNEL);
  1801. pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE |
  1802.     _SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE;
  1803. /* Functions */
  1804. BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM);
  1805. BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM);
  1806. BTFIXUPSET_CALL(flush_cache_all, sun4c_flush_cache_all, BTFIXUPCALL_NORM);
  1807. if (sun4c_vacinfo.do_hwflushes) {
  1808. BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_hw, BTFIXUPCALL_NORM);
  1809. BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_hw, BTFIXUPCALL_NORM);
  1810. BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_hw, BTFIXUPCALL_NORM);
  1811. } else {
  1812. BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_sw, BTFIXUPCALL_NORM);
  1813. BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_sw, BTFIXUPCALL_NORM);
  1814. BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_sw, BTFIXUPCALL_NORM);
  1815. }
  1816. BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm, BTFIXUPCALL_NORM);
  1817. BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm, BTFIXUPCALL_NORM);
  1818. BTFIXUPSET_CALL(destroy_context, sun4c_destroy_context, BTFIXUPCALL_NORM);
  1819. BTFIXUPSET_CALL(switch_mm, sun4c_switch_mm, BTFIXUPCALL_NORM);
  1820. BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page, BTFIXUPCALL_NORM);
  1821. BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page, BTFIXUPCALL_NORM);
  1822. BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range, BTFIXUPCALL_NORM);
  1823. BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range, BTFIXUPCALL_NORM);
  1824. BTFIXUPSET_CALL(free_task_struct, sun4c_free_task_struct, BTFIXUPCALL_NORM);
  1825. BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram, BTFIXUPCALL_NORM);
  1826. BTFIXUPSET_CALL(flush_tlb_all, sun4c_flush_tlb_all, BTFIXUPCALL_NORM);
  1827. BTFIXUPSET_CALL(flush_sig_insns, sun4c_flush_sig_insns, BTFIXUPCALL_NOP);
  1828. BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0);
  1829. BTFIXUPSET_CALL(pte_page, sun4c_pte_page, BTFIXUPCALL_NORM);
  1830. #if PAGE_SHIFT <= 12
  1831. BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1));
  1832. #else
  1833. BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_NORM);
  1834. #endif
  1835. BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NORM);
  1836. BTFIXUPSET_CALL(pte_present, sun4c_pte_present, BTFIXUPCALL_NORM);
  1837. BTFIXUPSET_CALL(pte_clear, sun4c_pte_clear, BTFIXUPCALL_STG0O0);
  1838. BTFIXUPSET_CALL(pmd_bad, sun4c_pmd_bad, BTFIXUPCALL_NORM);
  1839. BTFIXUPSET_CALL(pmd_present, sun4c_pmd_present, BTFIXUPCALL_NORM);
  1840. BTFIXUPSET_CALL(pmd_clear, sun4c_pmd_clear, BTFIXUPCALL_STG0O0);
  1841. BTFIXUPSET_CALL(pgd_none, sun4c_pgd_none, BTFIXUPCALL_RETINT(0));
  1842. BTFIXUPSET_CALL(pgd_bad, sun4c_pgd_bad, BTFIXUPCALL_RETINT(0));
  1843. BTFIXUPSET_CALL(pgd_present, sun4c_pgd_present, BTFIXUPCALL_RETINT(1));
  1844. BTFIXUPSET_CALL(pgd_clear, sun4c_pgd_clear, BTFIXUPCALL_NOP);
  1845. BTFIXUPSET_CALL(mk_pte, sun4c_mk_pte, BTFIXUPCALL_NORM);
  1846. BTFIXUPSET_CALL(mk_pte_phys, sun4c_mk_pte_phys, BTFIXUPCALL_NORM);
  1847. BTFIXUPSET_CALL(mk_pte_io, sun4c_mk_pte_io, BTFIXUPCALL_NORM);
  1848. BTFIXUPSET_INT(pte_modify_mask, _SUN4C_PAGE_CHG_MASK);
  1849. BTFIXUPSET_CALL(pmd_offset, sun4c_pmd_offset, BTFIXUPCALL_NORM);
  1850. BTFIXUPSET_CALL(pte_offset, sun4c_pte_offset, BTFIXUPCALL_NORM);
  1851. BTFIXUPSET_CALL(free_pte_fast, sun4c_free_pte_fast, BTFIXUPCALL_NORM);
  1852. BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM);
  1853. BTFIXUPSET_CALL(pte_alloc_one_fast, sun4c_pte_alloc_one_fast, BTFIXUPCALL_NORM);
  1854. BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP);
  1855. BTFIXUPSET_CALL(pmd_alloc_one_fast, sun4c_pmd_alloc_one_fast, BTFIXUPCALL_RETO0);
  1856. BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM);
  1857. BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM);
  1858. BTFIXUPSET_HALF(pte_writei, _SUN4C_PAGE_WRITE);
  1859. BTFIXUPSET_HALF(pte_dirtyi, _SUN4C_PAGE_MODIFIED);
  1860. BTFIXUPSET_HALF(pte_youngi, _SUN4C_PAGE_ACCESSED);
  1861. BTFIXUPSET_HALF(pte_wrprotecti, _SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE);
  1862. BTFIXUPSET_HALF(pte_mkcleani, _SUN4C_PAGE_MODIFIED|_SUN4C_PAGE_SILENT_WRITE);
  1863. BTFIXUPSET_HALF(pte_mkoldi, _SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_SILENT_READ);
  1864. BTFIXUPSET_CALL(pte_mkwrite, sun4c_pte_mkwrite, BTFIXUPCALL_NORM);
  1865. BTFIXUPSET_CALL(pte_mkdirty, sun4c_pte_mkdirty, BTFIXUPCALL_NORM);
  1866. BTFIXUPSET_CALL(pte_mkyoung, sun4c_pte_mkyoung, BTFIXUPCALL_NORM);
  1867. BTFIXUPSET_CALL(update_mmu_cache, sun4c_update_mmu_cache, BTFIXUPCALL_NORM);
  1868. BTFIXUPSET_CALL(mmu_lockarea, sun4c_lockarea, BTFIXUPCALL_NORM);
  1869. BTFIXUPSET_CALL(mmu_unlockarea, sun4c_unlockarea, BTFIXUPCALL_NORM);
  1870. BTFIXUPSET_CALL(mmu_get_scsi_one, sun4c_get_scsi_one, BTFIXUPCALL_NORM);
  1871. BTFIXUPSET_CALL(mmu_get_scsi_sgl, sun4c_get_scsi_sgl, BTFIXUPCALL_NORM);
  1872. BTFIXUPSET_CALL(mmu_release_scsi_one, sun4c_release_scsi_one, BTFIXUPCALL_NORM);
  1873. BTFIXUPSET_CALL(mmu_release_scsi_sgl, sun4c_release_scsi_sgl, BTFIXUPCALL_NORM);
  1874. BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM);
  1875. BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM);
  1876. BTFIXUPSET_CALL(mmu_translate_dvma, sun4c_translate_dvma, BTFIXUPCALL_NORM);
  1877. /* Task struct and kernel stack allocating/freeing. */
  1878. BTFIXUPSET_CALL(alloc_task_struct, sun4c_alloc_task_struct, BTFIXUPCALL_NORM);
  1879. BTFIXUPSET_CALL(get_task_struct, sun4c_get_task_struct, BTFIXUPCALL_NORM);
  1880. BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM);
  1881. /* These should _never_ get called with two level tables. */
  1882. BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP);
  1883. BTFIXUPSET_CALL(pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0);
  1884. }