1 /*- 2 * Copyright (c) 2004 Hidetoshi Shimokawa 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 __FBSDID("$FreeBSD$"); 28 29 #include <stand.h> 30 #include <bootstrap.h> 31 #include <sys/param.h> 32 #include <btxv86.h> 33 #include <dev/dcons/dcons.h> 34 35 void fw_enable(void); 36 void fw_poll(void); 37 38 static void dconsole_probe(struct console *cp); 39 static int dconsole_init(int arg); 40 static void dconsole_putchar(int c); 41 static int dconsole_getchar(void); 42 static int dconsole_ischar(void); 43 44 static int dcons_started = 0; 45 46 #define DCONS_BUF_SIZE (64*1024) 47 static struct dcons_softc sc[DCONS_NPORT]; 48 uint32_t dcons_paddr; 49 50 /* The buffer must be allocated in BSS because: 51 * - The dcons driver in the kernel is initialized before VM/pmap is 52 * initialized, so that the buffer must be allocated in the region 53 * that is mapped at the very early boot state. 54 * - We expect identity map only for regions before KERNLOAD 55 * (i386:4MB amd64:1MB). 56 * - It seems that heap in conventional memory(640KB) is not sufficient 57 * and we move it to high address as LOADER_SUPPORT_BZIP2. 58 * - BSS is placed in conventional memory. 59 */ 60 static char dcons_buffer[DCONS_BUF_SIZE + PAGE_SIZE]; 61 62 struct console dconsole = { 63 .c_name = "dcons", 64 .c_desc = "dumb console port", 65 .c_flags = 0, 66 .c_probe = dconsole_probe, 67 .c_init = dconsole_init, 68 .c_out = dconsole_putchar, 69 .c_in = dconsole_getchar, 70 .c_ready = dconsole_ischar, 71 .c_private = NULL 72 }; 73 74 #define DCONSOLE_AS_MULTI_CONSOLE 1 75 76 static void 77 dconsole_probe(struct console *cp) 78 { 79 /* XXX check the BIOS equipment list? */ 80 cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT); 81 #if DCONSOLE_AS_MULTI_CONSOLE 82 dconsole_init(0); 83 cp->c_flags |= (C_ACTIVEIN | C_ACTIVEOUT); 84 #endif 85 } 86 87 static int 88 dconsole_init(int arg) 89 { 90 char buf[16], *dbuf; 91 int size; 92 93 if (dcons_started && arg == 0) 94 return 0; 95 dcons_started = 1; 96 97 size = DCONS_BUF_SIZE; 98 dbuf = (char *)round_page((vm_offset_t)&dcons_buffer[0]); 99 dcons_paddr = VTOP(dbuf); 100 sprintf(buf, "0x%08x", dcons_paddr); 101 setenv("dcons.addr", buf, 1); 102 103 dcons_init((struct dcons_buf *)dbuf, size, sc); 104 sprintf(buf, "%d", size); 105 setenv("dcons.size", buf, 1); 106 fw_enable(); 107 return(0); 108 } 109 110 static void 111 dconsole_putchar(int c) 112 { 113 dcons_putc(&sc[0], c); 114 } 115 116 static int 117 dconsole_getchar(void) 118 { 119 fw_poll(); 120 return (dcons_checkc(&sc[0])); 121 } 122 123 static int 124 dconsole_ischar(void) 125 { 126 fw_poll(); 127 return (dcons_ischar(&sc[0])); 128 } 129