/sys/powerpc/aim/machdep.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 784 lines · 481 code · 123 blank · 180 comment · 53 complexity · 1fe4da80bfefd2bc660437ba1a86e9b6 MD5 · raw file

  1. /*-
  2. * Copyright (C) 1995, 1996 Wolfgang Solfrank.
  3. * Copyright (C) 1995, 1996 TooLs GmbH.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. All advertising materials mentioning features or use of this software
  15. * must display the following acknowledgement:
  16. * This product includes software developed by TooLs GmbH.
  17. * 4. The name of TooLs GmbH may not be used to endorse or promote products
  18. * derived from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
  21. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  22. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23. * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  26. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  27. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. /*-
  32. * Copyright (C) 2001 Benno Rice
  33. * All rights reserved.
  34. *
  35. * Redistribution and use in source and binary forms, with or without
  36. * modification, are permitted provided that the following conditions
  37. * are met:
  38. * 1. Redistributions of source code must retain the above copyright
  39. * notice, this list of conditions and the following disclaimer.
  40. * 2. Redistributions in binary form must reproduce the above copyright
  41. * notice, this list of conditions and the following disclaimer in the
  42. * documentation and/or other materials provided with the distribution.
  43. *
  44. * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
  45. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  46. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  47. * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  48. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  49. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  50. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  51. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  52. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  53. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54. * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $
  55. */
  56. #include <sys/cdefs.h>
  57. __FBSDID("$FreeBSD$");
  58. #include "opt_compat.h"
  59. #include "opt_ddb.h"
  60. #include "opt_kstack_pages.h"
  61. #include "opt_platform.h"
  62. #include <sys/param.h>
  63. #include <sys/proc.h>
  64. #include <sys/systm.h>
  65. #include <sys/bio.h>
  66. #include <sys/buf.h>
  67. #include <sys/bus.h>
  68. #include <sys/cons.h>
  69. #include <sys/cpu.h>
  70. #include <sys/eventhandler.h>
  71. #include <sys/exec.h>
  72. #include <sys/imgact.h>
  73. #include <sys/kdb.h>
  74. #include <sys/kernel.h>
  75. #include <sys/ktr.h>
  76. #include <sys/linker.h>
  77. #include <sys/lock.h>
  78. #include <sys/malloc.h>
  79. #include <sys/mbuf.h>
  80. #include <sys/msgbuf.h>
  81. #include <sys/mutex.h>
  82. #include <sys/ptrace.h>
  83. #include <sys/reboot.h>
  84. #include <sys/signalvar.h>
  85. #include <sys/syscallsubr.h>
  86. #include <sys/sysctl.h>
  87. #include <sys/sysent.h>
  88. #include <sys/sysproto.h>
  89. #include <sys/ucontext.h>
  90. #include <sys/uio.h>
  91. #include <sys/vmmeter.h>
  92. #include <sys/vnode.h>
  93. #include <net/netisr.h>
  94. #include <vm/vm.h>
  95. #include <vm/vm_extern.h>
  96. #include <vm/vm_kern.h>
  97. #include <vm/vm_page.h>
  98. #include <vm/vm_map.h>
  99. #include <vm/vm_object.h>
  100. #include <vm/vm_pager.h>
  101. #include <machine/altivec.h>
  102. #ifndef __powerpc64__
  103. #include <machine/bat.h>
  104. #endif
  105. #include <machine/cpu.h>
  106. #include <machine/elf.h>
  107. #include <machine/fpu.h>
  108. #include <machine/hid.h>
  109. #include <machine/kdb.h>
  110. #include <machine/md_var.h>
  111. #include <machine/metadata.h>
  112. #include <machine/mmuvar.h>
  113. #include <machine/pcb.h>
  114. #include <machine/reg.h>
  115. #include <machine/sigframe.h>
  116. #include <machine/spr.h>
  117. #include <machine/trap.h>
  118. #include <machine/vmparam.h>
  119. #include <ddb/ddb.h>
  120. #include <dev/ofw/openfirm.h>
  121. #ifdef DDB
  122. extern vm_offset_t ksym_start, ksym_end;
  123. #endif
  124. int cold = 1;
  125. #ifdef __powerpc64__
  126. extern int n_slbs;
  127. int cacheline_size = 128;
  128. #else
  129. int cacheline_size = 32;
  130. #endif
  131. int hw_direct_map = 1;
  132. struct pcpu __pcpu[MAXCPU];
  133. static struct trapframe frame0;
  134. char machine[] = "powerpc";
  135. SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
  136. static void cpu_startup(void *);
  137. SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
  138. SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
  139. CTLFLAG_RD, &cacheline_size, 0, "");
  140. uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *);
  141. int setfault(faultbuf); /* defined in locore.S */
  142. long Maxmem = 0;
  143. long realmem = 0;
  144. #ifndef __powerpc64__
  145. struct bat battable[16];
  146. #endif
  147. struct kva_md_info kmi;
  148. static void
  149. cpu_startup(void *dummy)
  150. {
  151. /*
  152. * Initialise the decrementer-based clock.
  153. */
  154. decr_init();
  155. /*
  156. * Good {morning,afternoon,evening,night}.
  157. */
  158. cpu_setup(PCPU_GET(cpuid));
  159. #ifdef PERFMON
  160. perfmon_init();
  161. #endif
  162. printf("real memory = %ld (%ld MB)\n", ptoa(physmem),
  163. ptoa(physmem) / 1048576);
  164. realmem = physmem;
  165. if (bootverbose)
  166. printf("available KVA = %zd (%zd MB)\n",
  167. virtual_end - virtual_avail,
  168. (virtual_end - virtual_avail) / 1048576);
  169. /*
  170. * Display any holes after the first chunk of extended memory.
  171. */
  172. if (bootverbose) {
  173. int indx;
  174. printf("Physical memory chunk(s):\n");
  175. for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
  176. vm_offset_t size1 =
  177. phys_avail[indx + 1] - phys_avail[indx];
  178. #ifdef __powerpc64__
  179. printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n",
  180. #else
  181. printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n",
  182. #endif
  183. phys_avail[indx], phys_avail[indx + 1] - 1, size1,
  184. size1 / PAGE_SIZE);
  185. }
  186. }
  187. vm_ksubmap_init(&kmi);
  188. printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count),
  189. ptoa(cnt.v_free_count) / 1048576);
  190. /*
  191. * Set up buffers, so they can be used to read disk labels.
  192. */
  193. bufinit();
  194. vm_pager_bufferinit();
  195. }
  196. extern char kernel_text[], _end[];
  197. #ifndef __powerpc64__
  198. /* Bits for running on 64-bit systems in 32-bit mode. */
  199. extern void *testppc64, *testppc64size;
  200. extern void *restorebridge, *restorebridgesize;
  201. extern void *rfid_patch, *rfi_patch1, *rfi_patch2;
  202. extern void *trapcode64;
  203. #endif
  204. #ifdef SMP
  205. extern void *rstcode, *rstsize;
  206. #endif
  207. extern void *trapcode, *trapsize;
  208. extern void *slbtrap, *slbtrapsize;
  209. extern void *alitrap, *alisize;
  210. extern void *dsitrap, *dsisize;
  211. extern void *decrint, *decrsize;
  212. extern void *extint, *extsize;
  213. extern void *dblow, *dbsize;
  214. extern void *imisstrap, *imisssize;
  215. extern void *dlmisstrap, *dlmisssize;
  216. extern void *dsmisstrap, *dsmisssize;
  217. uintptr_t
  218. powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel,
  219. vm_offset_t basekernel, void *mdp)
  220. {
  221. struct pcpu *pc;
  222. void *generictrap;
  223. size_t trap_offset;
  224. void *kmdp;
  225. char *env;
  226. register_t msr, scratch;
  227. #ifdef WII
  228. register_t vers;
  229. #endif
  230. uint8_t *cache_check;
  231. int cacheline_warn;
  232. #ifndef __powerpc64__
  233. int ppc64;
  234. #endif
  235. kmdp = NULL;
  236. trap_offset = 0;
  237. cacheline_warn = 0;
  238. #ifdef WII
  239. /*
  240. * The Wii loader doesn't pass us any environment so, mdp
  241. * points to garbage at this point. The Wii CPU is a 750CL.
  242. */
  243. vers = mfpvr();
  244. if ((vers & 0xfffff0e0) == (MPC750 << 16 | MPC750CL))
  245. mdp = NULL;
  246. #endif
  247. /*
  248. * Parse metadata if present and fetch parameters. Must be done
  249. * before console is inited so cninit gets the right value of
  250. * boothowto.
  251. */
  252. if (mdp != NULL) {
  253. preload_metadata = mdp;
  254. kmdp = preload_search_by_type("elf kernel");
  255. if (kmdp != NULL) {
  256. boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
  257. kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
  258. endkernel = ulmax(endkernel, MD_FETCH(kmdp,
  259. MODINFOMD_KERNEND, vm_offset_t));
  260. #ifdef DDB
  261. ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
  262. ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
  263. #endif
  264. }
  265. }
  266. /*
  267. * Init params/tunables that can be overridden by the loader
  268. */
  269. init_param1();
  270. /*
  271. * Start initializing proc0 and thread0.
  272. */
  273. proc_linkup0(&proc0, &thread0);
  274. thread0.td_frame = &frame0;
  275. /*
  276. * Set up per-cpu data.
  277. */
  278. pc = __pcpu;
  279. pcpu_init(pc, 0, sizeof(struct pcpu));
  280. pc->pc_curthread = &thread0;
  281. #ifdef __powerpc64__
  282. __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread));
  283. #else
  284. __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread));
  285. #endif
  286. pc->pc_cpuid = 0;
  287. __asm __volatile("mtsprg 0, %0" :: "r"(pc));
  288. /*
  289. * Init mutexes, which we use heavily in PMAP
  290. */
  291. mutex_init();
  292. /*
  293. * Install the OF client interface
  294. */
  295. OF_bootstrap();
  296. /*
  297. * Initialize the console before printing anything.
  298. */
  299. cninit();
  300. /*
  301. * Complain if there is no metadata.
  302. */
  303. if (mdp == NULL || kmdp == NULL) {
  304. printf("powerpc_init: no loader metadata.\n");
  305. }
  306. /*
  307. * Init KDB
  308. */
  309. kdb_init();
  310. /* Various very early CPU fix ups */
  311. switch (mfpvr() >> 16) {
  312. /*
  313. * PowerPC 970 CPUs have a misfeature requested by Apple that
  314. * makes them pretend they have a 32-byte cacheline. Turn this
  315. * off before we measure the cacheline size.
  316. */
  317. case IBM970:
  318. case IBM970FX:
  319. case IBM970MP:
  320. case IBM970GX:
  321. scratch = mfspr(SPR_HID5);
  322. scratch &= ~HID5_970_DCBZ_SIZE_HI;
  323. mtspr(SPR_HID5, scratch);
  324. break;
  325. #ifdef __powerpc64__
  326. case IBMPOWER7:
  327. /* XXX: get from ibm,slb-size in device tree */
  328. n_slbs = 32;
  329. break;
  330. #endif
  331. }
  332. /*
  333. * Initialize the interrupt tables and figure out our cache line
  334. * size and whether or not we need the 64-bit bridge code.
  335. */
  336. /*
  337. * Disable translation in case the vector area hasn't been
  338. * mapped (G5). Note that no OFW calls can be made until
  339. * translation is re-enabled.
  340. */
  341. msr = mfmsr();
  342. mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI);
  343. /*
  344. * Measure the cacheline size using dcbz
  345. *
  346. * Use EXC_PGM as a playground. We are about to overwrite it
  347. * anyway, we know it exists, and we know it is cache-aligned.
  348. */
  349. cache_check = (void *)EXC_PGM;
  350. for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++)
  351. cache_check[cacheline_size] = 0xff;
  352. __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory");
  353. /* Find the first byte dcbz did not zero to get the cache line size */
  354. for (cacheline_size = 0; cacheline_size < 0x100 &&
  355. cache_check[cacheline_size] == 0; cacheline_size++);
  356. /* Work around psim bug */
  357. if (cacheline_size == 0) {
  358. cacheline_warn = 1;
  359. cacheline_size = 32;
  360. }
  361. /* Make sure the kernel icache is valid before we go too much further */
  362. __syncicache((caddr_t)startkernel, endkernel - startkernel);
  363. #ifndef __powerpc64__
  364. /*
  365. * Figure out whether we need to use the 64 bit PMAP. This works by
  366. * executing an instruction that is only legal on 64-bit PPC (mtmsrd),
  367. * and setting ppc64 = 0 if that causes a trap.
  368. */
  369. ppc64 = 1;
  370. bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size);
  371. __syncicache((void *)EXC_PGM, (size_t)&testppc64size);
  372. __asm __volatile("\
  373. mfmsr %0; \
  374. mtsprg2 %1; \
  375. \
  376. mtmsrd %0; \
  377. mfsprg2 %1;"
  378. : "=r"(scratch), "=r"(ppc64));
  379. if (ppc64)
  380. cpu_features |= PPC_FEATURE_64;
  381. /*
  382. * Now copy restorebridge into all the handlers, if necessary,
  383. * and set up the trap tables.
  384. */
  385. if (cpu_features & PPC_FEATURE_64) {
  386. /* Patch the two instances of rfi -> rfid */
  387. bcopy(&rfid_patch,&rfi_patch1,4);
  388. #ifdef KDB
  389. /* rfi_patch2 is at the end of dbleave */
  390. bcopy(&rfid_patch,&rfi_patch2,4);
  391. #endif
  392. /*
  393. * Copy a code snippet to restore 32-bit bridge mode
  394. * to the top of every non-generic trap handler
  395. */
  396. trap_offset += (size_t)&restorebridgesize;
  397. bcopy(&restorebridge, (void *)EXC_RST, trap_offset);
  398. bcopy(&restorebridge, (void *)EXC_DSI, trap_offset);
  399. bcopy(&restorebridge, (void *)EXC_ALI, trap_offset);
  400. bcopy(&restorebridge, (void *)EXC_PGM, trap_offset);
  401. bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset);
  402. bcopy(&restorebridge, (void *)EXC_TRC, trap_offset);
  403. bcopy(&restorebridge, (void *)EXC_BPT, trap_offset);
  404. /*
  405. * Set the common trap entry point to the one that
  406. * knows to restore 32-bit operation on execution.
  407. */
  408. generictrap = &trapcode64;
  409. } else {
  410. generictrap = &trapcode;
  411. }
  412. #else /* powerpc64 */
  413. cpu_features |= PPC_FEATURE_64;
  414. generictrap = &trapcode;
  415. #endif
  416. #ifdef SMP
  417. bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstsize);
  418. #else
  419. bcopy(generictrap, (void *)EXC_RST, (size_t)&trapsize);
  420. #endif
  421. #ifdef KDB
  422. bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbsize);
  423. bcopy(&dblow, (void *)(EXC_PGM + trap_offset), (size_t)&dbsize);
  424. bcopy(&dblow, (void *)(EXC_TRC + trap_offset), (size_t)&dbsize);
  425. bcopy(&dblow, (void *)(EXC_BPT + trap_offset), (size_t)&dbsize);
  426. #else
  427. bcopy(generictrap, (void *)EXC_MCHK, (size_t)&trapsize);
  428. bcopy(generictrap, (void *)EXC_PGM, (size_t)&trapsize);
  429. bcopy(generictrap, (void *)EXC_TRC, (size_t)&trapsize);
  430. bcopy(generictrap, (void *)EXC_BPT, (size_t)&trapsize);
  431. #endif
  432. bcopy(&alitrap, (void *)(EXC_ALI + trap_offset), (size_t)&alisize);
  433. bcopy(&dsitrap, (void *)(EXC_DSI + trap_offset), (size_t)&dsisize);
  434. bcopy(generictrap, (void *)EXC_ISI, (size_t)&trapsize);
  435. #ifdef __powerpc64__
  436. bcopy(&slbtrap, (void *)EXC_DSE, (size_t)&slbtrapsize);
  437. bcopy(&slbtrap, (void *)EXC_ISE, (size_t)&slbtrapsize);
  438. #endif
  439. bcopy(generictrap, (void *)EXC_EXI, (size_t)&trapsize);
  440. bcopy(generictrap, (void *)EXC_FPU, (size_t)&trapsize);
  441. bcopy(generictrap, (void *)EXC_DECR, (size_t)&trapsize);
  442. bcopy(generictrap, (void *)EXC_SC, (size_t)&trapsize);
  443. bcopy(generictrap, (void *)EXC_FPA, (size_t)&trapsize);
  444. bcopy(generictrap, (void *)EXC_VEC, (size_t)&trapsize);
  445. bcopy(generictrap, (void *)EXC_PERF, (size_t)&trapsize);
  446. bcopy(generictrap, (void *)EXC_VECAST_G4, (size_t)&trapsize);
  447. bcopy(generictrap, (void *)EXC_VECAST_G5, (size_t)&trapsize);
  448. #ifndef __powerpc64__
  449. /* G2-specific TLB miss helper handlers */
  450. bcopy(&imisstrap, (void *)EXC_IMISS, (size_t)&imisssize);
  451. bcopy(&dlmisstrap, (void *)EXC_DLMISS, (size_t)&dlmisssize);
  452. bcopy(&dsmisstrap, (void *)EXC_DSMISS, (size_t)&dsmisssize);
  453. #endif
  454. __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD);
  455. /*
  456. * Restore MSR
  457. */
  458. mtmsr(msr);
  459. /* Warn if cachline size was not determined */
  460. if (cacheline_warn == 1) {
  461. printf("WARNING: cacheline size undetermined, setting to 32\n");
  462. }
  463. /*
  464. * Choose a platform module so we can get the physical memory map.
  465. */
  466. platform_probe_and_attach();
  467. /*
  468. * Initialise virtual memory. Use BUS_PROBE_GENERIC priority
  469. * in case the platform module had a better idea of what we
  470. * should do.
  471. */
  472. if (cpu_features & PPC_FEATURE_64)
  473. pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC);
  474. else
  475. pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC);
  476. pmap_bootstrap(startkernel, endkernel);
  477. mtmsr(PSL_KERNSET & ~PSL_EE);
  478. /*
  479. * Initialize params/tunables that are derived from memsize
  480. */
  481. init_param2(physmem);
  482. /*
  483. * Grab booted kernel's name
  484. */
  485. env = getenv("kernelname");
  486. if (env != NULL) {
  487. strlcpy(kernelname, env, sizeof(kernelname));
  488. freeenv(env);
  489. }
  490. /*
  491. * Finish setting up thread0.
  492. */
  493. thread0.td_pcb = (struct pcb *)
  494. ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE -
  495. sizeof(struct pcb)) & ~15UL);
  496. bzero((void *)thread0.td_pcb, sizeof(struct pcb));
  497. pc->pc_curpcb = thread0.td_pcb;
  498. /* Initialise the message buffer. */
  499. msgbufinit(msgbufp, msgbufsize);
  500. #ifdef KDB
  501. if (boothowto & RB_KDB)
  502. kdb_enter(KDB_WHY_BOOTFLAGS,
  503. "Boot flags requested debugger");
  504. #endif
  505. return (((uintptr_t)thread0.td_pcb -
  506. (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL);
  507. }
  508. void
  509. bzero(void *buf, size_t len)
  510. {
  511. caddr_t p;
  512. p = buf;
  513. while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
  514. *p++ = 0;
  515. len--;
  516. }
  517. while (len >= sizeof(u_long) * 8) {
  518. *(u_long*) p = 0;
  519. *((u_long*) p + 1) = 0;
  520. *((u_long*) p + 2) = 0;
  521. *((u_long*) p + 3) = 0;
  522. len -= sizeof(u_long) * 8;
  523. *((u_long*) p + 4) = 0;
  524. *((u_long*) p + 5) = 0;
  525. *((u_long*) p + 6) = 0;
  526. *((u_long*) p + 7) = 0;
  527. p += sizeof(u_long) * 8;
  528. }
  529. while (len >= sizeof(u_long)) {
  530. *(u_long*) p = 0;
  531. len -= sizeof(u_long);
  532. p += sizeof(u_long);
  533. }
  534. while (len) {
  535. *p++ = 0;
  536. len--;
  537. }
  538. }
  539. void
  540. cpu_boot(int howto)
  541. {
  542. }
  543. /*
  544. * Flush the D-cache for non-DMA I/O so that the I-cache can
  545. * be made coherent later.
  546. */
  547. void
  548. cpu_flush_dcache(void *ptr, size_t len)
  549. {
  550. /* TBD */
  551. }
  552. void
  553. cpu_initclocks(void)
  554. {
  555. decr_tc_init();
  556. cpu_initclocks_bsp();
  557. }
  558. /*
  559. * Shutdown the CPU as much as possible.
  560. */
  561. void
  562. cpu_halt(void)
  563. {
  564. OF_exit();
  565. }
  566. int
  567. ptrace_set_pc(struct thread *td, unsigned long addr)
  568. {
  569. struct trapframe *tf;
  570. tf = td->td_frame;
  571. tf->srr0 = (register_t)addr;
  572. return (0);
  573. }
  574. int
  575. ptrace_single_step(struct thread *td)
  576. {
  577. struct trapframe *tf;
  578. tf = td->td_frame;
  579. tf->srr1 |= PSL_SE;
  580. return (0);
  581. }
  582. int
  583. ptrace_clear_single_step(struct thread *td)
  584. {
  585. struct trapframe *tf;
  586. tf = td->td_frame;
  587. tf->srr1 &= ~PSL_SE;
  588. return (0);
  589. }
  590. void
  591. kdb_cpu_clear_singlestep(void)
  592. {
  593. kdb_frame->srr1 &= ~PSL_SE;
  594. }
  595. void
  596. kdb_cpu_set_singlestep(void)
  597. {
  598. kdb_frame->srr1 |= PSL_SE;
  599. }
  600. /*
  601. * Initialise a struct pcpu.
  602. */
  603. void
  604. cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
  605. {
  606. #ifdef __powerpc64__
  607. /* Copy the SLB contents from the current CPU */
  608. memcpy(pcpu->pc_slb, PCPU_GET(slb), sizeof(pcpu->pc_slb));
  609. #endif
  610. }
  611. void
  612. spinlock_enter(void)
  613. {
  614. struct thread *td;
  615. register_t msr;
  616. td = curthread;
  617. if (td->td_md.md_spinlock_count == 0) {
  618. msr = intr_disable();
  619. td->td_md.md_spinlock_count = 1;
  620. td->td_md.md_saved_msr = msr;
  621. } else
  622. td->td_md.md_spinlock_count++;
  623. critical_enter();
  624. }
  625. void
  626. spinlock_exit(void)
  627. {
  628. struct thread *td;
  629. register_t msr;
  630. td = curthread;
  631. critical_exit();
  632. msr = td->td_md.md_saved_msr;
  633. td->td_md.md_spinlock_count--;
  634. if (td->td_md.md_spinlock_count == 0)
  635. intr_restore(msr);
  636. }
  637. int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */
  638. int
  639. db_trap_glue(struct trapframe *frame)
  640. {
  641. if (!(frame->srr1 & PSL_PR)
  642. && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC
  643. || (frame->exc == EXC_PGM
  644. && (frame->srr1 & 0x20000))
  645. || frame->exc == EXC_BPT
  646. || frame->exc == EXC_DSI)) {
  647. int type = frame->exc;
  648. if (type == EXC_PGM && (frame->srr1 & 0x20000)) {
  649. type = T_BREAKPOINT;
  650. }
  651. return (kdb_trap(type, 0, frame));
  652. }
  653. return (0);
  654. }
  655. #ifndef __powerpc64__
  656. uint64_t
  657. va_to_vsid(pmap_t pm, vm_offset_t va)
  658. {
  659. return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK);
  660. }
  661. #endif