| File: | obj-scan-build/../xen/console.c |
| Location: | line 53, column 8 |
| Description: | Branch condition evaluates to a garbage value |
| 1 | /* | |||
| 2 | * Copyright (C) 2006-2011 Free Software Foundation | |||
| 3 | * | |||
| 4 | * This program is free software ; you can redistribute it and/or modify | |||
| 5 | * it under the terms of the GNU General Public License as published by | |||
| 6 | * the Free Software Foundation ; either version 2 of the License, or | |||
| 7 | * (at your option) any later version. | |||
| 8 | * | |||
| 9 | * This program is distributed in the hope that it will be useful, | |||
| 10 | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | |||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 12 | * GNU General Public License for more details. | |||
| 13 | * | |||
| 14 | * You should have received a copy of the GNU General Public License | |||
| 15 | * along with the program ; if not, write to the Free Software | |||
| 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| 17 | */ | |||
| 18 | ||||
| 19 | #include <sys/types.h> | |||
| 20 | #include <device/tty.h> | |||
| 21 | #include <device/cons.h> | |||
| 22 | #include <machine/pmap.h> | |||
| 23 | #include <machine/machspl.h> | |||
| 24 | #include <xen/public/io/console.h> | |||
| 25 | #include "console.h" | |||
| 26 | #include "ring.h" | |||
| 27 | #include "evt.h" | |||
| 28 | ||||
| 29 | /* Hypervisor part */ | |||
| 30 | ||||
| 31 | decl_simple_lock_data(static, outlock)static struct simple_lock_data_empty outlock;; | |||
| 32 | decl_simple_lock_data(static, inlock)static struct simple_lock_data_empty inlock;; | |||
| 33 | static struct xencons_interface *console; | |||
| 34 | static int kd_pollc; | |||
| 35 | int kb_mode; /* XXX: actually don't care. */ | |||
| 36 | ||||
| 37 | #undef hyp_console_write | |||
| 38 | void hyp_console_write(const char *str, int len) | |||
| 39 | { | |||
| 40 | hyp_console_io (CONSOLEIO_write0, len, kvtolin(str)((vm_offset_t)(str) - 0xC0000000UL + ((0xc0000000UL)))); | |||
| 41 | } | |||
| 42 | ||||
| 43 | int hypputc(int c) | |||
| 44 | { | |||
| 45 | if (!console) { | |||
| 46 | char d = c; | |||
| 47 | hyp_console_io(CONSOLEIO_write0, 1, kvtolin(&d)((vm_offset_t)(&d) - 0xC0000000UL + ((0xc0000000UL)))); | |||
| 48 | } else { | |||
| 49 | spl_t spl = splhigh(); | |||
| 50 | int complain; | |||
| 51 | simple_lock(&outlock); | |||
| 52 | while (hyp_ring_smash(console->out, console->out_prod, console->out_cons)((((unsigned)((console->out_prod) + 1)) & (sizeof((console ->out))-1)) == (((unsigned)((console->out_cons))) & (sizeof((console->out))-1)))) { | |||
| 53 | if (!complain) { | |||
| ||||
| 54 | complain = 1; | |||
| 55 | hyp_console_put("ring smash\n")({ const char *__str = (void*) ("ring smash\n"); hyp_console_write (__str, strlen (__str)); }); | |||
| 56 | } | |||
| 57 | /* TODO: are we allowed to sleep in putc? */ | |||
| 58 | hyp_yield()hyp_sched_op(0, 0); | |||
| 59 | } | |||
| 60 | hyp_ring_cell(console->out, console->out_prod)(console->out)[(((unsigned)((console->out_prod))) & (sizeof((console->out))-1))] = c; | |||
| 61 | wmb()__asm__ __volatile__("lock; addl $0,0(%esp)"); | |||
| 62 | console->out_prod++; | |||
| 63 | hyp_event_channel_send(boot_info.console_evtchnconsole.domU.evtchn); | |||
| 64 | simple_unlock(&outlock)((void)(&outlock)); | |||
| 65 | splx(spl); | |||
| 66 | } | |||
| 67 | return 0; | |||
| 68 | } | |||
| 69 | ||||
| 70 | int hypcnputc(dev_t dev, int c) | |||
| 71 | { | |||
| 72 | return hypputc(c); | |||
| ||||
| 73 | } | |||
| 74 | ||||
| 75 | /* get char by polling, used by debugger */ | |||
| 76 | int hypcngetc(dev_t dev, int wait) | |||
| 77 | { | |||
| 78 | int ret; | |||
| 79 | if (wait) | |||
| 80 | while (console->in_prod == console->in_cons) | |||
| 81 | hyp_yield()hyp_sched_op(0, 0); | |||
| 82 | else | |||
| 83 | if (console->in_prod == console->in_cons) | |||
| 84 | return -1; | |||
| 85 | ret = hyp_ring_cell(console->in, console->in_cons)(console->in)[(((unsigned)((console->in_cons))) & ( sizeof((console->in))-1))]; | |||
| 86 | mb()__asm__ __volatile__("lock; addl $0,0(%esp)"); | |||
| 87 | console->in_cons++; | |||
| 88 | hyp_event_channel_send(boot_info.console_evtchnconsole.domU.evtchn); | |||
| 89 | return ret; | |||
| 90 | } | |||
| 91 | ||||
| 92 | void cnpollc(boolean_t on) { | |||
| 93 | if (on) { | |||
| 94 | kd_pollc++; | |||
| 95 | } else { | |||
| 96 | --kd_pollc; | |||
| 97 | } | |||
| 98 | } | |||
| 99 | ||||
| 100 | void kd_setleds1(u_char val) | |||
| 101 | { | |||
| 102 | /* Can't do this. */ | |||
| 103 | } | |||
| 104 | ||||
| 105 | /* Mach part */ | |||
| 106 | ||||
| 107 | struct tty hypcn_tty; | |||
| 108 | ||||
| 109 | static void hypcnintr(int unit, spl_t spl, void *ret_addr, void *regs) { | |||
| 110 | struct tty *tp = &hypcn_tty; | |||
| 111 | if (kd_pollc) | |||
| 112 | return; | |||
| 113 | simple_lock(&inlock); | |||
| 114 | while (console->in_prod != console->in_cons) { | |||
| 115 | int c = hyp_ring_cell(console->in, console->in_cons)(console->in)[(((unsigned)((console->in_cons))) & ( sizeof((console->in))-1))]; | |||
| 116 | mb()__asm__ __volatile__("lock; addl $0,0(%esp)"); | |||
| 117 | console->in_cons++; | |||
| 118 | #if MACH_KDB1 | |||
| 119 | if (c == (char)'£') { | |||
| 120 | printf("£ pressed\n"); | |||
| 121 | kdb_kintr(); | |||
| 122 | continue; | |||
| 123 | } | |||
| 124 | #endif /* MACH_KDB */ | |||
| 125 | if ((tp->t_state & (TS_ISOPEN0x00000008|TS_WOPEN0x00000004))) | |||
| 126 | (*linesw[tp->t_line].l_rint)(c, tp); | |||
| 127 | } | |||
| 128 | hyp_event_channel_send(boot_info.console_evtchnconsole.domU.evtchn); | |||
| 129 | simple_unlock(&inlock)((void)(&inlock)); | |||
| 130 | } | |||
| 131 | ||||
| 132 | int hypcnread(int dev, io_req_t ior) | |||
| 133 | { | |||
| 134 | struct tty *tp = &hypcn_tty; | |||
| 135 | tp->t_state |= TS_CARR_ON0x00000020; | |||
| 136 | return char_read(tp, ior); | |||
| 137 | } | |||
| 138 | ||||
| 139 | int hypcnwrite(int dev, io_req_t ior) | |||
| 140 | { | |||
| 141 | return char_write(&hypcn_tty, ior); | |||
| 142 | } | |||
| 143 | ||||
| 144 | void hypcnstart(struct tty *tp) | |||
| 145 | { | |||
| 146 | spl_t o_pri; | |||
| 147 | int ch; | |||
| 148 | unsigned char c; | |||
| 149 | ||||
| 150 | if (tp->t_state & TS_TTSTOP0x00000100) | |||
| 151 | return; | |||
| 152 | while (1) { | |||
| 153 | tp->t_state &= ~TS_BUSY0x00000040; | |||
| 154 | if (tp->t_state & TS_TTSTOP0x00000100) | |||
| 155 | break; | |||
| 156 | if ((tp->t_outq.c_cc <= 0) || (ch = getc(&tp->t_outq)) == -1) | |||
| 157 | break; | |||
| 158 | c = ch; | |||
| 159 | o_pri = splsoftclock(); | |||
| 160 | hypputc(c); | |||
| 161 | splx(o_pri); | |||
| 162 | } | |||
| 163 | if (tp->t_outq.c_cc <= TTLOWAT(tp)ttlowat[(tp)->t_ospeed]) { | |||
| 164 | tt_write_wakeup(tp)(tty_queue_completion(&(tp)->t_delayed_write)); | |||
| 165 | } | |||
| 166 | } | |||
| 167 | ||||
| 168 | void hypcnstop() | |||
| 169 | { | |||
| 170 | } | |||
| 171 | ||||
| 172 | io_return_t hypcngetstat(dev_t dev, int flavor, int *data, unsigned int *count) | |||
| 173 | { | |||
| 174 | return tty_get_status(&hypcn_tty, flavor, data, count); | |||
| 175 | } | |||
| 176 | ||||
| 177 | io_return_t hypcnsetstat(dev_t dev, int flavor, int *data, unsigned int count) | |||
| 178 | { | |||
| 179 | return tty_set_status(&hypcn_tty, flavor, data, count); | |||
| 180 | } | |||
| 181 | ||||
| 182 | int hypcnportdeath(dev_t dev, mach_port_t port) | |||
| 183 | { | |||
| 184 | return tty_portdeath(&hypcn_tty, (ipc_port_t) port); | |||
| 185 | } | |||
| 186 | ||||
| 187 | int hypcnopen(dev_t dev, int flag, io_req_t ior) | |||
| 188 | { | |||
| 189 | struct tty *tp = &hypcn_tty; | |||
| 190 | spl_t o_pri; | |||
| 191 | ||||
| 192 | o_pri = spltty(); | |||
| 193 | simple_lock(&tp->t_lock); | |||
| 194 | if (!(tp->t_state & (TS_ISOPEN0x00000008|TS_WOPEN0x00000004))) { | |||
| 195 | /* XXX ttychars allocates memory */ | |||
| 196 | simple_unlock(&tp->t_lock)((void)(&tp->t_lock)); | |||
| 197 | ttychars(tp); | |||
| 198 | simple_lock(&tp->t_lock); | |||
| 199 | tp->t_oproct_start = hypcnstart; | |||
| 200 | tp->t_stop = hypcnstop; | |||
| 201 | tp->t_ospeed = tp->t_ispeed = B960013; | |||
| 202 | tp->t_flags = ODDP0x00000002|EVENP0x00000004|ECHO0x00000080|CRMOD0x00000100|XTABS0x00000200; | |||
| 203 | } | |||
| 204 | tp->t_state |= TS_CARR_ON0x00000020; | |||
| 205 | simple_unlock(&tp->t_lock)((void)(&tp->t_lock)); | |||
| 206 | splx(o_pri); | |||
| 207 | return (char_open(dev, tp, flag, ior)); | |||
| 208 | } | |||
| 209 | ||||
| 210 | int hypcnclose(int dev, int flag) | |||
| 211 | { | |||
| 212 | struct tty *tp = &hypcn_tty; | |||
| 213 | spl_t s = spltty(); | |||
| 214 | simple_lock(&tp->t_lock); | |||
| 215 | ttyclose(tp); | |||
| 216 | simple_unlock(&tp->t_lock)((void)(&tp->t_lock)); | |||
| 217 | splx(s); | |||
| 218 | return 0; | |||
| 219 | } | |||
| 220 | ||||
| 221 | int hypcnprobe(struct consdev *cp) | |||
| 222 | { | |||
| 223 | cp->cn_dev = makedev(0, 0)((((0) & 0xFF) << 8) | ((0) & 0xFF)); | |||
| 224 | cp->cn_pri = CN_INTERNAL2; | |||
| 225 | return 0; | |||
| 226 | } | |||
| 227 | ||||
| 228 | int hypcninit(struct consdev *cp) | |||
| 229 | { | |||
| 230 | if (console) | |||
| 231 | return 0; | |||
| 232 | simple_lock_init(&outlock); | |||
| 233 | simple_lock_init(&inlock); | |||
| 234 | console = (void*) mfn_to_kv(boot_info.console_mfn)((vm_offset_t)(((vm_offset_t)(((((unsigned long *) 0xF5800000UL )[boot_info.console.domU.mfn])) << 12))) + 0xC0000000UL ); | |||
| 235 | #ifdef MACH_PV_PAGETABLES | |||
| 236 | pmap_set_page_readwrite(console); | |||
| 237 | #endif /* MACH_PV_PAGETABLES */ | |||
| 238 | hyp_evt_handler(boot_info.console_evtchnconsole.domU.evtchn, hypcnintr, 0, SPL66); | |||
| 239 | return 0; | |||
| 240 | } |