static void fbt_enable(void *arg, dtrace_id_t id, void *parg) { fbt_probe_t *fbt = parg; modctl_t *ctl = fbt->fbtp_ctl; ctl->nenabled++; /* * Now check that our modctl has the expected load count. If it * doesn't, this module must have been unloaded and reloaded -- and * we're not going to touch it. */ if (ctl->loadcnt != fbt->fbtp_loadcnt) { if (fbt_verbose) { printf("fbt is failing for probe %s " "(module %s reloaded)", fbt->fbtp_name, ctl->filename); } return; } for (; fbt != NULL; fbt = fbt->fbtp_next) { *fbt->fbtp_patchpoint = fbt->fbtp_patchval; __syncicache(fbt->fbtp_patchpoint, 4); } }
void fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val) { *fbt->fbtp_patchpoint = val; __syncicache(fbt->fbtp_patchpoint, 4); }
int elf_cpu_load_file(linker_file_t lf) { /* Only sync the cache for non-kernel modules */ if (lf->id != 1) __syncicache(lf->address, lf->size); return (0); }
int md_setup_trampoline(volatile struct cpu_hatch_data *h, struct cpu_info *ci) { if (!openpic_base) return -1; /* construct an absolute branch instruction */ /* ba cpu_spinup_trampoline */ *(u_int *)EXC_RST = 0x48000002 | (u_int)cpu_spinup_trampoline; __syncicache((void *)EXC_RST, 0x100); h->running = -1; /* Start secondary CPU. */ openpic_write(OPENPIC_PROC_INIT, (1 << 1)); return 1; }
static void fbt_resume(void *arg, dtrace_id_t id, void *parg) { fbt_probe_t *fbt = parg; modctl_t *ctl = fbt->fbtp_ctl; ASSERT(ctl->nenabled > 0); if ((ctl->loadcnt != fbt->fbtp_loadcnt)) return; for (; fbt != NULL; fbt = fbt->fbtp_next) { *fbt->fbtp_patchpoint = fbt->fbtp_patchval; __syncicache(fbt->fbtp_patchpoint, 4); } }
int ppc64_ofw_elf_loadfile(char *filename, u_int64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); /* * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ if (!strcmp((*result)->f_type, "elf kernel")) __syncicache((void *) (*result)->f_addr, (*result)->f_size); return (0); }
int __elfN(uboot_load)(char *filename, u_int64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); #if defined(__powerpc__) /* * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ if (!strcmp((*result)->f_type, "elf kernel")) __syncicache((void *) (*result)->f_addr, (*result)->f_size); #endif return (0); }
void main(int argc, char *argv[], char *bootargs_start, char *bootargs_end) { unsigned long marks[MARK_MAX]; struct brdprop *brdprop; char *new_argv[MAX_ARGS]; char *bname; ssize_t len; int err, fd, howto, i, n; printf("\n>> %s altboot, revision %s\n", bootprog_name, bootprog_rev); brdprop = brd_lookup(brdtype); printf(">> %s, cpu %u MHz, bus %u MHz, %dMB SDRAM\n", brdprop->verbose, cpuclock / 1000000, busclock / 1000000, bi_mem.memsize >> 20); nata = pcilookup(PCI_CLASS_IDE, lata, 2); if (nata == 0) nata = pcilookup(PCI_CLASS_RAID, lata, 2); if (nata == 0) nata = pcilookup(PCI_CLASS_MISCSTORAGE, lata, 2); if (nata == 0) nata = pcilookup(PCI_CLASS_SCSI, lata, 2); nnif = pcilookup(PCI_CLASS_ETH, lnif, 2); nusb = pcilookup(PCI_CLASS_USB, lusb, 3); #ifdef DEBUG if (nata == 0) printf("No IDE/SATA found\n"); else for (n = 0; n < nata; n++) { int b, d, f, bdf, pvd; bdf = lata[n].bdf; pvd = lata[n].pvd; pcidecomposetag(bdf, &b, &d, &f); printf("%04x.%04x DSK %02d:%02d:%02d\n", PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f); } if (nnif == 0) printf("no NET found\n"); else for (n = 0; n < nnif; n++) { int b, d, f, bdf, pvd; bdf = lnif[n].bdf; pvd = lnif[n].pvd; pcidecomposetag(bdf, &b, &d, &f); printf("%04x.%04x NET %02d:%02d:%02d\n", PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f); } if (nusb == 0) printf("no USB found\n"); else for (n = 0; n < nusb; n++) { int b, d, f, bdf, pvd; bdf = lusb[0].bdf; pvd = lusb[0].pvd; pcidecomposetag(bdf, &b, &d, &f); printf("%04x.%04x USB %02d:%02d:%02d\n", PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f); } #endif pcisetup(); pcifixup(); /* * When argc is too big then it is probably a pointer, which could * indicate that we were launched as a Linux kernel module using * "bootm". */ if (argc > MAX_ARGS) { if (argv != NULL) { /* * initrd image was loaded: * check if it contains a valid altboot command line */ char *p = (char *)argv; if (strncmp(p, "altboot:", 8) == 0) { *p = 0; for (p = p + 8; *p >= ' '; p++); argc = parse_cmdline(new_argv, MAX_ARGS, ((char *)argv) + 8, p); argv = new_argv; } else argc = 0; /* boot default */ } else { /* parse standard Linux bootargs */ argc = parse_cmdline(new_argv, MAX_ARGS, bootargs_start, bootargs_end); argv = new_argv; } } /* look for a PATA drive configuration string under the arguments */ for (n = 1; n < argc; n++) { if (strncmp(argv[n], "ide:", 4) == 0 && argv[n][4] >= '0' && argv[n][4] <= '2') { drive_config = &argv[n][4]; break; } } /* intialize a disk driver */ for (i = 0, n = 0; i < nata; i++) n += dskdv_init(&lata[i]); if (n == 0) printf("IDE/SATA device driver was not found\n"); /* initialize a network interface */ for (n = 0; n < nnif; n++) if (netif_init(&lnif[n]) != 0) break; if (n >= nnif) printf("no NET device driver was found\n"); /* wait 2s for user to enter interactive mode */ for (n = 200; n >= 0; n--) { if (n % 100 == 0) printf("\rHit any key to enter interactive mode: %d", n / 100); if (tstchar()) { #ifdef DEBUG unsigned c; c = toupper(getchar()); if (c == 'C') { /* controller test terminal */ sat_test(); n = 200; continue; } else if (c == 'F') { /* find strings in Flash ROM */ findflash(); n = 200; continue; } #else (void)getchar(); #endif /* enter command line */ argv = new_argv; argc = input_cmdline(argv, MAX_ARGS); break; } delay(10000); } putchar('\n'); howto = RB_AUTOBOOT; /* default is autoboot = 0 */ /* get boot options and determine bootname */ for (n = 1; n < argc; n++) { if (strncmp(argv[n], "ide:", 4) == 0) continue; /* ignore drive configuration argument */ for (i = 0; i < sizeof(bootargs) / sizeof(bootargs[0]); i++) { if (strncasecmp(argv[n], bootargs[i].name, strlen(bootargs[i].name)) == 0) { howto |= bootargs[i].value; break; } } if (i >= sizeof(bootargs) / sizeof(bootargs[0])) break; /* break on first unknown string */ } /* * If no device name is given, we construct a list of drives * which have valid disklabels. */ if (n >= argc) { static const size_t blen = sizeof("wdN:"); n = 0; argc = 0; argv = alloc(MAX_UNITS * (sizeof(char *) + blen)); bname = (char *)(argv + MAX_UNITS); for (i = 0; i < MAX_UNITS; i++) { if (!dlabel_valid(i)) continue; snprintf(bname, blen, "wd%d:", i); argv[argc++] = bname; bname += blen; } /* use default drive if no valid disklabel is found */ if (argc == 0) { argc = 1; argv[0] = BNAME_DEFAULT; } } /* try to boot off kernel from the drive list */ while (n < argc) { bname = argv[n++]; if (check_bootname(bname) == 0) { printf("%s not a valid bootname\n", bname); continue; } if ((fd = open(bname, 0)) < 0) { if (errno == ENOENT) printf("\"%s\" not found\n", bi_path.bootpath); continue; } printf("loading \"%s\" ", bi_path.bootpath); marks[MARK_START] = 0; if (howto == -1) { /* load another altboot binary and replace ourselves */ len = read(fd, (void *)0x100000, 0x1000000 - 0x100000); if (len == -1) goto loadfail; close(fd); netif_shutdown_all(); memcpy((void *)0xf0000, newaltboot, newaltboot_end - newaltboot); __syncicache((void *)0xf0000, newaltboot_end - newaltboot); printf("Restarting...\n"); run((void *)1, argv, (void *)0x100000, (void *)len, (void *)0xf0000); } err = fdloadfile(fd, marks, LOAD_KERNEL); close(fd); if (err < 0) continue; printf("entry=%p, ssym=%p, esym=%p\n", (void *)marks[MARK_ENTRY], (void *)marks[MARK_SYM], (void *)marks[MARK_END]); bootinfo = (void *)0x4000; bi_init(bootinfo); bi_add(&bi_cons, BTINFO_CONSOLE, sizeof(bi_cons)); bi_add(&bi_mem, BTINFO_MEMORY, sizeof(bi_mem)); bi_add(&bi_clk, BTINFO_CLOCK, sizeof(bi_clk)); bi_add(&bi_path, BTINFO_BOOTPATH, sizeof(bi_path)); bi_add(&bi_rdev, BTINFO_ROOTDEVICE, sizeof(bi_rdev)); bi_add(&bi_fam, BTINFO_PRODFAMILY, sizeof(bi_fam)); if (brdtype == BRD_SYNOLOGY || brdtype == BRD_DLINKDSM) { /* need to pass this MAC address to kernel */ bi_add(&bi_net, BTINFO_NET, sizeof(bi_net)); } if (modules_enabled) { if (fsmod != NULL) module_add(fsmod); kmodloadp = marks[MARK_END]; btinfo_modulelist = NULL; module_load(bname); if (btinfo_modulelist != NULL && btinfo_modulelist->num > 0) bi_add(btinfo_modulelist, BTINFO_MODULELIST, btinfo_modulelist_size); } launchfixup(); netif_shutdown_all(); __syncicache((void *)marks[MARK_ENTRY], (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); run((void *)marks[MARK_SYM], (void *)marks[MARK_END], (void *)howto, bootinfo, (void *)marks[MARK_ENTRY]); /* should never come here */ printf("exec returned. Restarting...\n"); _rtt(); } loadfail: printf("load failed. Restarting...\n"); _rtt(); }
/* * Halt or reboot the machine after syncing/dumping according to howto. */ void cpu_reboot(int howto, char *what) { static int syncing; static char str[256]; char *ap = str, *ap1 = ap; boothowto = howto; if (!cold && !(howto & RB_NOSYNC) && !syncing) { syncing = 1; vfs_shutdown(); /* sync */ resettodr(); /* set wall clock */ } splhigh(); if (!cold && (howto & RB_DUMP)) ibm4xx_dumpsys(); doshutdownhooks(); pmf_system_shutdown(boothowto); if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { /* Power off here if we know how...*/ } if (howto & RB_HALT) { printf("halted\n\n"); #if 0 goto reboot; /* XXX for now... */ #endif #ifdef DDB printf("dropping to debugger\n"); while(1) Debugger(); #endif } printf("rebooting\n\n"); if (what && *what) { if (strlen(what) > sizeof str - 5) printf("boot string too large, ignored\n"); else { strcpy(str, what); ap1 = ap = str + strlen(str); *ap++ = ' '; } } *ap++ = '-'; if (howto & RB_SINGLE) *ap++ = 's'; if (howto & RB_KDB) *ap++ = 'd'; *ap++ = 0; if (ap[-2] == '-') *ap1 = 0; /* flush cache for msgbuf */ __syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE)); #if 0 reboot: #endif ppc4xx_reset(); printf("ppc4xx_reset() failed!\n"); #ifdef DDB while(1) Debugger(); #else while (1) /* nothing */; #endif }
/* * Halt or reboot the machine after syncing/dumping according to howto. */ void cpu_reboot(int howto, char *what) { static int syncing; static char str[256]; char *ap = str, *ap1 = ap; /* * Enable external interrupts in case someone is rebooting * from a strange context via ddb. */ mtmsr(mfmsr() | PSL_EE); boothowto = howto; if (!cold && !(howto & RB_NOSYNC) && !syncing) { syncing = 1; vfs_shutdown(); /* sync */ resettodr(); /* set wall clock */ } #ifdef MULTIPROCESSOR /* Halt other CPU */ ppc_send_ipi(IPI_T_NOTME, PPC_IPI_HALT); delay(100000); /* XXX */ #endif splhigh(); if (!cold && (howto & RB_DUMP)) dumpsys(); doshutdownhooks(); if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { delay(1000000); #if NCUDA > 0 cuda_poweroff(); #endif #if NPMU > 0 pmu_poweroff(); #endif #if NADB > 0 adb_poweroff(); printf("WARNING: powerdown failed!\n"); #endif } if (howto & RB_HALT) { printf("halted\n\n"); /* flush cache for msgbuf */ __syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE)); ppc_exit(); } printf("rebooting\n\n"); if (what && *what) { if (strlen(what) > sizeof str - 5) printf("boot string too large, ignored\n"); else { strcpy(str, what); ap1 = ap = str + strlen(str); *ap++ = ' '; } } *ap++ = '-'; if (howto & RB_SINGLE) *ap++ = 's'; if (howto & RB_KDB) *ap++ = 'd'; *ap++ = 0; if (ap[-2] == '-') *ap1 = 0; /* flush cache for msgbuf */ __syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE)); #if NCUDA > 0 cuda_restart(); #endif #if NPMU > 0 pmu_restart(); #endif #if NADB > 0 adb_restart(); /* not return */ #endif ppc_exit(); }
void aim_cpu_init(vm_offset_t toc) { size_t trap_offset, trapsize; vm_offset_t trap; register_t msr, scratch; uint8_t *cache_check; int cacheline_warn; #ifndef __powerpc64__ int ppc64; #endif trap_offset = 0; cacheline_warn = 0; /* Various very early CPU fix ups */ switch (mfpvr() >> 16) { /* * PowerPC 970 CPUs have a misfeature requested by Apple that * makes them pretend they have a 32-byte cacheline. Turn this * off before we measure the cacheline size. */ case IBM970: case IBM970FX: case IBM970MP: case IBM970GX: scratch = mfspr(SPR_HID5); scratch &= ~HID5_970_DCBZ_SIZE_HI; mtspr(SPR_HID5, scratch); break; #ifdef __powerpc64__ case IBMPOWER7: case IBMPOWER7PLUS: case IBMPOWER8: case IBMPOWER8E: /* XXX: get from ibm,slb-size in device tree */ n_slbs = 32; break; #endif } /* * Initialize the interrupt tables and figure out our cache line * size and whether or not we need the 64-bit bridge code. */ /* * Disable translation in case the vector area hasn't been * mapped (G5). Note that no OFW calls can be made until * translation is re-enabled. */ msr = mfmsr(); mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI); /* * Measure the cacheline size using dcbz * * Use EXC_PGM as a playground. We are about to overwrite it * anyway, we know it exists, and we know it is cache-aligned. */ cache_check = (void *)EXC_PGM; for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++) cache_check[cacheline_size] = 0xff; __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory"); /* Find the first byte dcbz did not zero to get the cache line size */ for (cacheline_size = 0; cacheline_size < 0x100 && cache_check[cacheline_size] == 0; cacheline_size++); /* Work around psim bug */ if (cacheline_size == 0) { cacheline_warn = 1; cacheline_size = 32; } #ifndef __powerpc64__ /* * Figure out whether we need to use the 64 bit PMAP. This works by * executing an instruction that is only legal on 64-bit PPC (mtmsrd), * and setting ppc64 = 0 if that causes a trap. */ ppc64 = 1; bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size); __syncicache((void *)EXC_PGM, (size_t)&testppc64size); __asm __volatile("\ mfmsr %0; \ mtsprg2 %1; \ \ mtmsrd %0; \ mfsprg2 %1;" : "=r"(scratch), "=r"(ppc64));