1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * console.c: Routines that deal with sending and receiving IO 4 * to/from the current console device using the PROM. 5 * 6 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 7 */ 8 9 #include <linux/types.h> 10 #include <linux/kernel.h> 11 #include <linux/sched.h> 12 #include <asm/openprom.h> 13 #include <asm/oplib.h> 14 #include <linux/string.h> 15 16 /* Non blocking get character from console input device, returns -1 17 * if no input was taken. This can be used for polling. 18 */ 19 int 20 prom_nbgetchar(void) 21 { 22 int i = -1; 23 unsigned long flags; 24 25 local_irq_save(flags); 26 i = (*(romvec->pv_nbgetchar))(); 27 local_irq_restore(flags); 28 return i; /* Ugh, we could spin forever on unsupported proms ;( */ 29 } 30 31 /* Non blocking put character to console device, returns -1 if 32 * unsuccessful. 33 */ 34 int 35 prom_nbputchar(char c) 36 { 37 unsigned long flags; 38 int i = -1; 39 40 local_irq_save(flags); 41 i = (*(romvec->pv_nbputchar))(c); 42 local_irq_restore(flags); 43 return i; /* Ugh, we could spin forever on unsupported proms ;( */ 44 } 45 46 /* Blocking version of get character routine above. */ 47 char 48 prom_getchar(void) 49 { 50 int character; 51 while((character = prom_nbgetchar()) == -1) ; 52 return (char) character; 53 } 54 55 /* Blocking version of put character routine above. */ 56 void 57 prom_putchar(char c) 58 { 59 while(prom_nbputchar(c) == -1) ; 60 return; 61 } 62 63 /* Query for input device type */ 64 #if 0 65 enum prom_input_device 66 prom_query_input_device() 67 { 68 unsigned long flags; 69 int st_p; 70 char propb[64]; 71 char *p; 72 73 switch(prom_vers) { 74 case PROM_V0: 75 case PROM_V2: 76 default: 77 switch(*romvec->pv_stdin) { 78 case PROMDEV_KBD: return PROMDEV_IKBD; 79 case PROMDEV_TTYA: return PROMDEV_ITTYA; 80 case PROMDEV_TTYB: return PROMDEV_ITTYB; 81 default: 82 return PROMDEV_I_UNK; 83 }; 84 case PROM_V3: 85 case PROM_P1275: 86 local_irq_save(flags); 87 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin); 88 __asm__ __volatile__("ld [%0], %%g6\n\t" : : 89 "r" (¤t_set[smp_processor_id()]) : 90 "memory"); 91 local_irq_restore(flags); 92 if(prom_node_has_property(st_p, "keyboard")) 93 return PROMDEV_IKBD; 94 prom_getproperty(st_p, "device_type", propb, sizeof(propb)); 95 if(strncmp(propb, "serial", sizeof("serial"))) 96 return PROMDEV_I_UNK; 97 prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb)); 98 p = propb; 99 while(*p) p++; p -= 2; 100 if(p[0] == ':') { 101 if(p[1] == 'a') 102 return PROMDEV_ITTYA; 103 else if(p[1] == 'b') 104 return PROMDEV_ITTYB; 105 } 106 return PROMDEV_I_UNK; 107 }; 108 } 109 #endif 110 111 /* Query for output device type */ 112 113 #if 0 114 enum prom_output_device 115 prom_query_output_device() 116 { 117 unsigned long flags; 118 int st_p; 119 char propb[64]; 120 char *p; 121 int propl; 122 123 switch(prom_vers) { 124 case PROM_V0: 125 switch(*romvec->pv_stdin) { 126 case PROMDEV_SCREEN: return PROMDEV_OSCREEN; 127 case PROMDEV_TTYA: return PROMDEV_OTTYA; 128 case PROMDEV_TTYB: return PROMDEV_OTTYB; 129 }; 130 break; 131 case PROM_V2: 132 case PROM_V3: 133 case PROM_P1275: 134 local_irq_save(flags); 135 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout); 136 __asm__ __volatile__("ld [%0], %%g6\n\t" : : 137 "r" (¤t_set[smp_processor_id()]) : 138 "memory"); 139 local_irq_restore(flags); 140 propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); 141 if (propl >= 0 && propl == sizeof("display") && 142 strncmp("display", propb, sizeof("display")) == 0) 143 { 144 return PROMDEV_OSCREEN; 145 } 146 if(prom_vers == PROM_V3) { 147 if(strncmp("serial", propb, sizeof("serial"))) 148 return PROMDEV_O_UNK; 149 prom_getproperty(prom_root_node, "stdout-path", propb, sizeof(propb)); 150 p = propb; 151 while(*p) p++; p -= 2; 152 if(p[0]==':') { 153 if(p[1] == 'a') 154 return PROMDEV_OTTYA; 155 else if(p[1] == 'b') 156 return PROMDEV_OTTYB; 157 } 158 return PROMDEV_O_UNK; 159 } else { 160 /* This works on SS-2 (an early OpenFirmware) still. */ 161 switch(*romvec->pv_stdin) { 162 case PROMDEV_TTYA: return PROMDEV_OTTYA; 163 case PROMDEV_TTYB: return PROMDEV_OTTYB; 164 }; 165 } 166 break; 167 }; 168 return PROMDEV_O_UNK; 169 } 170 #endif 171