/* Console handling Copyright (C) 1996 Pete A. Zaitcev 1996 Jakub Jelinek This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "silo.h" #define SUN4_PROM_MAGIC 0x10010407 #define SUN4__PROM_VECTOR 0xFFE81000 #define SUN4__PRINTF 0x84 /* offset into a PROM vector */ typedef void (*Print) (const char *); typedef int (*Write) (int, const char *, int); /* Console class */ typedef struct console { /* Underscores at the end of class member are cool. */ /* The idea belongs to Paul Calder. --P3 */ unsigned magic_; /* For crash analisys */ Print print_; Write write_; int (*read1_) (); int fd0_; /* Read file descriptor */ int fd1_; /* Write file descriptor */ const struct linux_romvec *promvec_; } Console; static Console cons0; static int dpread1_v0 () { return cons0.promvec_->pv_getchar (); } static int dpread1_v3 () { static char c0; int rc; for (;;) { rc = cons0.promvec_->pv_v2devops.v2_dev_read (cons0.fd0_, &c0, 1); if (rc == -1) return -1; if (rc == 1) return c0 & 0xFF; } } void dpset (const struct linux_romvec *promvec) { cons0.magic_ = 0; cons0.print_ = 0; cons0.write_ = 0; cons0.read1_ = 0; cons0.fd0_ = 0; cons0.fd1_ = 0; cons0.promvec_ = promvec; if ((((unsigned) promvec) & 0xF0000000) == 0) { /* sun4, no PROM vector passed */ promvec = (struct linux_romvec *) SUN4__PROM_VECTOR; cons0.print_ = (Print) promvec->pv_printf; cons0.read1_ = dpread1_v0; } else if (promvec->pv_romvers == 3) { cons0.magic_ = promvec->pv_magic_cookie; cons0.write_ = (Write) promvec->pv_v2devops.v2_dev_write; cons0.read1_ = dpread1_v3; cons0.fd0_ = *promvec->pv_v2bootargs.fd_stdin; cons0.fd1_ = *promvec->pv_v2bootargs.fd_stdout; } else { /* Version 2 or 0. Who ever seen V.1? --P3 */ cons0.magic_ = promvec->pv_magic_cookie; cons0.print_ = (Print) promvec->pv_printf; cons0.read1_ = dpread1_v0; } } void dpout (register const char *data, int leng) { if (leng <= 0) return; if (cons0.write_ != 0) { (*cons0.write_) (cons0.fd1_, data, leng); } else { (*cons0.print_) (data); } return; } char dpin () { return cons0.read1_ (); } int nbgetchar (struct linux_romvec *promvec) { static char inc; if (promvec->pv_romvers < 2) return (*(promvec->pv_nbgetchar)) (); else if ((*(promvec->pv_v2devops).v2_dev_read) (*promvec->pv_v2bootargs.fd_stdin, &inc, 0x1) == 1) return inc; return -1; }