/************************************************************************** * * * Copyright (C) 1992-1996 Silicon Graphics, Inc. * * * * These coded instructions, statements, and computer programs contain * * unpublished proprietary information of Silicon Graphics, Inc., and * * are protected by Federal copyright law. They may not be disclosed * * to third parties or copied or duplicated in any form, in whole or * * in part, without the prior written consent of Silicon Graphics, Inc. * * * **************************************************************************/ /***********************************************************************\ * File: sysinit.c * * * * Contains the code which completes system startup, runs * * standard diags, checks the system configuration state, * * and finally calls main. * * * \***********************************************************************/ #ident "$Revision: 1.108 $" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "io6prom_private.h" #include #include #include #include #include #include /* For slave launch testing */ #include "ip27prom.h" extern ulong get_BSR(void) ; extern int bssmagic ; #include #include #include #include #include "traverse_nodes.h" void main(void); void init_prom_soft(int); void reboot(void); void config_cache(void); void init_tlb(void); int version(void); extern void dump_diag_results(int); extern void check_early_init(void); extern void checkclk_mod_all(void) ; extern void check_edtab(void) ; extern void nvram_disabled_io_info_update(void); void dump_inventory(void) ; static void alloc_memdesc(void); static void show_halt_msg(void); static nasid_t update_master_baseio(void) ; int update_old_master_baseio(nasid_t) ; __psunsigned_t io6prom_elsc_init(void) ; int read_skipauto(void) ; void check_part_reboot(void) ; extern void ei_pwr_cycle_launch(void); #ifdef SABLE extern int fake_prom; extern int sc_sable; extern int sk_sable; #endif /* SABLE */ extern __psint_t _gp; extern int num_nodes; extern void tlb_setup(nasid_t); void nvaddr_init(void) ; extern void slave_print_mod_num(nasid_t); #if 0 extern int propagate_serial_num() ; #endif void elsc_print_mod_num(int); __psunsigned_t getnv_base_lb(lboard_t *) ; extern __psunsigned_t nvram_base ; __psunsigned_t ioc3uart_base ; nasid_t master_nasid; nasid_t master_baseio_nasid; extern moduleid_t master_baseio_modid ; extern slotid_t master_baseio_slotid ; extern char *master_console_path ; extern unsigned char prom_versnum,prom_revnum; long Stack[IO6PROM_STACK_SIZE / sizeof(long)] = {0}; __uint64_t diag_malloc_brk ; /* * Set master control flags in the prom. */ void sysinit(int diag_mode) { int restart; char restart_ll ; int node, slice; int i; kl_config_hdr_t *klch_m, *klch_b ; #ifdef SABLE hubuart_init(); /* Assembly version */ sc_sable = 1; sk_sable = 1; #endif /* If we get here, we have been successfully loaded. print the rest of the Loading ... msg */ printf("DONE\n\n") ; /* Display the IO6PROM sign on message */ (void) version(); master_nasid = get_nasid(); diag_set_mode(diag_mode); #if defined (HUB_ERR_STS_WAR) if (do_hub_errsts_war() == 0) printf("Force read error for HUB_ERR_STS_WAR failed\n"); #endif /* set up GDA on master_nasid */ init_local_dir(); io6prom_elsc_init() ; /* Choose one of the local master io6 as global master */ /* change the KLCONFIG HEADER of the master_nasid so that its console_t points to the global master baseio. Any onw who needs the console uart base can get it from here. */ if ((master_baseio_nasid = update_master_baseio()) >= 0) { klch_m = KL_CONFIG_HDR(master_nasid) ; klch_b = KL_CONFIG_HDR(master_baseio_nasid) ; bcopy((void *)&klch_b->ch_cons_info, (void *)&klch_m->ch_cons_info, sizeof(console_t)) ; } else { /* For compatibility with old proms. Old proms do not have the GLOBAL_MASTER_IO6 and LOCAL_MASTER_IO6 bits set. Set it for atleast the master_nasid. */ update_old_master_baseio(master_nasid) ; } nvaddr_init() ; /* * PV 669589. If memory banks 0 and 1 are swapped, the correct * behavior is for the prom to also swap all other pairs of banks. * New versions of the proms know how to do this. The IO prom must be * forwards and backwards compatible with all versions of the CPU * prom, but we don't know whether the CPU prom which loaded this IO * prom had the old or new behavior. If the CPU prom had the new * behavior, it "unswapped" the banks before loading the IO prom, * thereby re-creating the old behavior. Old CPU proms have the old * behavior (obviously). Here, we make the behavior correct by * swapping the config information for banks 2 and up. */ swap_some_memory_banks(); /* Initialize the globals pertaining to cache size */ /* Finds out values of dmabuf_linemask, _icache_linemask _dcache_linemask based on the cache in Global Master. */ config_cache(); verbose_faults = 1; set_SR(IO6PROM_SR & ~(SR_IE)); init_env(); #if defined (HUB_ERR_STS_WAR) if (do_hub_errsts_war() == 0) printf("Force read error for HUB_ERR_STS_WAR failed\n"); #endif nvram_prom_version_set(prom_versnum,prom_revnum); /* * These need to be set to get stdio and certain prom initialization * to behave correctly. */ _prom = 1; stdio_init = 0; init_prom_soft(1); #if defined (HUB_ERR_STS_WAR) if (do_hub_errsts_war() == 0) printf("Force read error for HUB_ERR_STS_WAR failed\n"); #endif /* Run the checkclk test on all modules */ if ((GET_DIAG_MODE(diag_mode) == DIAG_MODE_HEAVY) || (GET_DIAG_MODE(diag_mode) == DIAG_MODE_MFG)) checkclk_mod_all() ; /* Dump system config info and diag results */ dump_diag_results(diag_mode); /* Do the right thing depending on how the RESTART stuff is set */ /* * Bug PV 464448 * init_prom_soft above may not return if there was a * scsi time out, and the war code reset the system. * We may lose the restart info in such a case. The fix * involves storing the reboot state also in nvram. * Read that location and if it appears that we have a * valid value there, use it as the restart value and * reset the nvram. This same mechanism can be used to * remember additional state. upto 5 bits. */ restart_ll = get_scsi_to_ll_value() ; if ((restart_ll & (SCSI_TO_LL_MAGIC | SCSI_TO_LL_REBOOT)) == (SCSI_TO_LL_MAGIC | SCSI_TO_LL_REBOOT)) { restart = PROMOP_REBOOT ; set_scsi_to_ll_value(0); } else restart = diag_get_lladdr(); diag_set_lladdr(PROMOP_INVALID); #if defined (HUB_ERR_STS_WAR) if (do_hub_errsts_war() == 0) printf("Force read error for HUB_ERR_STS_WAR failed\n"); #endif #ifdef DEBUG printf("printing module numbers...\n"); #endif /* Loop through all the nodes and launch the module printing code on one of its processors. This prints each module's number twice but makes the code simpler. */ for (node = 1; node < num_nodes; node++) { for (slice = 0; slice < CPUS_PER_NODE; slice++) { klcpu_t *klcpu; cpuid_t cid = cnode_slice_to_cpuid(node, slice); if (cid != -1) klcpu = get_cpuinfo(cid); else klcpu = NULL; /* if it's there and it's enabled have it print its module number */ if (klcpu && KLCONFIG_INFO_ENABLED(&(klcpu->cpu_info))) { #if DEBUG printf("printing module number on node %d, cpu %d\n", node,slice); #endif LAUNCH_SLAVE(GDA->g_nasidtable[node],slice, (launch_proc_t)PHYS_TO_K0(kvtophys( (void *)slave_print_mod_num)), get_nasid(), (void*)TO_NODE(GDA->g_nasidtable[node],IP27PROM_STACK_A + 1024), (void*)0); break; } } /* for */ } /* for */ /* print this module's number on the ELSC */ us_delay(40000); elsc_print_mod_num(1); /* RFE PV # 445985 */ /* If the skip autoboot virtual dip switch is set and we were about to do a startup() dont do it. Take a shortcut and go to EnterInteractiveMode right here. */ if (read_skipauto() && (restart != PROMOP_RESTART) && (restart != PROMOP_REBOOT)) restart = PROMOP_RESTART ; /* check if this is a reboot controlled by another partition. */ check_part_reboot() ; switch (restart) { case PROMOP_RESTART: EnterInteractiveMode(); break; case PROMOP_REBOOT: reboot(); break; default: startup(); break; } } /* * Function: slave_set_moduleid -> executed on slave CPU to set * moduleid * Args: module -> module to set to * Returns: Nothing */ void slave_set_moduleid(int module) { io6prom_elsc_init() ; elsc_module_set(get_elsc(), module); } static void make_mod_msg(char *mmsg, moduleid_t mnum, int partition, int master) { #ifdef OLD_CODE int m10, m100 ; strcpy(mmsg, "Mod ") ; m10 = (mnum/10) ; m100 = (mnum/100) ; mmsg[4] = (m100) ? (m100 + '0') : ' ' ; mmsg[5] = (m10%10) ? (m10%10) + '0' : ' ' ; mmsg[6] = (mnum%10) + '0' ; mmsg[7] = master ? 'C' : ' ' ; mmsg[8] = 0 ; #endif /* * Right now we only check partition id's for validity */ if(partition >=0 && partition <= 63){ if(master) sprintf(mmsg, "P%2d M%2dC", partition, mnum); else sprintf(mmsg, "P%2d M%2d", partition, mnum); } else { if(master) sprintf(mmsg, " M%2dC", mnum); else sprintf(mmsg, " M%2d ", mnum); } } /* * elsc_print_mod_num_ * sets up the ELSC and then prints the module number on its LEDs */ void elsc_print_mod_num(int master) { lboard_t *board; char mod_msg[48]; if (SN00) return; io6prom_elsc_init() ; board = find_lboard((lboard_t*)KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27); /* convert to a 3 digit number. */ make_mod_msg(mod_msg, board->brd_module, elsc_partition_get(get_elsc()), master); elsc_display_mesg(get_elsc(), mod_msg); /* we can't use printf so no error message if it fails :( */ } /* * get all slave nvram bases into nslvnv_base */ int get_slvnv_base(lboard_t *l, void *ap, void *rp) { __psunsigned_t *slvp = (__psunsigned_t *)rp ; int *nslv_p = (int *)ap ; if (l->brd_type != KLTYPE_BASEIO) return 1 ; if (l->brd_flags & GLOBAL_MASTER_IO6) return 1 ; if (slvp[*nslv_p] = getnv_base_lb(l)) { (*nslv_p) += 1 ; } return 1 ; } /* * init_prom_soft() * Calls the initialization routines for the major * PROM subsystems. */ void init_prom_soft(int no_init_env) { #if DEBUG /* Check for the value of stack on re-entry */ int dummy ; printf("Stack = 0x%lx, SP = 0x%lx\n", Stack, &dummy) ; #endif master_nasid = get_nasid(); if (!no_init_env) update_master_baseio() ; nvaddr_init() ; io6prom_elsc_init() ; /* Init diag malloc area every time we re-enter the IO6prom */ diag_malloc_brk = DIAG_BASE ; init_klmalloc_device(master_nasid) ; #if DEBUG dump_klmalloc_table(master_nasid) ; #endif sysctlr_message("InitCach"); config_cache(); flush_cache(); set_SR(IO6PROM_SR & ~(SR_IE)); /* Set SR to its "normal" state */ check_edtab(); nvram_disabled_io_info_update(); if (!no_init_env) init_env(); sysctlr_message("InitSaio"); _init_saio(); /* Just for testing since this runs with the 'init' command and can be run any number of times without reboot. */ read_extra_nic() ; /*do_dis_node_brds() ;*/ check_inventory() ; elsc_print_mod_num(1); #ifdef DEBUG dump_inventory() ; #endif #if 0 propagate_serial_num() ; #endif init_tlb(); alloc_memdesc(); } /* * show_halt_msg() * Display a nice friendly halt message for the user */ static void show_halt_msg(void) { if (doGui()) setGuiMode(1,GUI_NOLOGO); popupDialog("\n\nOkay to power off the system now.\n\n" "Press RESET button to restart.", 0,DIALOGINFO,DIALOGCENTER|DIALOGBIGFONT); } /* * halt() * Bring the system to a quiescent state */ void halt() { show_halt_msg(); } /* * powerdown() * Attempt a soft power down of the system. */ void powerdown(void) { cpu_soft_powerdown(); show_halt_msg(); } /* * restart() * Attempt to restart the machine. */ void restart(void) { static int restart_buttons[] = {DIALOGRESTART,-1}; if (doGui()) setGuiMode(1,GUI_NOLOGO); popupDialog("\n\nYou may shutdown the system.\n\nPress any key to restart.", restart_buttons, DIALOGINFO, DIALOGCENTER|DIALOGBIGFONT); if (doGui()) setGuiMode(0, GUI_RESET); startup(); } /* * reboot() * This is supposed to try to reproduce the last system boot * command. */ void reboot(void) { int Verbose = 0; /* ??? */ if (!Verbose && doGui()) { setGuiMode(1,0); } else { p_panelmode(); p_cursoff(); } if (ESUCCESS != autoboot(0, 0, 0)) { putchar('\n'); setTpButtonAction(EnterInteractiveMode,TPBCONTINUE,WBNOW); p_curson(); p_printf("Unable to boot; press any key to continue: "); getchar(); putchar('\n'); } /* If reboot fails, reinitialize software in case a partially * booted program has messed up the prom state. */ EnterInteractiveMode(); /* should not get here */ } /* * Update the IOC3 flags for the master console. * These are needed so that drivers can be installed * further down in the IO prom. */ nasid_t update_master_baseio(void) { cnodeid_t cnode ; nasid_t nasid ; lboard_t *lb; gda_t *gdap; klioc3_t *ioc3p ; gdap = (gda_t *)GDA_ADDR(get_nasid()); if (gdap->g_magic != GDA_MAGIC) { printf("update_master_io6: Invalid GDA MAGIC\n") ; return -1 ; } /* for all nodes */ for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) { nasid = gdap->g_nasidtable[cnode]; if (nasid == INVALID_NASID) continue; lb = (lboard_t *)KL_CONFIG_INFO(nasid) ; /* find all baseio boards */ while (lb) { lb = find_lboard(lb, KLTYPE_BASEIO); if (!lb) break ; /* the first local master is the global master */ if (lb->brd_flags & LOCAL_MASTER_IO6) { lb->brd_flags |= GLOBAL_MASTER_IO6 ; master_baseio_modid = lb->brd_module ; master_baseio_slotid = lb->brd_slot ; ioc3p = NULL ; ioc3p = (klioc3_t *)find_component(lb, (klinfo_t *)ioc3p, KLSTRUCT_IOC3) ; /* Install all drivers for this IOC3 */ ioc3p->ioc3_info.flags |= KLINFO_INSTALL ; ioc3p->ioc3_superio.flags |= KLINFO_INSTALL ; ioc3p->ioc3_enet.flags |= KLINFO_INSTALL ; return lb->brd_nasid ; } lb = KLCF_NEXT(lb); } } /* did not find any local master in the whole system */ return -1 ; } /* * enter_imode() * Drop back into Interactive Mode. */ void enter_imode(void) { _hook_exceptions(); _init_saio(); /* initialize saio library */ alloc_memdesc(); /* allocate memory descriptors for prom */ set_SR(IO6PROM_SR & ~(SR_IE)); main(); EnterInteractiveMode(); /* shouldn't get here */ } /* * alloc_memdesc() * Allocate memory descriptors. */ static void alloc_memdesc(void) { } /* * Set up some data structs for compatiblity with old * proms */ update_old_master_baseio(nasid_t nasid) { lboard_t *lboard; lboard = (lboard_t *)KL_CONFIG_INFO(nasid); if ((lboard = find_lboard(lboard, KLTYPE_BASEIO)) == NULL) { printf("CPU and IO proms highly incompatible.\ Update CPU and IO proms to the same rev level.\n") ; return 0 ; } lboard->brd_flags |= (LOCAL_MASTER_IO6|GLOBAL_MASTER_IO6) ; return 1 ; } void dump_diag_results(int diag_mode) { sn0_dump_diag(diag_mode); #if IP27_CPU_EARLY_INIT_WAR check_early_init(); #endif } /* * Scan all io boards and collect their base addrs. */ void nvaddr_init() { int i ; extern __psunsigned_t slvnv_base[] ; extern int nslv_nvram ; extern __uint64_t mstnv_state ; nslv_nvram = mstnv_state = 0 ; for (i=0;ibrd_module == lb->brd_module) return; pwr_cyc[pwr_cyc_indx] = lb; pwr_cyc_indx++; } int search_early_init(lboard_t *lb, void *arg, void *result) { klcpu_t *cpuinfo; if (lb->brd_type != KLTYPE_IP27) return 1; cpuinfo = (klcpu_t *) find_component(lb, NULL, KLSTRUCT_CPU); if (cpuinfo && !(cpuinfo->cpu_info.flags & KLINFO_ENABLE) && (cpuinfo->cpu_info.diagval == KLDIAG_EARLYINIT_FAILED)) { add_pwr_cyc(lb); return 1; } cpuinfo = (klcpu_t *) find_component(lb, (klinfo_t *) cpuinfo, KLSTRUCT_CPU); if (cpuinfo && !(cpuinfo->cpu_info.flags & KLINFO_ENABLE) && (cpuinfo->cpu_info.diagval == KLDIAG_EARLYINIT_FAILED)) add_pwr_cyc(lb); return 1; } void ei_pwr_cycle_module(void) { io6prom_elsc_init(); us_delay(200000); elsc_power_cycle(get_elsc()); } static int ei_pwr_cycle(lboard_t *lb) { lboard_t *mod_brds[NODESLOTS_PER_MODULE]; int i; if (module_brds(lb->brd_nasid, mod_brds, NODESLOTS_PER_MODULE) < 0) return -1; for (i = 0; i < NODESLOTS_PER_MODULE; i++) if (mod_brds[i]) { klcpu_t *cpuinfo; cpuinfo = (klcpu_t *) find_component(mod_brds[i], NULL, KLSTRUCT_CPU); if (cpuinfo && (cpuinfo->cpu_info.flags & KLINFO_ENABLE)) { LAUNCH_SLAVE(mod_brds[i]->brd_nasid, cpuinfo->cpu_info.physid, (launch_proc_t) PHYS_TO_K0(kvtophys((void *) ei_pwr_cycle_launch)), get_nasid(), (void *) TO_NODE(mod_brds[i]->brd_nasid, IP27PROM_STACK_A + 1024), 0); return 0; } cpuinfo = (klcpu_t *) find_component(mod_brds[i], (klinfo_t *) cpuinfo, KLSTRUCT_CPU); if (cpuinfo && (cpuinfo->cpu_info.flags & KLINFO_ENABLE)) { LAUNCH_SLAVE(mod_brds[i]->brd_nasid, cpuinfo->cpu_info.physid, (launch_proc_t) PHYS_TO_K0(kvtophys((void *) ei_pwr_cycle_launch)), get_nasid(), (void *) TO_NODE(mod_brds[i]->brd_nasid, IP27PROM_STACK_A + 1024), 0); return 0; } } return -1; } #define EARLY_INIT_MAX_CNT 3 void check_early_init(void) { int i, self = 0; moduleid_t module; char ea_cnt; if (SN00) { char buf[4]; ip27log_getenv(get_nasid(), IP27LOG_MODULE_KEY, buf, "1", 0); module = atoi(buf); } else module = elsc_module_get(get_elsc()); visit_lboard(search_early_init, NULL, NULL); if (!pwr_cyc_indx) { set_nvreg(NVOFF_EA_CNT, 0); update_checksum(); return; } else if ((ea_cnt = get_nvreg(NVOFF_EA_CNT)) >= EARLY_INIT_MAX_CNT) { printf("\nWARNING: Some CPUs failed during early init. Failed" " to start up CPUs\n"); return; } set_nvreg(NVOFF_EA_CNT, ea_cnt + 1); update_checksum(); printf("\nWARNING: Some CPUs failed during early init. Power cycling " "affected modules (Try %d of %d)\n", ea_cnt + 1, EARLY_INIT_MAX_CNT); for (i = 0; i < pwr_cyc_indx; i++) if (pwr_cyc[i]->brd_module == module) self = 1; else if (ei_pwr_cycle(pwr_cyc[i]) < 0) printf("WARNING: /hw/module/%d/slot/n%d/cpu: Failed " "early init. Please power cycle manually\n", pwr_cyc[i]->brd_module, SLOTNUM_GETSLOT(pwr_cyc[i]->brd_slot)); if (self) { us_delay(200000); elsc_power_cycle(get_elsc()); } } #endif #define SAVE_CLEAR_FENCE 1 #define RESTORE_FENCE 2 #define PART_REBOOT_WAIT 180 struct save_fence_s { __uint64_t vector ; sn0drv_fence_t fence ; } *sf ; static int sfcnt ; void do_rou_reg(klrou_t *klr, struct save_fence_s *sfp, int flag) { __uint64_t value ; int port ; int err ; sfp->vector = klr->rou_vector ; if (flag == SAVE_CLEAR_FENCE) { err = vector_read_node(sfp->vector, get_nasid(), 0, RR_PROT_CONF, &value); if (err<0) return ; sfp->fence.local_blk.reg = value ; err = vector_write_node(sfp->vector, get_nasid(), 0, RR_PROT_CONF, value|0x3f); if (err != NET_ERROR_NONE) return ; } ForEachRouterPort(port) { if (klr->rou_port[port].port_nasid == INVALID_NASID) continue ; if (flag == SAVE_CLEAR_FENCE) { err = vector_read_node(sfp->vector, get_nasid(), 0, RR_RESET_MASK(port), &value); if (err<0) continue ; sfp->fence.ports[port-1].reg = value ; err = vector_write_node(sfp->vector, get_nasid(), 0, RR_RESET_MASK(port), value|0x3f); if (err != NET_ERROR_NONE) return ; } } } int vlb_do_router_fences(lboard_t *lb, void *ap, void *rp) { klrou_t *klr ; lboard_t *myip27 ; /* Do nothing with META ROUTERS XXX */ if (KLCLASS(lb->brd_type) == KLCLASS_ROUTER) { #ifdef LONG_POLE_128P /* This is one of the alternatives to read and store * the status of the meta router port fences. It works * OK, but under certain h/w configs the system freezes * if we type unix at the io6prom prompt. To be investigated. */ if (lb->brd_type == KLTYPE_META_ROUTER) { printf("M.R = %llx\n", lb->brd_nic) ; if (myip27 = find_lboard((lboard_t *) KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27)) { net_vec_t vec ; vec = klcfg_discover_route(myip27, lb, 0) ; if (vec != NET_VEC_BAD) printf("M.R. vec = %llx\n", vec) ; else printf("M.R. bad vec\n") ; } } #endif /* LONG_POLE_128P */ if ((klr = (klrou_t *)find_first_component(lb, KLSTRUCT_ROU))){ do_rou_reg(klr, &sf[sfcnt++], *(int *)ap) ; } } return 1 ; } void do_router_fences(int flag) { int i, err, port ; int num_rou = num_nodes/2 + num_nodes ; /* normal routers + meta routers */ if (flag == SAVE_CLEAR_FENCE) { sf = (struct save_fence_s *) malloc( sizeof(struct save_fence_s) * num_rou) ; if (sf == NULL) return ; visit_lboard(vlb_do_router_fences, (void *)&flag, NULL) ; return ; } #ifdef DEBUG printf("No of vectors restored = %d\n", sfcnt) ; #endif if (flag == RESTORE_FENCE) { for (i=0; ipointer ; klp->klp_state = KLP_STATE_PROM ; /* Do we have to do it */ part_reboot = get_nvreg(NVOFF_RESTART) ; #ifdef LONG_POLE_128P /* * During debug, we may want to optionally do this stuff. */ */ printf("Part reboot stuff? ") ; if ((c = getchar()) == 'y') part_reboot = 0xe ; #endif if (part_reboot == 0xe) { /* We have seen this once. Clear it. */ set_nvreg(NVOFF_RESTART, 0) ; update_checksum(); /* Clear all our fences so that another part may reset us. */ do_router_fences(SAVE_CLEAR_FENCE) ; /* Wait for secs */ printf("Waiting %d secs for reset from remote partition.\n", cnt) ; printf("If this seems to be wrong, Please hit ctrl-C to " "go back to ioprom prompt.\n") ; Signal (SIGINT, part_reboot_intr); while (cnt--) { printf(". ") ; #if 0 /* Failed attempt at doing async io in prom. */ if (gets(buf) && (*buf == CTRL('c'))) break ; ttycnt = 0 ; Read(0, buf, 1, &ttycnt) ; if (ttycnt == 1) { printf("%x\n", *buf) ; if (*buf == CTRL('c')) break ; } #endif if (setjmp(part_reboot_buf)) break ; us_delay(1000000L) ; } printf("\n") ; /* If we reach here, no one reset us. Put back the fences and go to prom menu. XXX */ printf("Timed out waiting for remote partition reboot.\n") ; printf("If this shutdown was due to mkpart command you will\n" "need to reset the system manually when the other\n" "partitions are reset.\n") ; do_router_fences(RESTORE_FENCE) ; } }