1708d4f09SSam Ravnborg /* 2708d4f09SSam Ravnborg * misc.c: Miscellaneous prom functions that don't belong 3708d4f09SSam Ravnborg * anywhere else. 4708d4f09SSam Ravnborg * 5708d4f09SSam Ravnborg * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 6708d4f09SSam Ravnborg */ 7708d4f09SSam Ravnborg 8708d4f09SSam Ravnborg #include <linux/types.h> 9708d4f09SSam Ravnborg #include <linux/kernel.h> 10708d4f09SSam Ravnborg #include <linux/sched.h> 116943f3daSSam Ravnborg #include <linux/module.h> 126943f3daSSam Ravnborg 13708d4f09SSam Ravnborg #include <asm/openprom.h> 14708d4f09SSam Ravnborg #include <asm/oplib.h> 15708d4f09SSam Ravnborg #include <asm/auxio.h> 16708d4f09SSam Ravnborg #include <asm/system.h> 17708d4f09SSam Ravnborg 18708d4f09SSam Ravnborg extern void restore_current(void); 19708d4f09SSam Ravnborg 20708d4f09SSam Ravnborg DEFINE_SPINLOCK(prom_lock); 21708d4f09SSam Ravnborg 22708d4f09SSam Ravnborg /* Reset and reboot the machine with the command 'bcommand'. */ 23708d4f09SSam Ravnborg void 24708d4f09SSam Ravnborg prom_reboot(char *bcommand) 25708d4f09SSam Ravnborg { 26708d4f09SSam Ravnborg unsigned long flags; 27708d4f09SSam Ravnborg spin_lock_irqsave(&prom_lock, flags); 28708d4f09SSam Ravnborg (*(romvec->pv_reboot))(bcommand); 29708d4f09SSam Ravnborg /* Never get here. */ 30708d4f09SSam Ravnborg restore_current(); 31708d4f09SSam Ravnborg spin_unlock_irqrestore(&prom_lock, flags); 32708d4f09SSam Ravnborg } 33708d4f09SSam Ravnborg 34708d4f09SSam Ravnborg /* Forth evaluate the expression contained in 'fstring'. */ 35708d4f09SSam Ravnborg void 36708d4f09SSam Ravnborg prom_feval(char *fstring) 37708d4f09SSam Ravnborg { 38708d4f09SSam Ravnborg unsigned long flags; 39708d4f09SSam Ravnborg if(!fstring || fstring[0] == 0) 40708d4f09SSam Ravnborg return; 41708d4f09SSam Ravnborg spin_lock_irqsave(&prom_lock, flags); 42708d4f09SSam Ravnborg if(prom_vers == PROM_V0) 43708d4f09SSam Ravnborg (*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring); 44708d4f09SSam Ravnborg else 45708d4f09SSam Ravnborg (*(romvec->pv_fortheval.v2_eval))(fstring); 46708d4f09SSam Ravnborg restore_current(); 47708d4f09SSam Ravnborg spin_unlock_irqrestore(&prom_lock, flags); 48708d4f09SSam Ravnborg } 496943f3daSSam Ravnborg EXPORT_SYMBOL(prom_feval); 50708d4f09SSam Ravnborg 51708d4f09SSam Ravnborg /* Drop into the prom, with the chance to continue with the 'go' 52708d4f09SSam Ravnborg * prom command. 53708d4f09SSam Ravnborg */ 54708d4f09SSam Ravnborg void 55708d4f09SSam Ravnborg prom_cmdline(void) 56708d4f09SSam Ravnborg { 57708d4f09SSam Ravnborg extern void install_obp_ticker(void); 58708d4f09SSam Ravnborg extern void install_linux_ticker(void); 59708d4f09SSam Ravnborg unsigned long flags; 60708d4f09SSam Ravnborg 61708d4f09SSam Ravnborg spin_lock_irqsave(&prom_lock, flags); 62708d4f09SSam Ravnborg install_obp_ticker(); 63708d4f09SSam Ravnborg (*(romvec->pv_abort))(); 64708d4f09SSam Ravnborg restore_current(); 65708d4f09SSam Ravnborg install_linux_ticker(); 66708d4f09SSam Ravnborg spin_unlock_irqrestore(&prom_lock, flags); 67708d4f09SSam Ravnborg set_auxio(AUXIO_LED, 0); 68708d4f09SSam Ravnborg } 69708d4f09SSam Ravnborg 70708d4f09SSam Ravnborg /* Drop into the prom, but completely terminate the program. 71708d4f09SSam Ravnborg * No chance of continuing. 72708d4f09SSam Ravnborg */ 735f66dd35SSam Ravnborg void __noreturn 74708d4f09SSam Ravnborg prom_halt(void) 75708d4f09SSam Ravnborg { 76708d4f09SSam Ravnborg unsigned long flags; 77708d4f09SSam Ravnborg again: 78708d4f09SSam Ravnborg spin_lock_irqsave(&prom_lock, flags); 79708d4f09SSam Ravnborg (*(romvec->pv_halt))(); 80708d4f09SSam Ravnborg /* Never get here. */ 81708d4f09SSam Ravnborg restore_current(); 82708d4f09SSam Ravnborg spin_unlock_irqrestore(&prom_lock, flags); 83708d4f09SSam Ravnborg goto again; /* PROM is out to get me -DaveM */ 84708d4f09SSam Ravnborg } 85708d4f09SSam Ravnborg 86708d4f09SSam Ravnborg typedef void (*sfunc_t)(void); 87708d4f09SSam Ravnborg 88708d4f09SSam Ravnborg /* Set prom sync handler to call function 'funcp'. */ 89708d4f09SSam Ravnborg void 90708d4f09SSam Ravnborg prom_setsync(sfunc_t funcp) 91708d4f09SSam Ravnborg { 92708d4f09SSam Ravnborg if(!funcp) return; 93708d4f09SSam Ravnborg *romvec->pv_synchook = funcp; 94708d4f09SSam Ravnborg } 95708d4f09SSam Ravnborg 96708d4f09SSam Ravnborg /* Get the idprom and stuff it into buffer 'idbuf'. Returns the 97708d4f09SSam Ravnborg * format type. 'num_bytes' is the number of bytes that your idbuf 98708d4f09SSam Ravnborg * has space for. Returns 0xff on error. 99708d4f09SSam Ravnborg */ 100708d4f09SSam Ravnborg unsigned char 101708d4f09SSam Ravnborg prom_get_idprom(char *idbuf, int num_bytes) 102708d4f09SSam Ravnborg { 103708d4f09SSam Ravnborg int len; 104708d4f09SSam Ravnborg 105708d4f09SSam Ravnborg len = prom_getproplen(prom_root_node, "idprom"); 106708d4f09SSam Ravnborg if((len>num_bytes) || (len==-1)) return 0xff; 107708d4f09SSam Ravnborg if(!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes)) 108708d4f09SSam Ravnborg return idbuf[0]; 109708d4f09SSam Ravnborg 110708d4f09SSam Ravnborg return 0xff; 111708d4f09SSam Ravnborg } 112708d4f09SSam Ravnborg 113708d4f09SSam Ravnborg /* Get the major prom version number. */ 114708d4f09SSam Ravnborg int 115708d4f09SSam Ravnborg prom_version(void) 116708d4f09SSam Ravnborg { 117708d4f09SSam Ravnborg return romvec->pv_romvers; 118708d4f09SSam Ravnborg } 119708d4f09SSam Ravnborg 120708d4f09SSam Ravnborg /* Get the prom plugin-revision. */ 121708d4f09SSam Ravnborg int 122708d4f09SSam Ravnborg prom_getrev(void) 123708d4f09SSam Ravnborg { 124708d4f09SSam Ravnborg return prom_rev; 125708d4f09SSam Ravnborg } 126708d4f09SSam Ravnborg 127708d4f09SSam Ravnborg /* Get the prom firmware print revision. */ 128708d4f09SSam Ravnborg int 129708d4f09SSam Ravnborg prom_getprev(void) 130708d4f09SSam Ravnborg { 131708d4f09SSam Ravnborg return prom_prev; 132708d4f09SSam Ravnborg } 133