Commit 80cabfad16384ca47f783a7c494bd1c3c6e3c4bc

Authored by bellard
1 parent 38ca2abc

separated more devices from emulator


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@656 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
1 1 include config.mak
2 2  
3 3 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH)
4   -VPATH=$(SRC_PATH):$(TARGET_PATH)
  4 +VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw
5 5 CFLAGS=-Wall -O2 -g
6 6 LDFLAGS=-g
7 7 LIBS=
... ... @@ -204,7 +204,8 @@ ifeq ($(ARCH),alpha)
204 204 endif
205 205  
206 206 # must use static linking to avoid leaving stuff in virtual address space
207   -VL_OBJS=vl.o block.o ide.o vga.o sb16.o dma.o oss.o fdc.o osdep.o
  207 +VL_OBJS=vl.o osdep.o block.o ide.o ne2000.o pckbd.o vga.o sb16.o dma.o oss.o \
  208 + fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o
208 209 ifeq ($(TARGET_ARCH), ppc)
209 210 VL_OBJS+= hw.o
210 211 endif
... ...
hw/i8254.c 0 → 100644
  1 +/*
  2 + * QEMU 8253/8254 interval timer emulation
  3 + *
  4 + * Copyright (c) 2003-2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdlib.h>
  25 +#include <stdio.h>
  26 +#include <stdarg.h>
  27 +#include <string.h>
  28 +#include <getopt.h>
  29 +#include <inttypes.h>
  30 +#include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
  34 +#include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +#include <netinet/in.h>
  42 +
  43 +#include "cpu.h"
  44 +#include "vl.h"
  45 +
  46 +#define RW_STATE_LSB 0
  47 +#define RW_STATE_MSB 1
  48 +#define RW_STATE_WORD0 2
  49 +#define RW_STATE_WORD1 3
  50 +#define RW_STATE_LATCHED_WORD0 4
  51 +#define RW_STATE_LATCHED_WORD1 5
  52 +
  53 +PITChannelState pit_channels[3];
  54 +
  55 +static int pit_get_count(PITChannelState *s)
  56 +{
  57 + uint64_t d;
  58 + int counter;
  59 +
  60 + d = muldiv64(cpu_get_ticks() - s->count_load_time, PIT_FREQ, ticks_per_sec);
  61 + switch(s->mode) {
  62 + case 0:
  63 + case 1:
  64 + case 4:
  65 + case 5:
  66 + counter = (s->count - d) & 0xffff;
  67 + break;
  68 + case 3:
  69 + /* XXX: may be incorrect for odd counts */
  70 + counter = s->count - ((2 * d) % s->count);
  71 + break;
  72 + default:
  73 + counter = s->count - (d % s->count);
  74 + break;
  75 + }
  76 + return counter;
  77 +}
  78 +
  79 +/* get pit output bit */
  80 +int pit_get_out(PITChannelState *s)
  81 +{
  82 + uint64_t d;
  83 + int out;
  84 +
  85 + d = muldiv64(cpu_get_ticks() - s->count_load_time, PIT_FREQ, ticks_per_sec);
  86 + switch(s->mode) {
  87 + default:
  88 + case 0:
  89 + out = (d >= s->count);
  90 + break;
  91 + case 1:
  92 + out = (d < s->count);
  93 + break;
  94 + case 2:
  95 + if ((d % s->count) == 0 && d != 0)
  96 + out = 1;
  97 + else
  98 + out = 0;
  99 + break;
  100 + case 3:
  101 + out = (d % s->count) < ((s->count + 1) >> 1);
  102 + break;
  103 + case 4:
  104 + case 5:
  105 + out = (d == s->count);
  106 + break;
  107 + }
  108 + return out;
  109 +}
  110 +
  111 +/* get the number of 0 to 1 transitions we had since we call this
  112 + function */
  113 +/* XXX: maybe better to use ticks precision to avoid getting edges
  114 + twice if checks are done at very small intervals */
  115 +int pit_get_out_edges(PITChannelState *s)
  116 +{
  117 + uint64_t d1, d2;
  118 + int64_t ticks;
  119 + int ret, v;
  120 +
  121 + ticks = cpu_get_ticks();
  122 + d1 = muldiv64(s->count_last_edge_check_time - s->count_load_time,
  123 + PIT_FREQ, ticks_per_sec);
  124 + d2 = muldiv64(ticks - s->count_load_time,
  125 + PIT_FREQ, ticks_per_sec);
  126 + s->count_last_edge_check_time = ticks;
  127 + switch(s->mode) {
  128 + default:
  129 + case 0:
  130 + if (d1 < s->count && d2 >= s->count)
  131 + ret = 1;
  132 + else
  133 + ret = 0;
  134 + break;
  135 + case 1:
  136 + ret = 0;
  137 + break;
  138 + case 2:
  139 + d1 /= s->count;
  140 + d2 /= s->count;
  141 + ret = d2 - d1;
  142 + break;
  143 + case 3:
  144 + v = s->count - ((s->count + 1) >> 1);
  145 + d1 = (d1 + v) / s->count;
  146 + d2 = (d2 + v) / s->count;
  147 + ret = d2 - d1;
  148 + break;
  149 + case 4:
  150 + case 5:
  151 + if (d1 < s->count && d2 >= s->count)
  152 + ret = 1;
  153 + else
  154 + ret = 0;
  155 + break;
  156 + }
  157 + return ret;
  158 +}
  159 +
  160 +/* val must be 0 or 1 */
  161 +void pit_set_gate(PITChannelState *s, int val)
  162 +{
  163 + switch(s->mode) {
  164 + default:
  165 + case 0:
  166 + case 4:
  167 + /* XXX: just disable/enable counting */
  168 + break;
  169 + case 1:
  170 + case 5:
  171 + if (s->gate < val) {
  172 + /* restart counting on rising edge */
  173 + s->count_load_time = cpu_get_ticks();
  174 + s->count_last_edge_check_time = s->count_load_time;
  175 + }
  176 + break;
  177 + case 2:
  178 + case 3:
  179 + if (s->gate < val) {
  180 + /* restart counting on rising edge */
  181 + s->count_load_time = cpu_get_ticks();
  182 + s->count_last_edge_check_time = s->count_load_time;
  183 + }
  184 + /* XXX: disable/enable counting */
  185 + break;
  186 + }
  187 + s->gate = val;
  188 +}
  189 +
  190 +static inline void pit_load_count(PITChannelState *s, int val)
  191 +{
  192 + if (val == 0)
  193 + val = 0x10000;
  194 + s->count_load_time = cpu_get_ticks();
  195 + s->count_last_edge_check_time = s->count_load_time;
  196 + s->count = val;
  197 + if (s == &pit_channels[0] && val <= pit_min_timer_count) {
  198 + fprintf(stderr,
  199 + "\nWARNING: qemu: on your system, accurate timer emulation is impossible if its frequency is more than %d Hz. If using a 2.6 guest Linux kernel, you must patch asm/param.h to change HZ from 1000 to 100.\n\n",
  200 + PIT_FREQ / pit_min_timer_count);
  201 + }
  202 +}
  203 +
  204 +void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
  205 +{
  206 + int channel, access;
  207 + PITChannelState *s;
  208 +
  209 + addr &= 3;
  210 + if (addr == 3) {
  211 + channel = val >> 6;
  212 + if (channel == 3)
  213 + return;
  214 + s = &pit_channels[channel];
  215 + access = (val >> 4) & 3;
  216 + switch(access) {
  217 + case 0:
  218 + s->latched_count = pit_get_count(s);
  219 + s->rw_state = RW_STATE_LATCHED_WORD0;
  220 + break;
  221 + default:
  222 + s->mode = (val >> 1) & 7;
  223 + s->bcd = val & 1;
  224 + s->rw_state = access - 1 + RW_STATE_LSB;
  225 + break;
  226 + }
  227 + } else {
  228 + s = &pit_channels[addr];
  229 + switch(s->rw_state) {
  230 + case RW_STATE_LSB:
  231 + pit_load_count(s, val);
  232 + break;
  233 + case RW_STATE_MSB:
  234 + pit_load_count(s, val << 8);
  235 + break;
  236 + case RW_STATE_WORD0:
  237 + case RW_STATE_WORD1:
  238 + if (s->rw_state & 1) {
  239 + pit_load_count(s, (s->latched_count & 0xff) | (val << 8));
  240 + } else {
  241 + s->latched_count = val;
  242 + }
  243 + s->rw_state ^= 1;
  244 + break;
  245 + }
  246 + }
  247 +}
  248 +
  249 +uint32_t pit_ioport_read(CPUState *env, uint32_t addr)
  250 +{
  251 + int ret, count;
  252 + PITChannelState *s;
  253 +
  254 + addr &= 3;
  255 + s = &pit_channels[addr];
  256 + switch(s->rw_state) {
  257 + case RW_STATE_LSB:
  258 + case RW_STATE_MSB:
  259 + case RW_STATE_WORD0:
  260 + case RW_STATE_WORD1:
  261 + count = pit_get_count(s);
  262 + if (s->rw_state & 1)
  263 + ret = (count >> 8) & 0xff;
  264 + else
  265 + ret = count & 0xff;
  266 + if (s->rw_state & 2)
  267 + s->rw_state ^= 1;
  268 + break;
  269 + default:
  270 + case RW_STATE_LATCHED_WORD0:
  271 + case RW_STATE_LATCHED_WORD1:
  272 + if (s->rw_state & 1)
  273 + ret = s->latched_count >> 8;
  274 + else
  275 + ret = s->latched_count & 0xff;
  276 + s->rw_state ^= 1;
  277 + break;
  278 + }
  279 + return ret;
  280 +}
  281 +
  282 +void pit_init(void)
  283 +{
  284 + PITChannelState *s;
  285 + int i;
  286 +
  287 + for(i = 0;i < 3; i++) {
  288 + s = &pit_channels[i];
  289 + s->mode = 3;
  290 + s->gate = (i != 2);
  291 + pit_load_count(s, 0);
  292 + }
  293 +
  294 + register_ioport_write(0x40, 4, pit_ioport_write, 1);
  295 + register_ioport_read(0x40, 3, pit_ioport_read, 1);
  296 +}
  297 +
... ...
hw/i8259.c 0 → 100644
  1 +/*
  2 + * QEMU 8259 interrupt controller emulation
  3 + *
  4 + * Copyright (c) 2003-2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdlib.h>
  25 +#include <stdio.h>
  26 +#include <stdarg.h>
  27 +#include <string.h>
  28 +#include <getopt.h>
  29 +#include <inttypes.h>
  30 +#include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
  34 +#include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +#include <netinet/in.h>
  42 +
  43 +#include "cpu.h"
  44 +#include "vl.h"
  45 +
  46 +/* debug PIC */
  47 +//#define DEBUG_PIC
  48 +
  49 +typedef struct PicState {
  50 + uint8_t last_irr; /* edge detection */
  51 + uint8_t irr; /* interrupt request register */
  52 + uint8_t imr; /* interrupt mask register */
  53 + uint8_t isr; /* interrupt service register */
  54 + uint8_t priority_add; /* highest irq priority */
  55 + uint8_t irq_base;
  56 + uint8_t read_reg_select;
  57 + uint8_t poll;
  58 + uint8_t special_mask;
  59 + uint8_t init_state;
  60 + uint8_t auto_eoi;
  61 + uint8_t rotate_on_auto_eoi;
  62 + uint8_t special_fully_nested_mode;
  63 + uint8_t init4; /* true if 4 byte init */
  64 +} PicState;
  65 +
  66 +/* 0 is master pic, 1 is slave pic */
  67 +PicState pics[2];
  68 +int pic_irq_requested;
  69 +
  70 +/* set irq level. If an edge is detected, then the IRR is set to 1 */
  71 +static inline void pic_set_irq1(PicState *s, int irq, int level)
  72 +{
  73 + int mask;
  74 + mask = 1 << irq;
  75 + if (level) {
  76 + if ((s->last_irr & mask) == 0)
  77 + s->irr |= mask;
  78 + s->last_irr |= mask;
  79 + } else {
  80 + s->last_irr &= ~mask;
  81 + }
  82 +}
  83 +
  84 +/* return the highest priority found in mask (highest = smallest
  85 + number). Return 8 if no irq */
  86 +static inline int get_priority(PicState *s, int mask)
  87 +{
  88 + int priority;
  89 + if (mask == 0)
  90 + return 8;
  91 + priority = 0;
  92 + while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
  93 + priority++;
  94 + return priority;
  95 +}
  96 +
  97 +/* return the pic wanted interrupt. return -1 if none */
  98 +static int pic_get_irq(PicState *s)
  99 +{
  100 + int mask, cur_priority, priority;
  101 +
  102 + mask = s->irr & ~s->imr;
  103 + priority = get_priority(s, mask);
  104 + if (priority == 8)
  105 + return -1;
  106 + /* compute current priority. If special fully nested mode on the
  107 + master, the IRQ coming from the slave is not taken into account
  108 + for the priority computation. */
  109 + mask = s->isr;
  110 + if (s->special_fully_nested_mode && s == &pics[0])
  111 + mask &= ~(1 << 2);
  112 + cur_priority = get_priority(s, mask);
  113 + if (priority < cur_priority) {
  114 + /* higher priority found: an irq should be generated */
  115 + return (priority + s->priority_add) & 7;
  116 + } else {
  117 + return -1;
  118 + }
  119 +}
  120 +
  121 +/* raise irq to CPU if necessary. must be called every time the active
  122 + irq may change */
  123 +void pic_update_irq(void)
  124 +{
  125 + int irq2, irq;
  126 +
  127 + /* first look at slave pic */
  128 + irq2 = pic_get_irq(&pics[1]);
  129 + if (irq2 >= 0) {
  130 + /* if irq request by slave pic, signal master PIC */
  131 + pic_set_irq1(&pics[0], 2, 1);
  132 + pic_set_irq1(&pics[0], 2, 0);
  133 + }
  134 + /* look at requested irq */
  135 + irq = pic_get_irq(&pics[0]);
  136 + if (irq >= 0) {
  137 + if (irq == 2) {
  138 + /* from slave pic */
  139 + pic_irq_requested = 8 + irq2;
  140 + } else {
  141 + /* from master pic */
  142 + pic_irq_requested = irq;
  143 + }
  144 +#if defined(DEBUG_PIC)
  145 + {
  146 + int i;
  147 + for(i = 0; i < 2; i++) {
  148 + printf("pic%d: imr=%x irr=%x padd=%d\n",
  149 + i, pics[i].imr, pics[i].irr, pics[i].priority_add);
  150 +
  151 + }
  152 + }
  153 + printf("pic: cpu_interrupt req=%d\n", pic_irq_requested);
  154 +#endif
  155 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
  156 + }
  157 +}
  158 +
  159 +#ifdef DEBUG_IRQ_LATENCY
  160 +int64_t irq_time[16];
  161 +int64_t cpu_get_ticks(void);
  162 +#endif
  163 +#if defined(DEBUG_PIC)
  164 +int irq_level[16];
  165 +#endif
  166 +
  167 +void pic_set_irq(int irq, int level)
  168 +{
  169 +#if defined(DEBUG_PIC)
  170 + if (level != irq_level[irq]) {
  171 + printf("pic_set_irq: irq=%d level=%d\n", irq, level);
  172 + irq_level[irq] = level;
  173 + }
  174 +#endif
  175 +#ifdef DEBUG_IRQ_LATENCY
  176 + if (level) {
  177 + irq_time[irq] = cpu_get_ticks();
  178 + }
  179 +#endif
  180 + pic_set_irq1(&pics[irq >> 3], irq & 7, level);
  181 + pic_update_irq();
  182 +}
  183 +
  184 +/* acknowledge interrupt 'irq' */
  185 +static inline void pic_intack(PicState *s, int irq)
  186 +{
  187 + if (s->auto_eoi) {
  188 + if (s->rotate_on_auto_eoi)
  189 + s->priority_add = (irq + 1) & 7;
  190 + } else {
  191 + s->isr |= (1 << irq);
  192 + }
  193 + s->irr &= ~(1 << irq);
  194 +}
  195 +
  196 +int cpu_x86_get_pic_interrupt(CPUState *env)
  197 +{
  198 + int irq, irq2, intno;
  199 +
  200 + /* signal the pic that the irq was acked by the CPU */
  201 + irq = pic_irq_requested;
  202 +#ifdef DEBUG_IRQ_LATENCY
  203 + printf("IRQ%d latency=%0.3fus\n",
  204 + irq,
  205 + (double)(cpu_get_ticks() - irq_time[irq]) * 1000000.0 / ticks_per_sec);
  206 +#endif
  207 +#if defined(DEBUG_PIC)
  208 + printf("pic_interrupt: irq=%d\n", irq);
  209 +#endif
  210 +
  211 + if (irq >= 8) {
  212 + irq2 = irq & 7;
  213 + pic_intack(&pics[1], irq2);
  214 + irq = 2;
  215 + intno = pics[1].irq_base + irq2;
  216 + } else {
  217 + intno = pics[0].irq_base + irq;
  218 + }
  219 + pic_intack(&pics[0], irq);
  220 + return intno;
  221 +}
  222 +
  223 +void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
  224 +{
  225 + PicState *s;
  226 + int priority, cmd, irq;
  227 +
  228 +#ifdef DEBUG_PIC
  229 + printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
  230 +#endif
  231 + s = &pics[addr >> 7];
  232 + addr &= 1;
  233 + if (addr == 0) {
  234 + if (val & 0x10) {
  235 + /* init */
  236 + memset(s, 0, sizeof(PicState));
  237 + s->init_state = 1;
  238 + s->init4 = val & 1;
  239 + if (val & 0x02)
  240 + hw_error("single mode not supported");
  241 + if (val & 0x08)
  242 + hw_error("level sensitive irq not supported");
  243 + } else if (val & 0x08) {
  244 + if (val & 0x04)
  245 + s->poll = 1;
  246 + if (val & 0x02)
  247 + s->read_reg_select = val & 1;
  248 + if (val & 0x40)
  249 + s->special_mask = (val >> 5) & 1;
  250 + } else {
  251 + cmd = val >> 5;
  252 + switch(cmd) {
  253 + case 0:
  254 + case 4:
  255 + s->rotate_on_auto_eoi = cmd >> 2;
  256 + break;
  257 + case 1: /* end of interrupt */
  258 + case 5:
  259 + priority = get_priority(s, s->isr);
  260 + if (priority != 8) {
  261 + irq = (priority + s->priority_add) & 7;
  262 + s->isr &= ~(1 << irq);
  263 + if (cmd == 5)
  264 + s->priority_add = (irq + 1) & 7;
  265 + pic_update_irq();
  266 + }
  267 + break;
  268 + case 3:
  269 + irq = val & 7;
  270 + s->isr &= ~(1 << irq);
  271 + pic_update_irq();
  272 + break;
  273 + case 6:
  274 + s->priority_add = (val + 1) & 7;
  275 + pic_update_irq();
  276 + break;
  277 + case 7:
  278 + irq = val & 7;
  279 + s->isr &= ~(1 << irq);
  280 + s->priority_add = (irq + 1) & 7;
  281 + pic_update_irq();
  282 + break;
  283 + default:
  284 + /* no operation */
  285 + break;
  286 + }
  287 + }
  288 + } else {
  289 + switch(s->init_state) {
  290 + case 0:
  291 + /* normal mode */
  292 + s->imr = val;
  293 + pic_update_irq();
  294 + break;
  295 + case 1:
  296 + s->irq_base = val & 0xf8;
  297 + s->init_state = 2;
  298 + break;
  299 + case 2:
  300 + if (s->init4) {
  301 + s->init_state = 3;
  302 + } else {
  303 + s->init_state = 0;
  304 + }
  305 + break;
  306 + case 3:
  307 + s->special_fully_nested_mode = (val >> 4) & 1;
  308 + s->auto_eoi = (val >> 1) & 1;
  309 + s->init_state = 0;
  310 + break;
  311 + }
  312 + }
  313 +}
  314 +
  315 +static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
  316 +{
  317 + int ret;
  318 +
  319 + ret = pic_get_irq(s);
  320 + if (ret >= 0) {
  321 + if (addr1 >> 7) {
  322 + pics[0].isr &= ~(1 << 2);
  323 + pics[0].irr &= ~(1 << 2);
  324 + }
  325 + s->irr &= ~(1 << ret);
  326 + s->isr &= ~(1 << ret);
  327 + if (addr1 >> 7 || ret != 2)
  328 + pic_update_irq();
  329 + } else {
  330 + ret = 0x07;
  331 + pic_update_irq();
  332 + }
  333 +
  334 + return ret;
  335 +}
  336 +
  337 +uint32_t pic_ioport_read(CPUState *env, uint32_t addr1)
  338 +{
  339 + PicState *s;
  340 + unsigned int addr;
  341 + int ret;
  342 +
  343 + addr = addr1;
  344 + s = &pics[addr >> 7];
  345 + addr &= 1;
  346 + if (s->poll) {
  347 + ret = pic_poll_read(s, addr1);
  348 + s->poll = 0;
  349 + } else {
  350 + if (addr == 0) {
  351 + if (s->read_reg_select)
  352 + ret = s->isr;
  353 + else
  354 + ret = s->irr;
  355 + } else {
  356 + ret = s->imr;
  357 + }
  358 + }
  359 +#ifdef DEBUG_PIC
  360 + printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
  361 +#endif
  362 + return ret;
  363 +}
  364 +
  365 +/* memory mapped interrupt status */
  366 +uint32_t pic_intack_read(CPUState *env)
  367 +{
  368 + int ret;
  369 +
  370 + ret = pic_poll_read(&pics[0], 0x00);
  371 + if (ret == 2)
  372 + ret = pic_poll_read(&pics[1], 0x80) + 8;
  373 + /* Prepare for ISR read */
  374 + pics[0].read_reg_select = 1;
  375 +
  376 + return ret;
  377 +}
  378 +
  379 +void pic_init(void)
  380 +{
  381 +#if defined (TARGET_I386) || defined (TARGET_PPC)
  382 + register_ioport_write(0x20, 2, pic_ioport_write, 1);
  383 + register_ioport_read(0x20, 2, pic_ioport_read, 1);
  384 + register_ioport_write(0xa0, 2, pic_ioport_write, 1);
  385 + register_ioport_read(0xa0, 2, pic_ioport_read, 1);
  386 +#endif
  387 +}
  388 +
... ...
hw/mc146818rtc.c 0 → 100644
  1 +/*
  2 + * QEMU MC146818 RTC emulation
  3 + *
  4 + * Copyright (c) 2003-2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdlib.h>
  25 +#include <stdio.h>
  26 +#include <stdarg.h>
  27 +#include <string.h>
  28 +#include <getopt.h>
  29 +#include <inttypes.h>
  30 +#include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
  34 +#include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +#include <netinet/in.h>
  42 +
  43 +#include "cpu.h"
  44 +#include "vl.h"
  45 +
  46 +//#define DEBUG_CMOS
  47 +
  48 +#define RTC_SECONDS 0
  49 +#define RTC_SECONDS_ALARM 1
  50 +#define RTC_MINUTES 2
  51 +#define RTC_MINUTES_ALARM 3
  52 +#define RTC_HOURS 4
  53 +#define RTC_HOURS_ALARM 5
  54 +#define RTC_ALARM_DONT_CARE 0xC0
  55 +
  56 +#define RTC_DAY_OF_WEEK 6
  57 +#define RTC_DAY_OF_MONTH 7
  58 +#define RTC_MONTH 8
  59 +#define RTC_YEAR 9
  60 +
  61 +#define RTC_REG_A 10
  62 +#define RTC_REG_B 11
  63 +#define RTC_REG_C 12
  64 +#define RTC_REG_D 13
  65 +
  66 +/* PC cmos mappings */
  67 +#define REG_IBM_CENTURY_BYTE 0x32
  68 +#define REG_IBM_PS2_CENTURY_BYTE 0x37
  69 +
  70 +RTCState rtc_state;
  71 +
  72 +static void cmos_ioport_write(CPUState *env, uint32_t addr, uint32_t data)
  73 +{
  74 + RTCState *s = &rtc_state;
  75 +
  76 + if ((addr & 1) == 0) {
  77 + s->cmos_index = data & 0x7f;
  78 + } else {
  79 +#ifdef DEBUG_CMOS
  80 + printf("cmos: write index=0x%02x val=0x%02x\n",
  81 + s->cmos_index, data);
  82 +#endif
  83 + switch(addr) {
  84 + case RTC_SECONDS_ALARM:
  85 + case RTC_MINUTES_ALARM:
  86 + case RTC_HOURS_ALARM:
  87 + /* XXX: not supported */
  88 + s->cmos_data[s->cmos_index] = data;
  89 + break;
  90 + case RTC_SECONDS:
  91 + case RTC_MINUTES:
  92 + case RTC_HOURS:
  93 + case RTC_DAY_OF_WEEK:
  94 + case RTC_DAY_OF_MONTH:
  95 + case RTC_MONTH:
  96 + case RTC_YEAR:
  97 + s->cmos_data[s->cmos_index] = data;
  98 + break;
  99 + case RTC_REG_A:
  100 + case RTC_REG_B:
  101 + s->cmos_data[s->cmos_index] = data;
  102 + break;
  103 + case RTC_REG_C:
  104 + case RTC_REG_D:
  105 + /* cannot write to them */
  106 + break;
  107 + default:
  108 + s->cmos_data[s->cmos_index] = data;
  109 + break;
  110 + }
  111 + }
  112 +}
  113 +
  114 +static inline int to_bcd(int a)
  115 +{
  116 + return ((a / 10) << 4) | (a % 10);
  117 +}
  118 +
  119 +static void cmos_update_time(RTCState *s)
  120 +{
  121 + struct tm *tm;
  122 + time_t ti;
  123 +
  124 + ti = time(NULL);
  125 + tm = gmtime(&ti);
  126 + s->cmos_data[RTC_SECONDS] = to_bcd(tm->tm_sec);
  127 + s->cmos_data[RTC_MINUTES] = to_bcd(tm->tm_min);
  128 + s->cmos_data[RTC_HOURS] = to_bcd(tm->tm_hour);
  129 + s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(tm->tm_wday);
  130 + s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(tm->tm_mday);
  131 + s->cmos_data[RTC_MONTH] = to_bcd(tm->tm_mon + 1);
  132 + s->cmos_data[RTC_YEAR] = to_bcd(tm->tm_year % 100);
  133 + s->cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19);
  134 + s->cmos_data[REG_IBM_PS2_CENTURY_BYTE] = s->cmos_data[REG_IBM_CENTURY_BYTE];
  135 +}
  136 +
  137 +static uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
  138 +{
  139 + RTCState *s = &rtc_state;
  140 + int ret;
  141 + if ((addr & 1) == 0) {
  142 + return 0xff;
  143 + } else {
  144 + switch(s->cmos_index) {
  145 + case RTC_SECONDS:
  146 + case RTC_MINUTES:
  147 + case RTC_HOURS:
  148 + case RTC_DAY_OF_WEEK:
  149 + case RTC_DAY_OF_MONTH:
  150 + case RTC_MONTH:
  151 + case RTC_YEAR:
  152 + case REG_IBM_CENTURY_BYTE:
  153 + case REG_IBM_PS2_CENTURY_BYTE:
  154 + cmos_update_time(s);
  155 + ret = s->cmos_data[s->cmos_index];
  156 + break;
  157 + case RTC_REG_A:
  158 + ret = s->cmos_data[s->cmos_index];
  159 + /* toggle update-in-progress bit for Linux (same hack as
  160 + plex86) */
  161 + s->cmos_data[RTC_REG_A] ^= 0x80;
  162 + break;
  163 + case RTC_REG_C:
  164 + ret = s->cmos_data[s->cmos_index];
  165 + pic_set_irq(s->irq, 0);
  166 + s->cmos_data[RTC_REG_C] = 0x00;
  167 + break;
  168 + default:
  169 + ret = s->cmos_data[s->cmos_index];
  170 + break;
  171 + }
  172 +#ifdef DEBUG_CMOS
  173 + printf("cmos: read index=0x%02x val=0x%02x\n",
  174 + s->cmos_index, ret);
  175 +#endif
  176 + return ret;
  177 + }
  178 +}
  179 +
  180 +void rtc_timer(void)
  181 +{
  182 + RTCState *s = &rtc_state;
  183 + if (s->cmos_data[RTC_REG_B] & 0x50) {
  184 + pic_set_irq(s->irq, 1);
  185 + }
  186 +}
  187 +
  188 +void rtc_init(int base, int irq)
  189 +{
  190 + RTCState *s = &rtc_state;
  191 +
  192 + cmos_update_time(s);
  193 +
  194 + s->irq = irq;
  195 + s->cmos_data[RTC_REG_A] = 0x26;
  196 + s->cmos_data[RTC_REG_B] = 0x02;
  197 + s->cmos_data[RTC_REG_C] = 0x00;
  198 + s->cmos_data[RTC_REG_D] = 0x80;
  199 +
  200 + register_ioport_write(base, 2, cmos_ioport_write, 1);
  201 + register_ioport_read(base, 2, cmos_ioport_read, 1);
  202 +}
  203 +
... ...
hw/ne2000.c 0 → 100644
  1 +/*
  2 + * QEMU NE2000 emulation
  3 + *
  4 + * Copyright (c) 2003-2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdlib.h>
  25 +#include <stdio.h>
  26 +#include <stdarg.h>
  27 +#include <string.h>
  28 +#include <getopt.h>
  29 +#include <inttypes.h>
  30 +#include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
  34 +#include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +#include <netinet/in.h>
  42 +
  43 +#include "cpu.h"
  44 +#include "vl.h"
  45 +
  46 +/* debug NE2000 card */
  47 +//#define DEBUG_NE2000
  48 +
  49 +/***********************************************************/
  50 +/* ne2000 emulation */
  51 +
  52 +#define E8390_CMD 0x00 /* The command register (for all pages) */
  53 +/* Page 0 register offsets. */
  54 +#define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */
  55 +#define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */
  56 +#define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */
  57 +#define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */
  58 +#define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */
  59 +#define EN0_TSR 0x04 /* Transmit status reg RD */
  60 +#define EN0_TPSR 0x04 /* Transmit starting page WR */
  61 +#define EN0_NCR 0x05 /* Number of collision reg RD */
  62 +#define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */
  63 +#define EN0_FIFO 0x06 /* FIFO RD */
  64 +#define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */
  65 +#define EN0_ISR 0x07 /* Interrupt status reg RD WR */
  66 +#define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */
  67 +#define EN0_RSARLO 0x08 /* Remote start address reg 0 */
  68 +#define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */
  69 +#define EN0_RSARHI 0x09 /* Remote start address reg 1 */
  70 +#define EN0_RCNTLO 0x0a /* Remote byte count reg WR */
  71 +#define EN0_RCNTHI 0x0b /* Remote byte count reg WR */
  72 +#define EN0_RSR 0x0c /* rx status reg RD */
  73 +#define EN0_RXCR 0x0c /* RX configuration reg WR */
  74 +#define EN0_TXCR 0x0d /* TX configuration reg WR */
  75 +#define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */
  76 +#define EN0_DCFG 0x0e /* Data configuration reg WR */
  77 +#define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */
  78 +#define EN0_IMR 0x0f /* Interrupt mask reg WR */
  79 +#define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */
  80 +
  81 +#define EN1_PHYS 0x11
  82 +#define EN1_CURPAG 0x17
  83 +#define EN1_MULT 0x18
  84 +
  85 +/* Register accessed at EN_CMD, the 8390 base addr. */
  86 +#define E8390_STOP 0x01 /* Stop and reset the chip */
  87 +#define E8390_START 0x02 /* Start the chip, clear reset */
  88 +#define E8390_TRANS 0x04 /* Transmit a frame */
  89 +#define E8390_RREAD 0x08 /* Remote read */
  90 +#define E8390_RWRITE 0x10 /* Remote write */
  91 +#define E8390_NODMA 0x20 /* Remote DMA */
  92 +#define E8390_PAGE0 0x00 /* Select page chip registers */
  93 +#define E8390_PAGE1 0x40 /* using the two high-order bits */
  94 +#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
  95 +
  96 +/* Bits in EN0_ISR - Interrupt status register */
  97 +#define ENISR_RX 0x01 /* Receiver, no error */
  98 +#define ENISR_TX 0x02 /* Transmitter, no error */
  99 +#define ENISR_RX_ERR 0x04 /* Receiver, with error */
  100 +#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
  101 +#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
  102 +#define ENISR_COUNTERS 0x20 /* Counters need emptying */
  103 +#define ENISR_RDC 0x40 /* remote dma complete */
  104 +#define ENISR_RESET 0x80 /* Reset completed */
  105 +#define ENISR_ALL 0x3f /* Interrupts we will enable */
  106 +
  107 +/* Bits in received packet status byte and EN0_RSR*/
  108 +#define ENRSR_RXOK 0x01 /* Received a good packet */
  109 +#define ENRSR_CRC 0x02 /* CRC error */
  110 +#define ENRSR_FAE 0x04 /* frame alignment error */
  111 +#define ENRSR_FO 0x08 /* FIFO overrun */
  112 +#define ENRSR_MPA 0x10 /* missed pkt */
  113 +#define ENRSR_PHY 0x20 /* physical/multicast address */
  114 +#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
  115 +#define ENRSR_DEF 0x80 /* deferring */
  116 +
  117 +/* Transmitted packet status, EN0_TSR. */
  118 +#define ENTSR_PTX 0x01 /* Packet transmitted without error */
  119 +#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
  120 +#define ENTSR_COL 0x04 /* The transmit collided at least once. */
  121 +#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
  122 +#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
  123 +#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
  124 +#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
  125 +#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
  126 +
  127 +#define NE2000_MEM_SIZE 32768
  128 +
  129 +typedef struct NE2000State {
  130 + uint8_t cmd;
  131 + uint32_t start;
  132 + uint32_t stop;
  133 + uint8_t boundary;
  134 + uint8_t tsr;
  135 + uint8_t tpsr;
  136 + uint16_t tcnt;
  137 + uint16_t rcnt;
  138 + uint32_t rsar;
  139 + uint8_t isr;
  140 + uint8_t dcfg;
  141 + uint8_t imr;
  142 + uint8_t phys[6]; /* mac address */
  143 + uint8_t curpag;
  144 + uint8_t mult[8]; /* multicast mask array */
  145 + int irq;
  146 + uint8_t mem[NE2000_MEM_SIZE];
  147 +} NE2000State;
  148 +
  149 +static NE2000State ne2000_state;
  150 +int net_fd = -1;
  151 +
  152 +static void ne2000_reset(NE2000State *s)
  153 +{
  154 + int i;
  155 +
  156 + s->isr = ENISR_RESET;
  157 + s->mem[0] = 0x52;
  158 + s->mem[1] = 0x54;
  159 + s->mem[2] = 0x00;
  160 + s->mem[3] = 0x12;
  161 + s->mem[4] = 0x34;
  162 + s->mem[5] = 0x56;
  163 + s->mem[14] = 0x57;
  164 + s->mem[15] = 0x57;
  165 +
  166 + /* duplicate prom data */
  167 + for(i = 15;i >= 0; i--) {
  168 + s->mem[2 * i] = s->mem[i];
  169 + s->mem[2 * i + 1] = s->mem[i];
  170 + }
  171 +}
  172 +
  173 +static void ne2000_update_irq(NE2000State *s)
  174 +{
  175 + int isr;
  176 + isr = s->isr & s->imr;
  177 + if (isr)
  178 + pic_set_irq(s->irq, 1);
  179 + else
  180 + pic_set_irq(s->irq, 0);
  181 +}
  182 +
  183 +/* return true if the NE2000 can receive more data */
  184 +int ne2000_can_receive(void)
  185 +{
  186 + NE2000State *s = &ne2000_state;
  187 + int avail, index, boundary;
  188 +
  189 + if (s->cmd & E8390_STOP)
  190 + return 0;
  191 + index = s->curpag << 8;
  192 + boundary = s->boundary << 8;
  193 + if (index < boundary)
  194 + avail = boundary - index;
  195 + else
  196 + avail = (s->stop - s->start) - (index - boundary);
  197 + if (avail < (MAX_ETH_FRAME_SIZE + 4))
  198 + return 0;
  199 + return 1;
  200 +}
  201 +
  202 +void ne2000_receive(uint8_t *buf, int size)
  203 +{
  204 + NE2000State *s = &ne2000_state;
  205 + uint8_t *p;
  206 + int total_len, next, avail, len, index;
  207 +
  208 +#if defined(DEBUG_NE2000)
  209 + printf("NE2000: received len=%d\n", size);
  210 +#endif
  211 +
  212 + index = s->curpag << 8;
  213 + /* 4 bytes for header */
  214 + total_len = size + 4;
  215 + /* address for next packet (4 bytes for CRC) */
  216 + next = index + ((total_len + 4 + 255) & ~0xff);
  217 + if (next >= s->stop)
  218 + next -= (s->stop - s->start);
  219 + /* prepare packet header */
  220 + p = s->mem + index;
  221 + p[0] = ENRSR_RXOK; /* receive status */
  222 + p[1] = next >> 8;
  223 + p[2] = total_len;
  224 + p[3] = total_len >> 8;
  225 + index += 4;
  226 +
  227 + /* write packet data */
  228 + while (size > 0) {
  229 + avail = s->stop - index;
  230 + len = size;
  231 + if (len > avail)
  232 + len = avail;
  233 + memcpy(s->mem + index, buf, len);
  234 + buf += len;
  235 + index += len;
  236 + if (index == s->stop)
  237 + index = s->start;
  238 + size -= len;
  239 + }
  240 + s->curpag = next >> 8;
  241 +
  242 + /* now we can signal we have receive something */
  243 + s->isr |= ENISR_RX;
  244 + ne2000_update_irq(s);
  245 +}
  246 +
  247 +static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
  248 +{
  249 + NE2000State *s = &ne2000_state;
  250 + int offset, page;
  251 +
  252 + addr &= 0xf;
  253 +#ifdef DEBUG_NE2000
  254 + printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
  255 +#endif
  256 + if (addr == E8390_CMD) {
  257 + /* control register */
  258 + s->cmd = val;
  259 + if (val & E8390_START) {
  260 + /* test specific case: zero length transfert */
  261 + if ((val & (E8390_RREAD | E8390_RWRITE)) &&
  262 + s->rcnt == 0) {
  263 + s->isr |= ENISR_RDC;
  264 + ne2000_update_irq(s);
  265 + }
  266 + if (val & E8390_TRANS) {
  267 + net_send_packet(net_fd, s->mem + (s->tpsr << 8), s->tcnt);
  268 + /* signal end of transfert */
  269 + s->tsr = ENTSR_PTX;
  270 + s->isr |= ENISR_TX;
  271 + ne2000_update_irq(s);
  272 + }
  273 + }
  274 + } else {
  275 + page = s->cmd >> 6;
  276 + offset = addr | (page << 4);
  277 + switch(offset) {
  278 + case EN0_STARTPG:
  279 + s->start = val << 8;
  280 + break;
  281 + case EN0_STOPPG:
  282 + s->stop = val << 8;
  283 + break;
  284 + case EN0_BOUNDARY:
  285 + s->boundary = val;
  286 + break;
  287 + case EN0_IMR:
  288 + s->imr = val;
  289 + ne2000_update_irq(s);
  290 + break;
  291 + case EN0_TPSR:
  292 + s->tpsr = val;
  293 + break;
  294 + case EN0_TCNTLO:
  295 + s->tcnt = (s->tcnt & 0xff00) | val;
  296 + break;
  297 + case EN0_TCNTHI:
  298 + s->tcnt = (s->tcnt & 0x00ff) | (val << 8);
  299 + break;
  300 + case EN0_RSARLO:
  301 + s->rsar = (s->rsar & 0xff00) | val;
  302 + break;
  303 + case EN0_RSARHI:
  304 + s->rsar = (s->rsar & 0x00ff) | (val << 8);
  305 + break;
  306 + case EN0_RCNTLO:
  307 + s->rcnt = (s->rcnt & 0xff00) | val;
  308 + break;
  309 + case EN0_RCNTHI:
  310 + s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
  311 + break;
  312 + case EN0_DCFG:
  313 + s->dcfg = val;
  314 + break;
  315 + case EN0_ISR:
  316 + s->isr &= ~val;
  317 + ne2000_update_irq(s);
  318 + break;
  319 + case EN1_PHYS ... EN1_PHYS + 5:
  320 + s->phys[offset - EN1_PHYS] = val;
  321 + break;
  322 + case EN1_CURPAG:
  323 + s->curpag = val;
  324 + break;
  325 + case EN1_MULT ... EN1_MULT + 7:
  326 + s->mult[offset - EN1_MULT] = val;
  327 + break;
  328 + }
  329 + }
  330 +}
  331 +
  332 +static uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr)
  333 +{
  334 + NE2000State *s = &ne2000_state;
  335 + int offset, page, ret;
  336 +
  337 + addr &= 0xf;
  338 + if (addr == E8390_CMD) {
  339 + ret = s->cmd;
  340 + } else {
  341 + page = s->cmd >> 6;
  342 + offset = addr | (page << 4);
  343 + switch(offset) {
  344 + case EN0_TSR:
  345 + ret = s->tsr;
  346 + break;
  347 + case EN0_BOUNDARY:
  348 + ret = s->boundary;
  349 + break;
  350 + case EN0_ISR:
  351 + ret = s->isr;
  352 + break;
  353 + case EN1_PHYS ... EN1_PHYS + 5:
  354 + ret = s->phys[offset - EN1_PHYS];
  355 + break;
  356 + case EN1_CURPAG:
  357 + ret = s->curpag;
  358 + break;
  359 + case EN1_MULT ... EN1_MULT + 7:
  360 + ret = s->mult[offset - EN1_MULT];
  361 + break;
  362 + default:
  363 + ret = 0x00;
  364 + break;
  365 + }
  366 + }
  367 +#ifdef DEBUG_NE2000
  368 + printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
  369 +#endif
  370 + return ret;
  371 +}
  372 +
  373 +static void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
  374 +{
  375 + NE2000State *s = &ne2000_state;
  376 + uint8_t *p;
  377 +
  378 +#ifdef DEBUG_NE2000
  379 + printf("NE2000: asic write val=0x%04x\n", val);
  380 +#endif
  381 + p = s->mem + s->rsar;
  382 + if (s->dcfg & 0x01) {
  383 + /* 16 bit access */
  384 + p[0] = val;
  385 + p[1] = val >> 8;
  386 + s->rsar += 2;
  387 + s->rcnt -= 2;
  388 + } else {
  389 + /* 8 bit access */
  390 + p[0] = val;
  391 + s->rsar++;
  392 + s->rcnt--;
  393 + }
  394 + /* wrap */
  395 + if (s->rsar == s->stop)
  396 + s->rsar = s->start;
  397 + if (s->rcnt == 0) {
  398 + /* signal end of transfert */
  399 + s->isr |= ENISR_RDC;
  400 + ne2000_update_irq(s);
  401 + }
  402 +}
  403 +
  404 +static uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr)
  405 +{
  406 + NE2000State *s = &ne2000_state;
  407 + uint8_t *p;
  408 + int ret;
  409 +
  410 + p = s->mem + s->rsar;
  411 + if (s->dcfg & 0x01) {
  412 + /* 16 bit access */
  413 + ret = p[0] | (p[1] << 8);
  414 + s->rsar += 2;
  415 + s->rcnt -= 2;
  416 + } else {
  417 + /* 8 bit access */
  418 + ret = p[0];
  419 + s->rsar++;
  420 + s->rcnt--;
  421 + }
  422 + /* wrap */
  423 + if (s->rsar == s->stop)
  424 + s->rsar = s->start;
  425 + if (s->rcnt == 0) {
  426 + /* signal end of transfert */
  427 + s->isr |= ENISR_RDC;
  428 + ne2000_update_irq(s);
  429 + }
  430 +#ifdef DEBUG_NE2000
  431 + printf("NE2000: asic read val=0x%04x\n", ret);
  432 +#endif
  433 + return ret;
  434 +}
  435 +
  436 +static void ne2000_reset_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
  437 +{
  438 + /* nothing to do (end of reset pulse) */
  439 +}
  440 +
  441 +static uint32_t ne2000_reset_ioport_read(CPUState *env, uint32_t addr)
  442 +{
  443 + NE2000State *s = &ne2000_state;
  444 + ne2000_reset(s);
  445 + return 0;
  446 +}
  447 +
  448 +void ne2000_init(int base, int irq)
  449 +{
  450 + NE2000State *s = &ne2000_state;
  451 +
  452 + register_ioport_write(base, 16, ne2000_ioport_write, 1);
  453 + register_ioport_read(base, 16, ne2000_ioport_read, 1);
  454 +
  455 + register_ioport_write(base + 0x10, 1, ne2000_asic_ioport_write, 1);
  456 + register_ioport_read(base + 0x10, 1, ne2000_asic_ioport_read, 1);
  457 + register_ioport_write(base + 0x10, 2, ne2000_asic_ioport_write, 2);
  458 + register_ioport_read(base + 0x10, 2, ne2000_asic_ioport_read, 2);
  459 +
  460 + register_ioport_write(base + 0x1f, 1, ne2000_reset_ioport_write, 1);
  461 + register_ioport_read(base + 0x1f, 1, ne2000_reset_ioport_read, 1);
  462 + s->irq = irq;
  463 +
  464 + ne2000_reset(s);
  465 +}
... ...
hw/pc.c 0 → 100644
  1 +/*
  2 + * QEMU PC System Emulator
  3 + *
  4 + * Copyright (c) 2003-2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdlib.h>
  25 +#include <stdio.h>
  26 +#include <stdarg.h>
  27 +#include <string.h>
  28 +#include <getopt.h>
  29 +#include <inttypes.h>
  30 +#include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
  34 +#include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +#include <netinet/in.h>
  42 +
  43 +#include "cpu.h"
  44 +#include "vl.h"
  45 +
  46 +#define BIOS_FILENAME "bios.bin"
  47 +#define VGABIOS_FILENAME "vgabios.bin"
  48 +#define LINUX_BOOT_FILENAME "linux_boot.bin"
  49 +
  50 +#define KERNEL_LOAD_ADDR 0x00100000
  51 +#define INITRD_LOAD_ADDR 0x00400000
  52 +#define KERNEL_PARAMS_ADDR 0x00090000
  53 +#define KERNEL_CMDLINE_ADDR 0x00099000
  54 +
  55 +int speaker_data_on;
  56 +int dummy_refresh_clock;
  57 +
  58 +static void ioport80_write(CPUState *env, uint32_t addr, uint32_t data)
  59 +{
  60 +}
  61 +
  62 +#define REG_EQUIPMENT_BYTE 0x14
  63 +
  64 +static void cmos_init(int ram_size, int boot_device)
  65 +{
  66 + RTCState *s = &rtc_state;
  67 + int val;
  68 +
  69 + /* various important CMOS locations needed by PC/Bochs bios */
  70 +
  71 + s->cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
  72 + s->cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
  73 +
  74 + /* memory size */
  75 + val = (ram_size / 1024) - 1024;
  76 + if (val > 65535)
  77 + val = 65535;
  78 + s->cmos_data[0x17] = val;
  79 + s->cmos_data[0x18] = val >> 8;
  80 + s->cmos_data[0x30] = val;
  81 + s->cmos_data[0x31] = val >> 8;
  82 +
  83 + val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
  84 + if (val > 65535)
  85 + val = 65535;
  86 + s->cmos_data[0x34] = val;
  87 + s->cmos_data[0x35] = val >> 8;
  88 +
  89 + switch(boot_device) {
  90 + case 'a':
  91 + case 'b':
  92 + s->cmos_data[0x3d] = 0x01; /* floppy boot */
  93 + break;
  94 + default:
  95 + case 'c':
  96 + s->cmos_data[0x3d] = 0x02; /* hard drive boot */
  97 + break;
  98 + case 'd':
  99 + s->cmos_data[0x3d] = 0x03; /* CD-ROM boot */
  100 + break;
  101 + }
  102 +}
  103 +
  104 +void cmos_register_fd (uint8_t fd0, uint8_t fd1)
  105 +{
  106 + RTCState *s = &rtc_state;
  107 + int nb = 0;
  108 +
  109 + s->cmos_data[0x10] = 0;
  110 + switch (fd0) {
  111 + case 0:
  112 + /* 1.44 Mb 3"5 drive */
  113 + s->cmos_data[0x10] |= 0x40;
  114 + break;
  115 + case 1:
  116 + /* 2.88 Mb 3"5 drive */
  117 + s->cmos_data[0x10] |= 0x60;
  118 + break;
  119 + case 2:
  120 + /* 1.2 Mb 5"5 drive */
  121 + s->cmos_data[0x10] |= 0x20;
  122 + break;
  123 + }
  124 + switch (fd1) {
  125 + case 0:
  126 + /* 1.44 Mb 3"5 drive */
  127 + s->cmos_data[0x10] |= 0x04;
  128 + break;
  129 + case 1:
  130 + /* 2.88 Mb 3"5 drive */
  131 + s->cmos_data[0x10] |= 0x06;
  132 + break;
  133 + case 2:
  134 + /* 1.2 Mb 5"5 drive */
  135 + s->cmos_data[0x10] |= 0x02;
  136 + break;
  137 + }
  138 + if (fd0 < 3)
  139 + nb++;
  140 + if (fd1 < 3)
  141 + nb++;
  142 + switch (nb) {
  143 + case 0:
  144 + break;
  145 + case 1:
  146 + s->cmos_data[REG_EQUIPMENT_BYTE] |= 0x01; /* 1 drive, ready for boot */
  147 + break;
  148 + case 2:
  149 + s->cmos_data[REG_EQUIPMENT_BYTE] |= 0x41; /* 2 drives, ready for boot */
  150 + break;
  151 + }
  152 +}
  153 +
  154 +void speaker_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
  155 +{
  156 + speaker_data_on = (val >> 1) & 1;
  157 + pit_set_gate(&pit_channels[2], val & 1);
  158 +}
  159 +
  160 +uint32_t speaker_ioport_read(CPUState *env, uint32_t addr)
  161 +{
  162 + int out;
  163 + out = pit_get_out(&pit_channels[2]);
  164 + dummy_refresh_clock ^= 1;
  165 + return (speaker_data_on << 1) | pit_channels[2].gate | (out << 5) |
  166 + (dummy_refresh_clock << 4);
  167 +}
  168 +
  169 +/***********************************************************/
  170 +/* PC floppy disk controler emulation glue */
  171 +#define PC_FDC_DMA 0x2
  172 +#define PC_FDC_IRQ 0x6
  173 +#define PC_FDC_BASE 0x3F0
  174 +
  175 +static void fdctrl_register (unsigned char **disknames, int ro,
  176 + char boot_device)
  177 +{
  178 + int i;
  179 +
  180 + fdctrl_init(PC_FDC_IRQ, PC_FDC_DMA, 0, PC_FDC_BASE, boot_device);
  181 + for (i = 0; i < MAX_FD; i++) {
  182 + if (disknames[i] != NULL)
  183 + fdctrl_disk_change(i, disknames[i], ro);
  184 + }
  185 +}
  186 +
  187 +/***********************************************************/
  188 +/* Bochs BIOS debug ports */
  189 +
  190 +void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val)
  191 +{
  192 + switch(addr) {
  193 + /* Bochs BIOS messages */
  194 + case 0x400:
  195 + case 0x401:
  196 + fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
  197 + exit(1);
  198 + case 0x402:
  199 + case 0x403:
  200 +#ifdef DEBUG_BIOS
  201 + fprintf(stderr, "%c", val);
  202 +#endif
  203 + break;
  204 +
  205 + /* LGPL'ed VGA BIOS messages */
  206 + case 0x501:
  207 + case 0x502:
  208 + fprintf(stderr, "VGA BIOS panic, line %d\n", val);
  209 + exit(1);
  210 + case 0x500:
  211 + case 0x503:
  212 +#ifdef DEBUG_BIOS
  213 + fprintf(stderr, "%c", val);
  214 +#endif
  215 + break;
  216 + }
  217 +}
  218 +
  219 +void bochs_bios_init(void)
  220 +{
  221 + register_ioport_write(0x400, 1, bochs_bios_write, 2);
  222 + register_ioport_write(0x401, 1, bochs_bios_write, 2);
  223 + register_ioport_write(0x402, 1, bochs_bios_write, 1);
  224 + register_ioport_write(0x403, 1, bochs_bios_write, 1);
  225 +
  226 + register_ioport_write(0x501, 1, bochs_bios_write, 2);
  227 + register_ioport_write(0x502, 1, bochs_bios_write, 2);
  228 + register_ioport_write(0x500, 1, bochs_bios_write, 1);
  229 + register_ioport_write(0x503, 1, bochs_bios_write, 1);
  230 +}
  231 +
  232 +
  233 +int load_kernel(const char *filename, uint8_t *addr,
  234 + uint8_t *real_addr)
  235 +{
  236 + int fd, size;
  237 + int setup_sects;
  238 +
  239 + fd = open(filename, O_RDONLY);
  240 + if (fd < 0)
  241 + return -1;
  242 +
  243 + /* load 16 bit code */
  244 + if (read(fd, real_addr, 512) != 512)
  245 + goto fail;
  246 + setup_sects = real_addr[0x1F1];
  247 + if (!setup_sects)
  248 + setup_sects = 4;
  249 + if (read(fd, real_addr + 512, setup_sects * 512) !=
  250 + setup_sects * 512)
  251 + goto fail;
  252 +
  253 + /* load 32 bit code */
  254 + size = read(fd, addr, 16 * 1024 * 1024);
  255 + if (size < 0)
  256 + goto fail;
  257 + close(fd);
  258 + return size;
  259 + fail:
  260 + close(fd);
  261 + return -1;
  262 +}
  263 +
  264 +/* PC hardware initialisation */
  265 +void pc_init(int ram_size, int vga_ram_size, int boot_device,
  266 + DisplayState *ds, const char **fd_filename, int snapshot,
  267 + const char *kernel_filename, const char *kernel_cmdline,
  268 + const char *initrd_filename)
  269 +{
  270 + char buf[1024];
  271 + int ret, linux_boot, initrd_size;
  272 +
  273 + linux_boot = (kernel_filename != NULL);
  274 +
  275 + /* allocate RAM */
  276 + cpu_register_physical_memory(0, ram_size, 0);
  277 +
  278 + /* BIOS load */
  279 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  280 + ret = load_image(buf, phys_ram_base + 0x000f0000);
  281 + if (ret != 0x10000) {
  282 + fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
  283 + exit(1);
  284 + }
  285 +
  286 + /* VGA BIOS load */
  287 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
  288 + ret = load_image(buf, phys_ram_base + 0x000c0000);
  289 +
  290 + /* setup basic memory access */
  291 + cpu_register_physical_memory(0xc0000, 0x10000, 0xc0000 | IO_MEM_ROM);
  292 + cpu_register_physical_memory(0xf0000, 0x10000, 0xf0000 | IO_MEM_ROM);
  293 +
  294 + bochs_bios_init();
  295 +
  296 + if (linux_boot) {
  297 + uint8_t bootsect[512];
  298 +
  299 + if (bs_table[0] == NULL) {
  300 + fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n");
  301 + exit(1);
  302 + }
  303 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
  304 + ret = load_image(buf, bootsect);
  305 + if (ret != sizeof(bootsect)) {
  306 + fprintf(stderr, "qemu: could not load linux boot sector '%s'\n",
  307 + buf);
  308 + exit(1);
  309 + }
  310 +
  311 + bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
  312 +
  313 + /* now we can load the kernel */
  314 + ret = load_kernel(kernel_filename,
  315 + phys_ram_base + KERNEL_LOAD_ADDR,
  316 + phys_ram_base + KERNEL_PARAMS_ADDR);
  317 + if (ret < 0) {
  318 + fprintf(stderr, "qemu: could not load kernel '%s'\n",
  319 + kernel_filename);
  320 + exit(1);
  321 + }
  322 +
  323 + /* load initrd */
  324 + initrd_size = 0;
  325 + if (initrd_filename) {
  326 + initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
  327 + if (initrd_size < 0) {
  328 + fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
  329 + initrd_filename);
  330 + exit(1);
  331 + }
  332 + }
  333 + if (initrd_size > 0) {
  334 + stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR);
  335 + stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
  336 + }
  337 + pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
  338 + kernel_cmdline);
  339 + stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
  340 + stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
  341 + KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
  342 + /* loader type */
  343 + stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
  344 + }
  345 +
  346 + /* init basic PC hardware */
  347 + register_ioport_write(0x80, 1, ioport80_write, 1);
  348 +
  349 + vga_initialize(ds, phys_ram_base + ram_size, ram_size,
  350 + vga_ram_size);
  351 +
  352 + rtc_init(0x70, 8);
  353 + cmos_init(ram_size, boot_device);
  354 + register_ioport_read(0x61, 1, speaker_ioport_read, 1);
  355 + register_ioport_write(0x61, 1, speaker_ioport_write, 1);
  356 +
  357 + pic_init();
  358 + pit_init();
  359 + serial_init(0x3f8, 4);
  360 + ne2000_init(0x300, 9);
  361 + ide_init();
  362 + kbd_init();
  363 + AUD_init();
  364 + DMA_init();
  365 + SB16_init();
  366 +
  367 + fdctrl_register((unsigned char **)fd_filename, snapshot, boot_device);
  368 +}
... ...
hw/pckbd.c 0 → 100644
  1 +/*
  2 + * QEMU PC keyboard emulation
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdlib.h>
  25 +#include <stdio.h>
  26 +#include <stdarg.h>
  27 +#include <string.h>
  28 +#include <getopt.h>
  29 +#include <inttypes.h>
  30 +#include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
  34 +#include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +#include <netinet/in.h>
  42 +
  43 +#include "cpu.h"
  44 +#include "vl.h"
  45 +
  46 +/* debug PC keyboard */
  47 +//#define DEBUG_KBD
  48 +
  49 +/* debug PC keyboard : only mouse */
  50 +//#define DEBUG_MOUSE
  51 +
  52 +/* Keyboard Controller Commands */
  53 +#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
  54 +#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
  55 +#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
  56 +#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
  57 +#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
  58 +#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
  59 +#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
  60 +#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
  61 +#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
  62 +#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
  63 +#define KBD_CCMD_READ_INPORT 0xC0 /* read input port */
  64 +#define KBD_CCMD_READ_OUTPORT 0xD0 /* read output port */
  65 +#define KBD_CCMD_WRITE_OUTPORT 0xD1 /* write output port */
  66 +#define KBD_CCMD_WRITE_OBUF 0xD2
  67 +#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
  68 + initiated by the auxiliary device */
  69 +#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
  70 +#define KBD_CCMD_DISABLE_A20 0xDD /* HP vectra only ? */
  71 +#define KBD_CCMD_ENABLE_A20 0xDF /* HP vectra only ? */
  72 +#define KBD_CCMD_RESET 0xFE
  73 +
  74 +/* Keyboard Commands */
  75 +#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
  76 +#define KBD_CMD_ECHO 0xEE
  77 +#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
  78 +#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
  79 +#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
  80 +#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
  81 +#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
  82 +#define KBD_CMD_RESET 0xFF /* Reset */
  83 +
  84 +/* Keyboard Replies */
  85 +#define KBD_REPLY_POR 0xAA /* Power on reset */
  86 +#define KBD_REPLY_ACK 0xFA /* Command ACK */
  87 +#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
  88 +
  89 +/* Status Register Bits */
  90 +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
  91 +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
  92 +#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
  93 +#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
  94 +#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
  95 +#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
  96 +#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
  97 +#define KBD_STAT_PERR 0x80 /* Parity error */
  98 +
  99 +/* Controller Mode Register Bits */
  100 +#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
  101 +#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
  102 +#define KBD_MODE_SYS 0x04 /* The system flag (?) */
  103 +#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
  104 +#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
  105 +#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
  106 +#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
  107 +#define KBD_MODE_RFU 0x80
  108 +
  109 +/* Mouse Commands */
  110 +#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
  111 +#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
  112 +#define AUX_SET_RES 0xE8 /* Set resolution */
  113 +#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
  114 +#define AUX_SET_STREAM 0xEA /* Set stream mode */
  115 +#define AUX_POLL 0xEB /* Poll */
  116 +#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
  117 +#define AUX_SET_WRAP 0xEE /* Set wrap mode */
  118 +#define AUX_SET_REMOTE 0xF0 /* Set remote mode */
  119 +#define AUX_GET_TYPE 0xF2 /* Get type */
  120 +#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
  121 +#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
  122 +#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
  123 +#define AUX_SET_DEFAULT 0xF6
  124 +#define AUX_RESET 0xFF /* Reset aux device */
  125 +#define AUX_ACK 0xFA /* Command byte ACK. */
  126 +
  127 +#define MOUSE_STATUS_REMOTE 0x40
  128 +#define MOUSE_STATUS_ENABLED 0x20
  129 +#define MOUSE_STATUS_SCALE21 0x10
  130 +
  131 +#define KBD_QUEUE_SIZE 256
  132 +
  133 +typedef struct {
  134 + uint8_t data[KBD_QUEUE_SIZE];
  135 + int rptr, wptr, count;
  136 +} KBDQueue;
  137 +
  138 +typedef struct KBDState {
  139 + KBDQueue queues[2];
  140 + uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
  141 + uint8_t status;
  142 + uint8_t mode;
  143 + /* keyboard state */
  144 + int kbd_write_cmd;
  145 + int scan_enabled;
  146 + /* mouse state */
  147 + int mouse_write_cmd;
  148 + uint8_t mouse_status;
  149 + uint8_t mouse_resolution;
  150 + uint8_t mouse_sample_rate;
  151 + uint8_t mouse_wrap;
  152 + uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
  153 + uint8_t mouse_detect_state;
  154 + int mouse_dx; /* current values, needed for 'poll' mode */
  155 + int mouse_dy;
  156 + int mouse_dz;
  157 + uint8_t mouse_buttons;
  158 +} KBDState;
  159 +
  160 +KBDState kbd_state;
  161 +int reset_requested;
  162 +
  163 +/* update irq and KBD_STAT_[MOUSE_]OBF */
  164 +/* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
  165 + incorrect, but it avoids having to simulate exact delays */
  166 +static void kbd_update_irq(KBDState *s)
  167 +{
  168 + int irq12_level, irq1_level;
  169 +
  170 + irq1_level = 0;
  171 + irq12_level = 0;
  172 + s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
  173 + if (s->queues[0].count != 0 ||
  174 + s->queues[1].count != 0) {
  175 + s->status |= KBD_STAT_OBF;
  176 + if (s->queues[1].count != 0) {
  177 + s->status |= KBD_STAT_MOUSE_OBF;
  178 + if (s->mode & KBD_MODE_MOUSE_INT)
  179 + irq12_level = 1;
  180 + } else {
  181 + if ((s->mode & KBD_MODE_KBD_INT) &&
  182 + !(s->mode & KBD_MODE_DISABLE_KBD))
  183 + irq1_level = 1;
  184 + }
  185 + }
  186 + pic_set_irq(1, irq1_level);
  187 + pic_set_irq(12, irq12_level);
  188 +}
  189 +
  190 +static void kbd_queue(KBDState *s, int b, int aux)
  191 +{
  192 + KBDQueue *q = &kbd_state.queues[aux];
  193 +
  194 +#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
  195 + if (aux)
  196 + printf("mouse event: 0x%02x\n", b);
  197 +#ifdef DEBUG_KBD
  198 + else
  199 + printf("kbd event: 0x%02x\n", b);
  200 +#endif
  201 +#endif
  202 + if (q->count >= KBD_QUEUE_SIZE)
  203 + return;
  204 + q->data[q->wptr] = b;
  205 + if (++q->wptr == KBD_QUEUE_SIZE)
  206 + q->wptr = 0;
  207 + q->count++;
  208 + kbd_update_irq(s);
  209 +}
  210 +
  211 +void kbd_put_keycode(int keycode)
  212 +{
  213 + KBDState *s = &kbd_state;
  214 + kbd_queue(s, keycode, 0);
  215 +}
  216 +
  217 +static uint32_t kbd_read_status(CPUState *env, uint32_t addr)
  218 +{
  219 + KBDState *s = &kbd_state;
  220 + int val;
  221 + val = s->status;
  222 +#if defined(DEBUG_KBD)
  223 + printf("kbd: read status=0x%02x\n", val);
  224 +#endif
  225 + return val;
  226 +}
  227 +
  228 +static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val)
  229 +{
  230 + KBDState *s = &kbd_state;
  231 +
  232 +#ifdef DEBUG_KBD
  233 + printf("kbd: write cmd=0x%02x\n", val);
  234 +#endif
  235 + switch(val) {
  236 + case KBD_CCMD_READ_MODE:
  237 + kbd_queue(s, s->mode, 0);
  238 + break;
  239 + case KBD_CCMD_WRITE_MODE:
  240 + case KBD_CCMD_WRITE_OBUF:
  241 + case KBD_CCMD_WRITE_AUX_OBUF:
  242 + case KBD_CCMD_WRITE_MOUSE:
  243 + case KBD_CCMD_WRITE_OUTPORT:
  244 + s->write_cmd = val;
  245 + break;
  246 + case KBD_CCMD_MOUSE_DISABLE:
  247 + s->mode |= KBD_MODE_DISABLE_MOUSE;
  248 + break;
  249 + case KBD_CCMD_MOUSE_ENABLE:
  250 + s->mode &= ~KBD_MODE_DISABLE_MOUSE;
  251 + break;
  252 + case KBD_CCMD_TEST_MOUSE:
  253 + kbd_queue(s, 0x00, 0);
  254 + break;
  255 + case KBD_CCMD_SELF_TEST:
  256 + s->status |= KBD_STAT_SELFTEST;
  257 + kbd_queue(s, 0x55, 0);
  258 + break;
  259 + case KBD_CCMD_KBD_TEST:
  260 + kbd_queue(s, 0x00, 0);
  261 + break;
  262 + case KBD_CCMD_KBD_DISABLE:
  263 + s->mode |= KBD_MODE_DISABLE_KBD;
  264 + kbd_update_irq(s);
  265 + break;
  266 + case KBD_CCMD_KBD_ENABLE:
  267 + s->mode &= ~KBD_MODE_DISABLE_KBD;
  268 + kbd_update_irq(s);
  269 + break;
  270 + case KBD_CCMD_READ_INPORT:
  271 + kbd_queue(s, 0x00, 0);
  272 + break;
  273 + case KBD_CCMD_READ_OUTPORT:
  274 + /* XXX: check that */
  275 +#ifdef TARGET_I386
  276 + val = 0x01 | (((cpu_single_env->a20_mask >> 20) & 1) << 1);
  277 +#else
  278 + val = 0x01;
  279 +#endif
  280 + if (s->status & KBD_STAT_OBF)
  281 + val |= 0x10;
  282 + if (s->status & KBD_STAT_MOUSE_OBF)
  283 + val |= 0x20;
  284 + kbd_queue(s, val, 0);
  285 + break;
  286 +#ifdef TARGET_I386
  287 + case KBD_CCMD_ENABLE_A20:
  288 + cpu_x86_set_a20(env, 1);
  289 + break;
  290 + case KBD_CCMD_DISABLE_A20:
  291 + cpu_x86_set_a20(env, 0);
  292 + break;
  293 +#endif
  294 + case KBD_CCMD_RESET:
  295 + reset_requested = 1;
  296 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
  297 + break;
  298 + case 0xff:
  299 + /* ignore that - I don't know what is its use */
  300 + break;
  301 + default:
  302 + fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val);
  303 + break;
  304 + }
  305 +}
  306 +
  307 +static uint32_t kbd_read_data(CPUState *env, uint32_t addr)
  308 +{
  309 + KBDState *s = &kbd_state;
  310 + KBDQueue *q;
  311 + int val, index;
  312 +
  313 + q = &s->queues[0]; /* first check KBD data */
  314 + if (q->count == 0)
  315 + q = &s->queues[1]; /* then check AUX data */
  316 + if (q->count == 0) {
  317 + /* NOTE: if no data left, we return the last keyboard one
  318 + (needed for EMM386) */
  319 + /* XXX: need a timer to do things correctly */
  320 + q = &s->queues[0];
  321 + index = q->rptr - 1;
  322 + if (index < 0)
  323 + index = KBD_QUEUE_SIZE - 1;
  324 + val = q->data[index];
  325 + } else {
  326 + val = q->data[q->rptr];
  327 + if (++q->rptr == KBD_QUEUE_SIZE)
  328 + q->rptr = 0;
  329 + q->count--;
  330 + /* reading deasserts IRQ */
  331 + if (q == &s->queues[0])
  332 + pic_set_irq(1, 0);
  333 + else
  334 + pic_set_irq(12, 0);
  335 + }
  336 + /* reassert IRQs if data left */
  337 + kbd_update_irq(s);
  338 +#ifdef DEBUG_KBD
  339 + printf("kbd: read data=0x%02x\n", val);
  340 +#endif
  341 + return val;
  342 +}
  343 +
  344 +static void kbd_reset_keyboard(KBDState *s)
  345 +{
  346 + s->scan_enabled = 1;
  347 +}
  348 +
  349 +static void kbd_write_keyboard(KBDState *s, int val)
  350 +{
  351 + switch(s->kbd_write_cmd) {
  352 + default:
  353 + case -1:
  354 + switch(val) {
  355 + case 0x00:
  356 + kbd_queue(s, KBD_REPLY_ACK, 0);
  357 + break;
  358 + case 0x05:
  359 + kbd_queue(s, KBD_REPLY_RESEND, 0);
  360 + break;
  361 + case KBD_CMD_GET_ID:
  362 + kbd_queue(s, KBD_REPLY_ACK, 0);
  363 + kbd_queue(s, 0xab, 0);
  364 + kbd_queue(s, 0x83, 0);
  365 + break;
  366 + case KBD_CMD_ECHO:
  367 + kbd_queue(s, KBD_CMD_ECHO, 0);
  368 + break;
  369 + case KBD_CMD_ENABLE:
  370 + s->scan_enabled = 1;
  371 + kbd_queue(s, KBD_REPLY_ACK, 0);
  372 + break;
  373 + case KBD_CMD_SET_LEDS:
  374 + case KBD_CMD_SET_RATE:
  375 + s->kbd_write_cmd = val;
  376 + kbd_queue(s, KBD_REPLY_ACK, 0);
  377 + break;
  378 + case KBD_CMD_RESET_DISABLE:
  379 + kbd_reset_keyboard(s);
  380 + s->scan_enabled = 0;
  381 + kbd_queue(s, KBD_REPLY_ACK, 0);
  382 + break;
  383 + case KBD_CMD_RESET_ENABLE:
  384 + kbd_reset_keyboard(s);
  385 + s->scan_enabled = 1;
  386 + kbd_queue(s, KBD_REPLY_ACK, 0);
  387 + break;
  388 + case KBD_CMD_RESET:
  389 + kbd_reset_keyboard(s);
  390 + kbd_queue(s, KBD_REPLY_ACK, 0);
  391 + kbd_queue(s, KBD_REPLY_POR, 0);
  392 + break;
  393 + default:
  394 + kbd_queue(s, KBD_REPLY_ACK, 0);
  395 + break;
  396 + }
  397 + break;
  398 + case KBD_CMD_SET_LEDS:
  399 + kbd_queue(s, KBD_REPLY_ACK, 0);
  400 + s->kbd_write_cmd = -1;
  401 + break;
  402 + case KBD_CMD_SET_RATE:
  403 + kbd_queue(s, KBD_REPLY_ACK, 0);
  404 + s->kbd_write_cmd = -1;
  405 + break;
  406 + }
  407 +}
  408 +
  409 +static void kbd_mouse_send_packet(KBDState *s)
  410 +{
  411 + unsigned int b;
  412 + int dx1, dy1, dz1;
  413 +
  414 + dx1 = s->mouse_dx;
  415 + dy1 = s->mouse_dy;
  416 + dz1 = s->mouse_dz;
  417 + /* XXX: increase range to 8 bits ? */
  418 + if (dx1 > 127)
  419 + dx1 = 127;
  420 + else if (dx1 < -127)
  421 + dx1 = -127;
  422 + if (dy1 > 127)
  423 + dy1 = 127;
  424 + else if (dy1 < -127)
  425 + dy1 = -127;
  426 + b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
  427 + kbd_queue(s, b, 1);
  428 + kbd_queue(s, dx1 & 0xff, 1);
  429 + kbd_queue(s, dy1 & 0xff, 1);
  430 + /* extra byte for IMPS/2 or IMEX */
  431 + switch(s->mouse_type) {
  432 + default:
  433 + break;
  434 + case 3:
  435 + if (dz1 > 127)
  436 + dz1 = 127;
  437 + else if (dz1 < -127)
  438 + dz1 = -127;
  439 + kbd_queue(s, dz1 & 0xff, 1);
  440 + break;
  441 + case 4:
  442 + if (dz1 > 7)
  443 + dz1 = 7;
  444 + else if (dz1 < -7)
  445 + dz1 = -7;
  446 + b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
  447 + kbd_queue(s, b, 1);
  448 + break;
  449 + }
  450 +
  451 + /* update deltas */
  452 + s->mouse_dx -= dx1;
  453 + s->mouse_dy -= dy1;
  454 + s->mouse_dz -= dz1;
  455 +}
  456 +
  457 +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
  458 +{
  459 + KBDState *s = &kbd_state;
  460 +
  461 + /* check if deltas are recorded when disabled */
  462 + if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
  463 + return;
  464 +
  465 + s->mouse_dx += dx;
  466 + s->mouse_dy -= dy;
  467 + s->mouse_dz += dz;
  468 + s->mouse_buttons = buttons_state;
  469 +
  470 + if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
  471 + (s->queues[1].count < (KBD_QUEUE_SIZE - 16))) {
  472 + for(;;) {
  473 + /* if not remote, send event. Multiple events are sent if
  474 + too big deltas */
  475 + kbd_mouse_send_packet(s);
  476 + if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
  477 + break;
  478 + }
  479 + }
  480 +}
  481 +
  482 +static void kbd_write_mouse(KBDState *s, int val)
  483 +{
  484 +#ifdef DEBUG_MOUSE
  485 + printf("kbd: write mouse 0x%02x\n", val);
  486 +#endif
  487 + switch(s->mouse_write_cmd) {
  488 + default:
  489 + case -1:
  490 + /* mouse command */
  491 + if (s->mouse_wrap) {
  492 + if (val == AUX_RESET_WRAP) {
  493 + s->mouse_wrap = 0;
  494 + kbd_queue(s, AUX_ACK, 1);
  495 + return;
  496 + } else if (val != AUX_RESET) {
  497 + kbd_queue(s, val, 1);
  498 + return;
  499 + }
  500 + }
  501 + switch(val) {
  502 + case AUX_SET_SCALE11:
  503 + s->mouse_status &= ~MOUSE_STATUS_SCALE21;
  504 + kbd_queue(s, AUX_ACK, 1);
  505 + break;
  506 + case AUX_SET_SCALE21:
  507 + s->mouse_status |= MOUSE_STATUS_SCALE21;
  508 + kbd_queue(s, AUX_ACK, 1);
  509 + break;
  510 + case AUX_SET_STREAM:
  511 + s->mouse_status &= ~MOUSE_STATUS_REMOTE;
  512 + kbd_queue(s, AUX_ACK, 1);
  513 + break;
  514 + case AUX_SET_WRAP:
  515 + s->mouse_wrap = 1;
  516 + kbd_queue(s, AUX_ACK, 1);
  517 + break;
  518 + case AUX_SET_REMOTE:
  519 + s->mouse_status |= MOUSE_STATUS_REMOTE;
  520 + kbd_queue(s, AUX_ACK, 1);
  521 + break;
  522 + case AUX_GET_TYPE:
  523 + kbd_queue(s, AUX_ACK, 1);
  524 + kbd_queue(s, s->mouse_type, 1);
  525 + break;
  526 + case AUX_SET_RES:
  527 + case AUX_SET_SAMPLE:
  528 + s->mouse_write_cmd = val;
  529 + kbd_queue(s, AUX_ACK, 1);
  530 + break;
  531 + case AUX_GET_SCALE:
  532 + kbd_queue(s, AUX_ACK, 1);
  533 + kbd_queue(s, s->mouse_status, 1);
  534 + kbd_queue(s, s->mouse_resolution, 1);
  535 + kbd_queue(s, s->mouse_sample_rate, 1);
  536 + break;
  537 + case AUX_POLL:
  538 + kbd_queue(s, AUX_ACK, 1);
  539 + kbd_mouse_send_packet(s);
  540 + break;
  541 + case AUX_ENABLE_DEV:
  542 + s->mouse_status |= MOUSE_STATUS_ENABLED;
  543 + kbd_queue(s, AUX_ACK, 1);
  544 + break;
  545 + case AUX_DISABLE_DEV:
  546 + s->mouse_status &= ~MOUSE_STATUS_ENABLED;
  547 + kbd_queue(s, AUX_ACK, 1);
  548 + break;
  549 + case AUX_SET_DEFAULT:
  550 + s->mouse_sample_rate = 100;
  551 + s->mouse_resolution = 2;
  552 + s->mouse_status = 0;
  553 + kbd_queue(s, AUX_ACK, 1);
  554 + break;
  555 + case AUX_RESET:
  556 + s->mouse_sample_rate = 100;
  557 + s->mouse_resolution = 2;
  558 + s->mouse_status = 0;
  559 + kbd_queue(s, AUX_ACK, 1);
  560 + kbd_queue(s, 0xaa, 1);
  561 + kbd_queue(s, s->mouse_type, 1);
  562 + break;
  563 + default:
  564 + break;
  565 + }
  566 + break;
  567 + case AUX_SET_SAMPLE:
  568 + s->mouse_sample_rate = val;
  569 +#if 0
  570 + /* detect IMPS/2 or IMEX */
  571 + switch(s->mouse_detect_state) {
  572 + default:
  573 + case 0:
  574 + if (val == 200)
  575 + s->mouse_detect_state = 1;
  576 + break;
  577 + case 1:
  578 + if (val == 100)
  579 + s->mouse_detect_state = 2;
  580 + else if (val == 200)
  581 + s->mouse_detect_state = 3;
  582 + else
  583 + s->mouse_detect_state = 0;
  584 + break;
  585 + case 2:
  586 + if (val == 80)
  587 + s->mouse_type = 3; /* IMPS/2 */
  588 + s->mouse_detect_state = 0;
  589 + break;
  590 + case 3:
  591 + if (val == 80)
  592 + s->mouse_type = 4; /* IMEX */
  593 + s->mouse_detect_state = 0;
  594 + break;
  595 + }
  596 +#endif
  597 + kbd_queue(s, AUX_ACK, 1);
  598 + s->mouse_write_cmd = -1;
  599 + break;
  600 + case AUX_SET_RES:
  601 + s->mouse_resolution = val;
  602 + kbd_queue(s, AUX_ACK, 1);
  603 + s->mouse_write_cmd = -1;
  604 + break;
  605 + }
  606 +}
  607 +
  608 +void kbd_write_data(CPUState *env, uint32_t addr, uint32_t val)
  609 +{
  610 + KBDState *s = &kbd_state;
  611 +
  612 +#ifdef DEBUG_KBD
  613 + printf("kbd: write data=0x%02x\n", val);
  614 +#endif
  615 +
  616 + switch(s->write_cmd) {
  617 + case 0:
  618 + kbd_write_keyboard(s, val);
  619 + break;
  620 + case KBD_CCMD_WRITE_MODE:
  621 + s->mode = val;
  622 + kbd_update_irq(s);
  623 + break;
  624 + case KBD_CCMD_WRITE_OBUF:
  625 + kbd_queue(s, val, 0);
  626 + break;
  627 + case KBD_CCMD_WRITE_AUX_OBUF:
  628 + kbd_queue(s, val, 1);
  629 + break;
  630 + case KBD_CCMD_WRITE_OUTPORT:
  631 +#ifdef TARGET_I386
  632 + cpu_x86_set_a20(env, (val >> 1) & 1);
  633 +#endif
  634 + if (!(val & 1)) {
  635 + reset_requested = 1;
  636 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
  637 + }
  638 + break;
  639 + case KBD_CCMD_WRITE_MOUSE:
  640 + kbd_write_mouse(s, val);
  641 + break;
  642 + default:
  643 + break;
  644 + }
  645 + s->write_cmd = 0;
  646 +}
  647 +
  648 +void kbd_reset(KBDState *s)
  649 +{
  650 + KBDQueue *q;
  651 + int i;
  652 +
  653 + s->kbd_write_cmd = -1;
  654 + s->mouse_write_cmd = -1;
  655 + s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
  656 + s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
  657 + for(i = 0; i < 2; i++) {
  658 + q = &s->queues[i];
  659 + q->rptr = 0;
  660 + q->wptr = 0;
  661 + q->count = 0;
  662 + }
  663 +}
  664 +
  665 +void kbd_init(void)
  666 +{
  667 + kbd_reset(&kbd_state);
  668 + register_ioport_read(0x60, 1, kbd_read_data, 1);
  669 + register_ioport_write(0x60, 1, kbd_write_data, 1);
  670 + register_ioport_read(0x64, 1, kbd_read_status, 1);
  671 + register_ioport_write(0x64, 1, kbd_write_command, 1);
  672 +}
... ...
hw/serial.c 0 → 100644
  1 +/*
  2 + * QEMU 16450 UART emulation
  3 + *
  4 + * Copyright (c) 2003-2004 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdlib.h>
  25 +#include <stdio.h>
  26 +#include <stdarg.h>
  27 +#include <string.h>
  28 +#include <getopt.h>
  29 +#include <inttypes.h>
  30 +#include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
  34 +#include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +#include <netinet/in.h>
  42 +
  43 +#include "cpu.h"
  44 +#include "vl.h"
  45 +
  46 +//#define DEBUG_SERIAL
  47 +
  48 +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
  49 +
  50 +#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
  51 +#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
  52 +#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
  53 +#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
  54 +
  55 +#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
  56 +#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
  57 +
  58 +#define UART_IIR_MSI 0x00 /* Modem status interrupt */
  59 +#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
  60 +#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
  61 +#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
  62 +
  63 +/*
  64 + * These are the definitions for the Modem Control Register
  65 + */
  66 +#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
  67 +#define UART_MCR_OUT2 0x08 /* Out2 complement */
  68 +#define UART_MCR_OUT1 0x04 /* Out1 complement */
  69 +#define UART_MCR_RTS 0x02 /* RTS complement */
  70 +#define UART_MCR_DTR 0x01 /* DTR complement */
  71 +
  72 +/*
  73 + * These are the definitions for the Modem Status Register
  74 + */
  75 +#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
  76 +#define UART_MSR_RI 0x40 /* Ring Indicator */
  77 +#define UART_MSR_DSR 0x20 /* Data Set Ready */
  78 +#define UART_MSR_CTS 0x10 /* Clear to Send */
  79 +#define UART_MSR_DDCD 0x08 /* Delta DCD */
  80 +#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
  81 +#define UART_MSR_DDSR 0x02 /* Delta DSR */
  82 +#define UART_MSR_DCTS 0x01 /* Delta CTS */
  83 +#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
  84 +
  85 +#define UART_LSR_TEMT 0x40 /* Transmitter empty */
  86 +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
  87 +#define UART_LSR_BI 0x10 /* Break interrupt indicator */
  88 +#define UART_LSR_FE 0x08 /* Frame error indicator */
  89 +#define UART_LSR_PE 0x04 /* Parity error indicator */
  90 +#define UART_LSR_OE 0x02 /* Overrun error indicator */
  91 +#define UART_LSR_DR 0x01 /* Receiver data ready */
  92 +
  93 +typedef struct SerialState {
  94 + uint8_t divider;
  95 + uint8_t rbr; /* receive register */
  96 + uint8_t ier;
  97 + uint8_t iir; /* read only */
  98 + uint8_t lcr;
  99 + uint8_t mcr;
  100 + uint8_t lsr; /* read only */
  101 + uint8_t msr;
  102 + uint8_t scr;
  103 + /* NOTE: this hidden state is necessary for tx irq generation as
  104 + it can be reset while reading iir */
  105 + int thr_ipending;
  106 + int irq;
  107 +} SerialState;
  108 +
  109 +SerialState serial_ports[1];
  110 +
  111 +void serial_update_irq(void)
  112 +{
  113 + SerialState *s = &serial_ports[0];
  114 +
  115 + if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
  116 + s->iir = UART_IIR_RDI;
  117 + } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
  118 + s->iir = UART_IIR_THRI;
  119 + } else {
  120 + s->iir = UART_IIR_NO_INT;
  121 + }
  122 + if (s->iir != UART_IIR_NO_INT) {
  123 + pic_set_irq(s->irq, 1);
  124 + } else {
  125 + pic_set_irq(s->irq, 0);
  126 + }
  127 +}
  128 +
  129 +void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
  130 +{
  131 + SerialState *s = &serial_ports[0];
  132 + unsigned char ch;
  133 + int ret;
  134 +
  135 + addr &= 7;
  136 +#ifdef DEBUG_SERIAL
  137 + printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
  138 +#endif
  139 + switch(addr) {
  140 + default:
  141 + case 0:
  142 + if (s->lcr & UART_LCR_DLAB) {
  143 + s->divider = (s->divider & 0xff00) | val;
  144 + } else {
  145 + s->thr_ipending = 0;
  146 + s->lsr &= ~UART_LSR_THRE;
  147 + serial_update_irq();
  148 +
  149 + ch = val;
  150 + do {
  151 + ret = write(1, &ch, 1);
  152 + } while (ret != 1);
  153 + s->thr_ipending = 1;
  154 + s->lsr |= UART_LSR_THRE;
  155 + s->lsr |= UART_LSR_TEMT;
  156 + serial_update_irq();
  157 + }
  158 + break;
  159 + case 1:
  160 + if (s->lcr & UART_LCR_DLAB) {
  161 + s->divider = (s->divider & 0x00ff) | (val << 8);
  162 + } else {
  163 + s->ier = val;
  164 + serial_update_irq();
  165 + }
  166 + break;
  167 + case 2:
  168 + break;
  169 + case 3:
  170 + s->lcr = val;
  171 + break;
  172 + case 4:
  173 + s->mcr = val;
  174 + break;
  175 + case 5:
  176 + break;
  177 + case 6:
  178 + s->msr = val;
  179 + break;
  180 + case 7:
  181 + s->scr = val;
  182 + break;
  183 + }
  184 +}
  185 +
  186 +uint32_t serial_ioport_read(CPUState *env, uint32_t addr)
  187 +{
  188 + SerialState *s = &serial_ports[0];
  189 + uint32_t ret;
  190 +
  191 + addr &= 7;
  192 + switch(addr) {
  193 + default:
  194 + case 0:
  195 + if (s->lcr & UART_LCR_DLAB) {
  196 + ret = s->divider & 0xff;
  197 + } else {
  198 + ret = s->rbr;
  199 + s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
  200 + serial_update_irq();
  201 + }
  202 + break;
  203 + case 1:
  204 + if (s->lcr & UART_LCR_DLAB) {
  205 + ret = (s->divider >> 8) & 0xff;
  206 + } else {
  207 + ret = s->ier;
  208 + }
  209 + break;
  210 + case 2:
  211 + ret = s->iir;
  212 + /* reset THR pending bit */
  213 + if ((ret & 0x7) == UART_IIR_THRI)
  214 + s->thr_ipending = 0;
  215 + serial_update_irq();
  216 + break;
  217 + case 3:
  218 + ret = s->lcr;
  219 + break;
  220 + case 4:
  221 + ret = s->mcr;
  222 + break;
  223 + case 5:
  224 + ret = s->lsr;
  225 + break;
  226 + case 6:
  227 + if (s->mcr & UART_MCR_LOOP) {
  228 + /* in loopback, the modem output pins are connected to the
  229 + inputs */
  230 + ret = (s->mcr & 0x0c) << 4;
  231 + ret |= (s->mcr & 0x02) << 3;
  232 + ret |= (s->mcr & 0x01) << 5;
  233 + } else {
  234 + ret = s->msr;
  235 + }
  236 + break;
  237 + case 7:
  238 + ret = s->scr;
  239 + break;
  240 + }
  241 +#ifdef DEBUG_SERIAL
  242 + printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
  243 +#endif
  244 + return ret;
  245 +}
  246 +
  247 +int serial_can_receive(void)
  248 +{
  249 + SerialState *s = &serial_ports[0];
  250 + return !(s->lsr & UART_LSR_DR);
  251 +}
  252 +
  253 +void serial_receive_byte(int ch)
  254 +{
  255 + SerialState *s = &serial_ports[0];
  256 +
  257 + s->rbr = ch;
  258 + s->lsr |= UART_LSR_DR;
  259 + serial_update_irq();
  260 +}
  261 +
  262 +void serial_receive_break(void)
  263 +{
  264 + SerialState *s = &serial_ports[0];
  265 +
  266 + s->rbr = 0;
  267 + s->lsr |= UART_LSR_BI | UART_LSR_DR;
  268 + serial_update_irq();
  269 +}
  270 +
  271 +void serial_init(int base, int irq)
  272 +{
  273 + SerialState *s = &serial_ports[0];
  274 +
  275 + s->irq = irq;
  276 + s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
  277 + s->iir = UART_IIR_NO_INT;
  278 +
  279 + register_ioport_write(base, 8, serial_ioport_write, 1);
  280 + register_ioport_read(base, 8, serial_ioport_read, 1);
  281 +}
... ...
1 1 /*
2   - * QEMU PC System Emulator
  2 + * QEMU System Emulator
3 3 *
4   - * Copyright (c) 2003 Fabrice Bellard
  4 + * Copyright (c) 2003-2004 Fabrice Bellard
5 5 *
6 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7 * of this software and associated documentation files (the "Software"), to deal
... ... @@ -51,33 +51,9 @@
51 51 #include "vl.h"
52 52  
53 53 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
54   -#define BIOS_FILENAME "bios.bin"
55   -#define VGABIOS_FILENAME "vgabios.bin"
56   -#define LINUX_BOOT_FILENAME "linux_boot.bin"
57 54  
58 55 //#define DEBUG_UNUSED_IOPORT
59 56  
60   -//#define DEBUG_IRQ_LATENCY
61   -
62   -/* output Bochs bios info messages */
63   -//#define DEBUG_BIOS
64   -
65   -//#define DEBUG_CMOS
66   -
67   -/* debug PIC */
68   -//#define DEBUG_PIC
69   -
70   -/* debug NE2000 card */
71   -//#define DEBUG_NE2000
72   -
73   -/* debug PC keyboard */
74   -//#define DEBUG_KBD
75   -
76   -/* debug PC keyboard : only mouse */
77   -//#define DEBUG_MOUSE
78   -
79   -//#define DEBUG_SERIAL
80   -
81 57 #if !defined(CONFIG_SOFTMMU)
82 58 #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
83 59 #else
... ... @@ -85,7 +61,6 @@
85 61 #endif
86 62  
87 63 #if defined (TARGET_I386)
88   -#define KERNEL_LOAD_ADDR 0x00100000
89 64 #elif defined (TARGET_PPC)
90 65 //#define USE_OPEN_FIRMWARE
91 66 #if !defined (USE_OPEN_FIRMWARE)
... ... @@ -96,16 +71,13 @@
96 71 #define KERNEL_STACK_ADDR 0x00400000
97 72 #endif
98 73 #endif
99   -#define INITRD_LOAD_ADDR 0x00400000
100   -#define KERNEL_PARAMS_ADDR 0x00090000
101   -#define KERNEL_CMDLINE_ADDR 0x00099000
102 74  
103 75 #define GUI_REFRESH_INTERVAL 30
104 76  
105 77 /* XXX: use a two level table to limit memory usage */
106 78 #define MAX_IOPORTS 65536
107 79  
108   -static const char *bios_dir = CONFIG_QEMU_SHAREDIR;
  80 +const char *bios_dir = CONFIG_QEMU_SHAREDIR;
109 81 char phys_ram_file[1024];
110 82 CPUState *global_env;
111 83 CPUState *cpu_single_env;
... ... @@ -119,6 +91,8 @@ int term_inited;
119 91 int64_t ticks_per_sec;
120 92 int boot_device = 'c';
121 93 static int ram_size;
  94 +static char network_script[1024];
  95 +int pit_min_timer_count = 0;
122 96  
123 97 /***********************************************************/
124 98 /* x86 io ports */
... ... @@ -245,39 +219,6 @@ char *pstrcat(char *buf, int buf_size, const char *s)
245 219 return buf;
246 220 }
247 221  
248   -#if defined (TARGET_I386)
249   -int load_kernel(const char *filename, uint8_t *addr,
250   - uint8_t *real_addr)
251   -{
252   - int fd, size;
253   - int setup_sects;
254   -
255   - fd = open(filename, O_RDONLY);
256   - if (fd < 0)
257   - return -1;
258   -
259   - /* load 16 bit code */
260   - if (read(fd, real_addr, 512) != 512)
261   - goto fail;
262   - setup_sects = real_addr[0x1F1];
263   - if (!setup_sects)
264   - setup_sects = 4;
265   - if (read(fd, real_addr + 512, setup_sects * 512) !=
266   - setup_sects * 512)
267   - goto fail;
268   -
269   - /* load 32 bit code */
270   - size = read(fd, addr, 16 * 1024 * 1024);
271   - if (size < 0)
272   - goto fail;
273   - close(fd);
274   - return size;
275   - fail:
276   - close(fd);
277   - return -1;
278   -}
279   -#endif
280   -
281 222 /* return the size or -1 if error */
282 223 int load_image(const char *filename, uint8_t *addr)
283 224 {
... ... @@ -326,10 +267,6 @@ int cpu_inl(CPUState *env, int addr)
326 267 }
327 268  
328 269 /***********************************************************/
329   -void ioport80_write(CPUState *env, uint32_t addr, uint32_t data)
330   -{
331   -}
332   -
333 270 void hw_error(const char *fmt, ...)
334 271 {
335 272 va_list ap;
... ... @@ -347,613 +284,6 @@ void hw_error(const char *fmt, ...)
347 284 abort();
348 285 }
349 286  
350   -/***********************************************************/
351   -/* cmos emulation */
352   -
353   -#if defined (TARGET_I386)
354   -#define RTC_SECONDS 0
355   -#define RTC_SECONDS_ALARM 1
356   -#define RTC_MINUTES 2
357   -#define RTC_MINUTES_ALARM 3
358   -#define RTC_HOURS 4
359   -#define RTC_HOURS_ALARM 5
360   -#define RTC_ALARM_DONT_CARE 0xC0
361   -
362   -#define RTC_DAY_OF_WEEK 6
363   -#define RTC_DAY_OF_MONTH 7
364   -#define RTC_MONTH 8
365   -#define RTC_YEAR 9
366   -
367   -#define RTC_REG_A 10
368   -#define RTC_REG_B 11
369   -#define RTC_REG_C 12
370   -#define RTC_REG_D 13
371   -
372   -/* PC cmos mappings */
373   -#define REG_EQUIPMENT_BYTE 0x14
374   -#define REG_IBM_CENTURY_BYTE 0x32
375   -#define REG_IBM_PS2_CENTURY_BYTE 0x37
376   -
377   -uint8_t cmos_data[128];
378   -uint8_t cmos_index;
379   -
380   -void cmos_ioport_write(CPUState *env, uint32_t addr, uint32_t data)
381   -{
382   - if (addr == 0x70) {
383   - cmos_index = data & 0x7f;
384   - } else {
385   -#ifdef DEBUG_CMOS
386   - printf("cmos: write index=0x%02x val=0x%02x\n",
387   - cmos_index, data);
388   -#endif
389   - switch(addr) {
390   - case RTC_SECONDS_ALARM:
391   - case RTC_MINUTES_ALARM:
392   - case RTC_HOURS_ALARM:
393   - /* XXX: not supported */
394   - cmos_data[cmos_index] = data;
395   - break;
396   - case RTC_SECONDS:
397   - case RTC_MINUTES:
398   - case RTC_HOURS:
399   - case RTC_DAY_OF_WEEK:
400   - case RTC_DAY_OF_MONTH:
401   - case RTC_MONTH:
402   - case RTC_YEAR:
403   - cmos_data[cmos_index] = data;
404   - break;
405   - case RTC_REG_A:
406   - case RTC_REG_B:
407   - cmos_data[cmos_index] = data;
408   - break;
409   - case RTC_REG_C:
410   - case RTC_REG_D:
411   - /* cannot write to them */
412   - break;
413   - default:
414   - cmos_data[cmos_index] = data;
415   - break;
416   - }
417   - }
418   -}
419   -
420   -static inline int to_bcd(int a)
421   -{
422   - return ((a / 10) << 4) | (a % 10);
423   -}
424   -
425   -static void cmos_update_time(void)
426   -{
427   - struct tm *tm;
428   - time_t ti;
429   -
430   - ti = time(NULL);
431   - tm = gmtime(&ti);
432   - cmos_data[RTC_SECONDS] = to_bcd(tm->tm_sec);
433   - cmos_data[RTC_MINUTES] = to_bcd(tm->tm_min);
434   - cmos_data[RTC_HOURS] = to_bcd(tm->tm_hour);
435   - cmos_data[RTC_DAY_OF_WEEK] = to_bcd(tm->tm_wday);
436   - cmos_data[RTC_DAY_OF_MONTH] = to_bcd(tm->tm_mday);
437   - cmos_data[RTC_MONTH] = to_bcd(tm->tm_mon + 1);
438   - cmos_data[RTC_YEAR] = to_bcd(tm->tm_year % 100);
439   - cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19);
440   - cmos_data[REG_IBM_PS2_CENTURY_BYTE] = cmos_data[REG_IBM_CENTURY_BYTE];
441   -}
442   -
443   -uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
444   -{
445   - int ret;
446   -
447   - if (addr == 0x70) {
448   - return 0xff;
449   - } else {
450   - switch(cmos_index) {
451   - case RTC_SECONDS:
452   - case RTC_MINUTES:
453   - case RTC_HOURS:
454   - case RTC_DAY_OF_WEEK:
455   - case RTC_DAY_OF_MONTH:
456   - case RTC_MONTH:
457   - case RTC_YEAR:
458   - case REG_IBM_CENTURY_BYTE:
459   - case REG_IBM_PS2_CENTURY_BYTE:
460   - cmos_update_time();
461   - ret = cmos_data[cmos_index];
462   - break;
463   - case RTC_REG_A:
464   - ret = cmos_data[cmos_index];
465   - /* toggle update-in-progress bit for Linux (same hack as
466   - plex86) */
467   - cmos_data[RTC_REG_A] ^= 0x80;
468   - break;
469   - case RTC_REG_C:
470   - ret = cmos_data[cmos_index];
471   - pic_set_irq(8, 0);
472   - cmos_data[RTC_REG_C] = 0x00;
473   - break;
474   - default:
475   - ret = cmos_data[cmos_index];
476   - break;
477   - }
478   -#ifdef DEBUG_CMOS
479   - printf("cmos: read index=0x%02x val=0x%02x\n",
480   - cmos_index, ret);
481   -#endif
482   - return ret;
483   - }
484   -}
485   -
486   -void cmos_init(void)
487   -{
488   - int val;
489   -
490   - cmos_update_time();
491   -
492   - cmos_data[RTC_REG_A] = 0x26;
493   - cmos_data[RTC_REG_B] = 0x02;
494   - cmos_data[RTC_REG_C] = 0x00;
495   - cmos_data[RTC_REG_D] = 0x80;
496   -
497   - /* various important CMOS locations needed by PC/Bochs bios */
498   -
499   - cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
500   - cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
501   -
502   - /* memory size */
503   - val = (ram_size / 1024) - 1024;
504   - if (val > 65535)
505   - val = 65535;
506   - cmos_data[0x17] = val;
507   - cmos_data[0x18] = val >> 8;
508   - cmos_data[0x30] = val;
509   - cmos_data[0x31] = val >> 8;
510   -
511   - val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
512   - if (val > 65535)
513   - val = 65535;
514   - cmos_data[0x34] = val;
515   - cmos_data[0x35] = val >> 8;
516   -
517   - switch(boot_device) {
518   - case 'a':
519   - case 'b':
520   - cmos_data[0x3d] = 0x01; /* floppy boot */
521   - break;
522   - default:
523   - case 'c':
524   - cmos_data[0x3d] = 0x02; /* hard drive boot */
525   - break;
526   - case 'd':
527   - cmos_data[0x3d] = 0x03; /* CD-ROM boot */
528   - break;
529   - }
530   -
531   - register_ioport_write(0x70, 2, cmos_ioport_write, 1);
532   - register_ioport_read(0x70, 2, cmos_ioport_read, 1);
533   -}
534   -
535   -void cmos_register_fd (uint8_t fd0, uint8_t fd1)
536   -{
537   - int nb = 0;
538   -
539   - cmos_data[0x10] = 0;
540   - switch (fd0) {
541   - case 0:
542   - /* 1.44 Mb 3"5 drive */
543   - cmos_data[0x10] |= 0x40;
544   - break;
545   - case 1:
546   - /* 2.88 Mb 3"5 drive */
547   - cmos_data[0x10] |= 0x60;
548   - break;
549   - case 2:
550   - /* 1.2 Mb 5"5 drive */
551   - cmos_data[0x10] |= 0x20;
552   - break;
553   - }
554   - switch (fd1) {
555   - case 0:
556   - /* 1.44 Mb 3"5 drive */
557   - cmos_data[0x10] |= 0x04;
558   - break;
559   - case 1:
560   - /* 2.88 Mb 3"5 drive */
561   - cmos_data[0x10] |= 0x06;
562   - break;
563   - case 2:
564   - /* 1.2 Mb 5"5 drive */
565   - cmos_data[0x10] |= 0x02;
566   - break;
567   - }
568   - if (fd0 < 3)
569   - nb++;
570   - if (fd1 < 3)
571   - nb++;
572   - switch (nb) {
573   - case 0:
574   - break;
575   - case 1:
576   - cmos_data[REG_EQUIPMENT_BYTE] |= 0x01; /* 1 drive, ready for boot */
577   - break;
578   - case 2:
579   - cmos_data[REG_EQUIPMENT_BYTE] |= 0x41; /* 2 drives, ready for boot */
580   - break;
581   - }
582   -}
583   -#endif /* TARGET_I386 */
584   -
585   -/***********************************************************/
586   -/* 8259 pic emulation */
587   -
588   -typedef struct PicState {
589   - uint8_t last_irr; /* edge detection */
590   - uint8_t irr; /* interrupt request register */
591   - uint8_t imr; /* interrupt mask register */
592   - uint8_t isr; /* interrupt service register */
593   - uint8_t priority_add; /* highest irq priority */
594   - uint8_t irq_base;
595   - uint8_t read_reg_select;
596   - uint8_t poll;
597   - uint8_t special_mask;
598   - uint8_t init_state;
599   - uint8_t auto_eoi;
600   - uint8_t rotate_on_auto_eoi;
601   - uint8_t special_fully_nested_mode;
602   - uint8_t init4; /* true if 4 byte init */
603   -} PicState;
604   -
605   -/* 0 is master pic, 1 is slave pic */
606   -PicState pics[2];
607   -int pic_irq_requested;
608   -
609   -/* set irq level. If an edge is detected, then the IRR is set to 1 */
610   -static inline void pic_set_irq1(PicState *s, int irq, int level)
611   -{
612   - int mask;
613   - mask = 1 << irq;
614   - if (level) {
615   - if ((s->last_irr & mask) == 0)
616   - s->irr |= mask;
617   - s->last_irr |= mask;
618   - } else {
619   - s->last_irr &= ~mask;
620   - }
621   -}
622   -
623   -/* return the highest priority found in mask (highest = smallest
624   - number). Return 8 if no irq */
625   -static inline int get_priority(PicState *s, int mask)
626   -{
627   - int priority;
628   - if (mask == 0)
629   - return 8;
630   - priority = 0;
631   - while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
632   - priority++;
633   - return priority;
634   -}
635   -
636   -/* return the pic wanted interrupt. return -1 if none */
637   -static int pic_get_irq(PicState *s)
638   -{
639   - int mask, cur_priority, priority;
640   -
641   - mask = s->irr & ~s->imr;
642   - priority = get_priority(s, mask);
643   - if (priority == 8)
644   - return -1;
645   - /* compute current priority. If special fully nested mode on the
646   - master, the IRQ coming from the slave is not taken into account
647   - for the priority computation. */
648   - mask = s->isr;
649   - if (s->special_fully_nested_mode && s == &pics[0])
650   - mask &= ~(1 << 2);
651   - cur_priority = get_priority(s, mask);
652   - if (priority < cur_priority) {
653   - /* higher priority found: an irq should be generated */
654   - return (priority + s->priority_add) & 7;
655   - } else {
656   - return -1;
657   - }
658   -}
659   -
660   -/* raise irq to CPU if necessary. must be called every time the active
661   - irq may change */
662   -void pic_update_irq(void)
663   -{
664   - int irq2, irq;
665   -
666   - /* first look at slave pic */
667   - irq2 = pic_get_irq(&pics[1]);
668   - if (irq2 >= 0) {
669   - /* if irq request by slave pic, signal master PIC */
670   - pic_set_irq1(&pics[0], 2, 1);
671   - pic_set_irq1(&pics[0], 2, 0);
672   - }
673   - /* look at requested irq */
674   - irq = pic_get_irq(&pics[0]);
675   - if (irq >= 0) {
676   - if (irq == 2) {
677   - /* from slave pic */
678   - pic_irq_requested = 8 + irq2;
679   - } else {
680   - /* from master pic */
681   - pic_irq_requested = irq;
682   - }
683   -#if defined(DEBUG_PIC)
684   - {
685   - int i;
686   - for(i = 0; i < 2; i++) {
687   - printf("pic%d: imr=%x irr=%x padd=%d\n",
688   - i, pics[i].imr, pics[i].irr, pics[i].priority_add);
689   -
690   - }
691   - }
692   - printf("pic: cpu_interrupt req=%d\n", pic_irq_requested);
693   -#endif
694   - cpu_interrupt(global_env, CPU_INTERRUPT_HARD);
695   - }
696   -}
697   -
698   -#ifdef DEBUG_IRQ_LATENCY
699   -int64_t irq_time[16];
700   -int64_t cpu_get_ticks(void);
701   -#endif
702   -#if defined(DEBUG_PIC)
703   -int irq_level[16];
704   -#endif
705   -
706   -void pic_set_irq(int irq, int level)
707   -{
708   -#if defined(DEBUG_PIC)
709   - if (level != irq_level[irq]) {
710   - printf("pic_set_irq: irq=%d level=%d\n", irq, level);
711   - irq_level[irq] = level;
712   - }
713   -#endif
714   -#ifdef DEBUG_IRQ_LATENCY
715   - if (level) {
716   - irq_time[irq] = cpu_get_ticks();
717   - }
718   -#endif
719   - pic_set_irq1(&pics[irq >> 3], irq & 7, level);
720   - pic_update_irq();
721   -}
722   -
723   -/* acknowledge interrupt 'irq' */
724   -static inline void pic_intack(PicState *s, int irq)
725   -{
726   - if (s->auto_eoi) {
727   - if (s->rotate_on_auto_eoi)
728   - s->priority_add = (irq + 1) & 7;
729   - } else {
730   - s->isr |= (1 << irq);
731   - }
732   - s->irr &= ~(1 << irq);
733   -}
734   -
735   -int cpu_x86_get_pic_interrupt(CPUState *env)
736   -{
737   - int irq, irq2, intno;
738   -
739   - /* signal the pic that the irq was acked by the CPU */
740   - irq = pic_irq_requested;
741   -#ifdef DEBUG_IRQ_LATENCY
742   - printf("IRQ%d latency=%0.3fus\n",
743   - irq,
744   - (double)(cpu_get_ticks() - irq_time[irq]) * 1000000.0 / ticks_per_sec);
745   -#endif
746   -#if defined(DEBUG_PIC)
747   - printf("pic_interrupt: irq=%d\n", irq);
748   -#endif
749   -
750   - if (irq >= 8) {
751   - irq2 = irq & 7;
752   - pic_intack(&pics[1], irq2);
753   - irq = 2;
754   - intno = pics[1].irq_base + irq2;
755   - } else {
756   - intno = pics[0].irq_base + irq;
757   - }
758   - pic_intack(&pics[0], irq);
759   - return intno;
760   -}
761   -
762   -void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
763   -{
764   - PicState *s;
765   - int priority, cmd, irq;
766   -
767   -#ifdef DEBUG_PIC
768   - printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
769   -#endif
770   - s = &pics[addr >> 7];
771   - addr &= 1;
772   - if (addr == 0) {
773   - if (val & 0x10) {
774   - /* init */
775   - memset(s, 0, sizeof(PicState));
776   - s->init_state = 1;
777   - s->init4 = val & 1;
778   - if (val & 0x02)
779   - hw_error("single mode not supported");
780   - if (val & 0x08)
781   - hw_error("level sensitive irq not supported");
782   - } else if (val & 0x08) {
783   - if (val & 0x04)
784   - s->poll = 1;
785   - if (val & 0x02)
786   - s->read_reg_select = val & 1;
787   - if (val & 0x40)
788   - s->special_mask = (val >> 5) & 1;
789   - } else {
790   - cmd = val >> 5;
791   - switch(cmd) {
792   - case 0:
793   - case 4:
794   - s->rotate_on_auto_eoi = cmd >> 2;
795   - break;
796   - case 1: /* end of interrupt */
797   - case 5:
798   - priority = get_priority(s, s->isr);
799   - if (priority != 8) {
800   - irq = (priority + s->priority_add) & 7;
801   - s->isr &= ~(1 << irq);
802   - if (cmd == 5)
803   - s->priority_add = (irq + 1) & 7;
804   - pic_update_irq();
805   - }
806   - break;
807   - case 3:
808   - irq = val & 7;
809   - s->isr &= ~(1 << irq);
810   - pic_update_irq();
811   - break;
812   - case 6:
813   - s->priority_add = (val + 1) & 7;
814   - pic_update_irq();
815   - break;
816   - case 7:
817   - irq = val & 7;
818   - s->isr &= ~(1 << irq);
819   - s->priority_add = (irq + 1) & 7;
820   - pic_update_irq();
821   - break;
822   - default:
823   - /* no operation */
824   - break;
825   - }
826   - }
827   - } else {
828   - switch(s->init_state) {
829   - case 0:
830   - /* normal mode */
831   - s->imr = val;
832   - pic_update_irq();
833   - break;
834   - case 1:
835   - s->irq_base = val & 0xf8;
836   - s->init_state = 2;
837   - break;
838   - case 2:
839   - if (s->init4) {
840   - s->init_state = 3;
841   - } else {
842   - s->init_state = 0;
843   - }
844   - break;
845   - case 3:
846   - s->special_fully_nested_mode = (val >> 4) & 1;
847   - s->auto_eoi = (val >> 1) & 1;
848   - s->init_state = 0;
849   - break;
850   - }
851   - }
852   -}
853   -
854   -static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
855   -{
856   - int ret;
857   -
858   - ret = pic_get_irq(s);
859   - if (ret >= 0) {
860   - if (addr1 >> 7) {
861   - pics[0].isr &= ~(1 << 2);
862   - pics[0].irr &= ~(1 << 2);
863   - }
864   - s->irr &= ~(1 << ret);
865   - s->isr &= ~(1 << ret);
866   - if (addr1 >> 7 || ret != 2)
867   - pic_update_irq();
868   - } else {
869   - ret = 0x07;
870   - pic_update_irq();
871   - }
872   -
873   - return ret;
874   -}
875   -
876   -uint32_t pic_ioport_read(CPUState *env, uint32_t addr1)
877   -{
878   - PicState *s;
879   - unsigned int addr;
880   - int ret;
881   -
882   - addr = addr1;
883   - s = &pics[addr >> 7];
884   - addr &= 1;
885   - if (s->poll) {
886   - ret = pic_poll_read(s, addr1);
887   - s->poll = 0;
888   - } else {
889   - if (addr == 0) {
890   - if (s->read_reg_select)
891   - ret = s->isr;
892   - else
893   - ret = s->irr;
894   - } else {
895   - ret = s->imr;
896   - }
897   - }
898   -#ifdef DEBUG_PIC
899   - printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
900   -#endif
901   - return ret;
902   -}
903   -
904   -/* memory mapped interrupt status */
905   -uint32_t pic_intack_read(CPUState *env)
906   -{
907   - int ret;
908   -
909   - ret = pic_poll_read(&pics[0], 0x00);
910   - if (ret == 2)
911   - ret = pic_poll_read(&pics[1], 0x80) + 8;
912   - /* Prepare for ISR read */
913   - pics[0].read_reg_select = 1;
914   -
915   - return ret;
916   -}
917   -
918   -void pic_init(void)
919   -{
920   -#if defined (TARGET_I386) || defined (TARGET_PPC)
921   - register_ioport_write(0x20, 2, pic_ioport_write, 1);
922   - register_ioport_read(0x20, 2, pic_ioport_read, 1);
923   - register_ioport_write(0xa0, 2, pic_ioport_write, 1);
924   - register_ioport_read(0xa0, 2, pic_ioport_read, 1);
925   -#endif
926   -}
927   -
928   -/***********************************************************/
929   -/* 8253 PIT emulation */
930   -
931   -#define PIT_FREQ 1193182
932   -
933   -#define RW_STATE_LSB 0
934   -#define RW_STATE_MSB 1
935   -#define RW_STATE_WORD0 2
936   -#define RW_STATE_WORD1 3
937   -#define RW_STATE_LATCHED_WORD0 4
938   -#define RW_STATE_LATCHED_WORD1 5
939   -
940   -typedef struct PITChannelState {
941   - int count; /* can be 65536 */
942   - uint16_t latched_count;
943   - uint8_t rw_state;
944   - uint8_t mode;
945   - uint8_t bcd; /* not supported */
946   - uint8_t gate; /* timer start */
947   - int64_t count_load_time;
948   - int64_t count_last_edge_check_time;
949   -} PITChannelState;
950   -
951   -PITChannelState pit_channels[3];
952   -int speaker_data_on;
953   -int dummy_refresh_clock;
954   -int pit_min_timer_count = 0;
955   -
956   -
957 287 #if defined(__powerpc__)
958 288  
959 289 static inline uint32_t get_tbl(void)
... ... @@ -1036,7 +366,7 @@ void cpu_calibrate_ticks(void)
1036 366 }
1037 367  
1038 368 /* compute with 96 bit intermediate result: (a*b)/c */
1039   -static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
  369 +uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
1040 370 {
1041 371 union {
1042 372 uint64_t ll;
... ... @@ -1059,1809 +389,214 @@ static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
1059 389 return res.ll;
1060 390 }
1061 391  
1062   -static int pit_get_count(PITChannelState *s)
1063   -{
1064   - uint64_t d;
1065   - int counter;
1066   -
1067   - d = muldiv64(cpu_get_ticks() - s->count_load_time, PIT_FREQ, ticks_per_sec);
1068   - switch(s->mode) {
1069   - case 0:
1070   - case 1:
1071   - case 4:
1072   - case 5:
1073   - counter = (s->count - d) & 0xffff;
1074   - break;
1075   - case 3:
1076   - /* XXX: may be incorrect for odd counts */
1077   - counter = s->count - ((2 * d) % s->count);
1078   - break;
1079   - default:
1080   - counter = s->count - (d % s->count);
1081   - break;
1082   - }
1083   - return counter;
1084   -}
1085   -
1086   -/* get pit output bit */
1087   -static int pit_get_out(PITChannelState *s)
1088   -{
1089   - uint64_t d;
1090   - int out;
1091   -
1092   - d = muldiv64(cpu_get_ticks() - s->count_load_time, PIT_FREQ, ticks_per_sec);
1093   - switch(s->mode) {
1094   - default:
1095   - case 0:
1096   - out = (d >= s->count);
1097   - break;
1098   - case 1:
1099   - out = (d < s->count);
1100   - break;
1101   - case 2:
1102   - if ((d % s->count) == 0 && d != 0)
1103   - out = 1;
1104   - else
1105   - out = 0;
1106   - break;
1107   - case 3:
1108   - out = (d % s->count) < ((s->count + 1) >> 1);
1109   - break;
1110   - case 4:
1111   - case 5:
1112   - out = (d == s->count);
1113   - break;
1114   - }
1115   - return out;
1116   -}
1117   -
1118   -/* get the number of 0 to 1 transitions we had since we call this
1119   - function */
1120   -/* XXX: maybe better to use ticks precision to avoid getting edges
1121   - twice if checks are done at very small intervals */
1122   -static int pit_get_out_edges(PITChannelState *s)
1123   -{
1124   - uint64_t d1, d2;
1125   - int64_t ticks;
1126   - int ret, v;
1127   -
1128   - ticks = cpu_get_ticks();
1129   - d1 = muldiv64(s->count_last_edge_check_time - s->count_load_time,
1130   - PIT_FREQ, ticks_per_sec);
1131   - d2 = muldiv64(ticks - s->count_load_time,
1132   - PIT_FREQ, ticks_per_sec);
1133   - s->count_last_edge_check_time = ticks;
1134   - switch(s->mode) {
1135   - default:
1136   - case 0:
1137   - if (d1 < s->count && d2 >= s->count)
1138   - ret = 1;
1139   - else
1140   - ret = 0;
1141   - break;
1142   - case 1:
1143   - ret = 0;
1144   - break;
1145   - case 2:
1146   - d1 /= s->count;
1147   - d2 /= s->count;
1148   - ret = d2 - d1;
1149   - break;
1150   - case 3:
1151   - v = s->count - ((s->count + 1) >> 1);
1152   - d1 = (d1 + v) / s->count;
1153   - d2 = (d2 + v) / s->count;
1154   - ret = d2 - d1;
1155   - break;
1156   - case 4:
1157   - case 5:
1158   - if (d1 < s->count && d2 >= s->count)
1159   - ret = 1;
1160   - else
1161   - ret = 0;
1162   - break;
1163   - }
1164   - return ret;
1165   -}
1166   -
1167   -/* val must be 0 or 1 */
1168   -static inline void pit_set_gate(PITChannelState *s, int val)
1169   -{
1170   - switch(s->mode) {
1171   - default:
1172   - case 0:
1173   - case 4:
1174   - /* XXX: just disable/enable counting */
1175   - break;
1176   - case 1:
1177   - case 5:
1178   - if (s->gate < val) {
1179   - /* restart counting on rising edge */
1180   - s->count_load_time = cpu_get_ticks();
1181   - s->count_last_edge_check_time = s->count_load_time;
1182   - }
1183   - break;
1184   - case 2:
1185   - case 3:
1186   - if (s->gate < val) {
1187   - /* restart counting on rising edge */
1188   - s->count_load_time = cpu_get_ticks();
1189   - s->count_last_edge_check_time = s->count_load_time;
1190   - }
1191   - /* XXX: disable/enable counting */
1192   - break;
1193   - }
1194   - s->gate = val;
1195   -}
1196   -
1197   -static inline void pit_load_count(PITChannelState *s, int val)
1198   -{
1199   - if (val == 0)
1200   - val = 0x10000;
1201   - s->count_load_time = cpu_get_ticks();
1202   - s->count_last_edge_check_time = s->count_load_time;
1203   - s->count = val;
1204   - if (s == &pit_channels[0] && val <= pit_min_timer_count) {
1205   - fprintf(stderr,
1206   - "\nWARNING: qemu: on your system, accurate timer emulation is impossible if its frequency is more than %d Hz. If using a 2.6 guest Linux kernel, you must patch asm/param.h to change HZ from 1000 to 100.\n\n",
1207   - PIT_FREQ / pit_min_timer_count);
1208   - }
1209   -}
1210   -
1211   -void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
1212   -{
1213   - int channel, access;
1214   - PITChannelState *s;
1215   -
1216   - addr &= 3;
1217   - if (addr == 3) {
1218   - channel = val >> 6;
1219   - if (channel == 3)
1220   - return;
1221   - s = &pit_channels[channel];
1222   - access = (val >> 4) & 3;
1223   - switch(access) {
1224   - case 0:
1225   - s->latched_count = pit_get_count(s);
1226   - s->rw_state = RW_STATE_LATCHED_WORD0;
1227   - break;
1228   - default:
1229   - s->mode = (val >> 1) & 7;
1230   - s->bcd = val & 1;
1231   - s->rw_state = access - 1 + RW_STATE_LSB;
1232   - break;
1233   - }
1234   - } else {
1235   - s = &pit_channels[addr];
1236   - switch(s->rw_state) {
1237   - case RW_STATE_LSB:
1238   - pit_load_count(s, val);
1239   - break;
1240   - case RW_STATE_MSB:
1241   - pit_load_count(s, val << 8);
1242   - break;
1243   - case RW_STATE_WORD0:
1244   - case RW_STATE_WORD1:
1245   - if (s->rw_state & 1) {
1246   - pit_load_count(s, (s->latched_count & 0xff) | (val << 8));
1247   - } else {
1248   - s->latched_count = val;
1249   - }
1250   - s->rw_state ^= 1;
1251   - break;
1252   - }
1253   - }
1254   -}
1255   -
1256   -uint32_t pit_ioport_read(CPUState *env, uint32_t addr)
1257   -{
1258   - int ret, count;
1259   - PITChannelState *s;
1260   -
1261   - addr &= 3;
1262   - s = &pit_channels[addr];
1263   - switch(s->rw_state) {
1264   - case RW_STATE_LSB:
1265   - case RW_STATE_MSB:
1266   - case RW_STATE_WORD0:
1267   - case RW_STATE_WORD1:
1268   - count = pit_get_count(s);
1269   - if (s->rw_state & 1)
1270   - ret = (count >> 8) & 0xff;
1271   - else
1272   - ret = count & 0xff;
1273   - if (s->rw_state & 2)
1274   - s->rw_state ^= 1;
1275   - break;
1276   - default:
1277   - case RW_STATE_LATCHED_WORD0:
1278   - case RW_STATE_LATCHED_WORD1:
1279   - if (s->rw_state & 1)
1280   - ret = s->latched_count >> 8;
1281   - else
1282   - ret = s->latched_count & 0xff;
1283   - s->rw_state ^= 1;
1284   - break;
1285   - }
1286   - return ret;
1287   -}
1288   -
1289   -#if defined (TARGET_I386)
1290   -void speaker_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
1291   -{
1292   - speaker_data_on = (val >> 1) & 1;
1293   - pit_set_gate(&pit_channels[2], val & 1);
1294   -}
1295   -
1296   -uint32_t speaker_ioport_read(CPUState *env, uint32_t addr)
1297   -{
1298   - int out;
1299   - out = pit_get_out(&pit_channels[2]);
1300   - dummy_refresh_clock ^= 1;
1301   - return (speaker_data_on << 1) | pit_channels[2].gate | (out << 5) |
1302   - (dummy_refresh_clock << 4);
1303   -}
1304   -#endif
  392 +#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
  393 +static int term_got_escape, term_command;
  394 +static unsigned char term_cmd_buf[128];
1305 395  
1306   -void pit_init(void)
1307   -{
1308   - PITChannelState *s;
1309   - int i;
  396 +typedef struct term_cmd_t {
  397 + const unsigned char *name;
  398 + void (*handler)(unsigned char *params);
  399 +} term_cmd_t;
1310 400  
1311   - cpu_calibrate_ticks();
1312   -
1313   - for(i = 0;i < 3; i++) {
1314   - s = &pit_channels[i];
1315   - s->mode = 3;
1316   - s->gate = (i != 2);
1317   - pit_load_count(s, 0);
1318   - }
1319   -
1320   - register_ioport_write(0x40, 4, pit_ioport_write, 1);
1321   - register_ioport_read(0x40, 3, pit_ioport_read, 1);
1322   -
1323   -#if defined (TARGET_I386)
1324   - register_ioport_read(0x61, 1, speaker_ioport_read, 1);
1325   - register_ioport_write(0x61, 1, speaker_ioport_write, 1);
1326   -#endif
1327   -}
1328   -
1329   -/***********************************************************/
1330   -/* serial port emulation */
1331   -
1332   -#define UART_IRQ 4
1333   -
1334   -#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
1335   -
1336   -#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
1337   -#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
1338   -#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
1339   -#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
1340   -
1341   -#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
1342   -#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
1343   -
1344   -#define UART_IIR_MSI 0x00 /* Modem status interrupt */
1345   -#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
1346   -#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
1347   -#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
1348   -
1349   -/*
1350   - * These are the definitions for the Modem Control Register
1351   - */
1352   -#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
1353   -#define UART_MCR_OUT2 0x08 /* Out2 complement */
1354   -#define UART_MCR_OUT1 0x04 /* Out1 complement */
1355   -#define UART_MCR_RTS 0x02 /* RTS complement */
1356   -#define UART_MCR_DTR 0x01 /* DTR complement */
1357   -
1358   -/*
1359   - * These are the definitions for the Modem Status Register
1360   - */
1361   -#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
1362   -#define UART_MSR_RI 0x40 /* Ring Indicator */
1363   -#define UART_MSR_DSR 0x20 /* Data Set Ready */
1364   -#define UART_MSR_CTS 0x10 /* Clear to Send */
1365   -#define UART_MSR_DDCD 0x08 /* Delta DCD */
1366   -#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
1367   -#define UART_MSR_DDSR 0x02 /* Delta DSR */
1368   -#define UART_MSR_DCTS 0x01 /* Delta CTS */
1369   -#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
1370   -
1371   -#define UART_LSR_TEMT 0x40 /* Transmitter empty */
1372   -#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
1373   -#define UART_LSR_BI 0x10 /* Break interrupt indicator */
1374   -#define UART_LSR_FE 0x08 /* Frame error indicator */
1375   -#define UART_LSR_PE 0x04 /* Parity error indicator */
1376   -#define UART_LSR_OE 0x02 /* Overrun error indicator */
1377   -#define UART_LSR_DR 0x01 /* Receiver data ready */
1378   -
1379   -typedef struct SerialState {
1380   - uint8_t divider;
1381   - uint8_t rbr; /* receive register */
1382   - uint8_t ier;
1383   - uint8_t iir; /* read only */
1384   - uint8_t lcr;
1385   - uint8_t mcr;
1386   - uint8_t lsr; /* read only */
1387   - uint8_t msr;
1388   - uint8_t scr;
1389   - /* NOTE: this hidden state is necessary for tx irq generation as
1390   - it can be reset while reading iir */
1391   - int thr_ipending;
1392   -} SerialState;
1393   -
1394   -SerialState serial_ports[1];
1395   -
1396   -void serial_update_irq(void)
1397   -{
1398   - SerialState *s = &serial_ports[0];
1399   -
1400   - if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
1401   - s->iir = UART_IIR_RDI;
1402   - } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
1403   - s->iir = UART_IIR_THRI;
1404   - } else {
1405   - s->iir = UART_IIR_NO_INT;
1406   - }
1407   - if (s->iir != UART_IIR_NO_INT) {
1408   - pic_set_irq(UART_IRQ, 1);
1409   - } else {
1410   - pic_set_irq(UART_IRQ, 0);
1411   - }
1412   -}
1413   -
1414   -void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
1415   -{
1416   - SerialState *s = &serial_ports[0];
1417   - unsigned char ch;
1418   - int ret;
1419   -
1420   - addr &= 7;
1421   -#ifdef DEBUG_SERIAL
1422   - printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
1423   -#endif
1424   - switch(addr) {
1425   - default:
1426   - case 0:
1427   - if (s->lcr & UART_LCR_DLAB) {
1428   - s->divider = (s->divider & 0xff00) | val;
1429   - } else {
1430   - s->thr_ipending = 0;
1431   - s->lsr &= ~UART_LSR_THRE;
1432   - serial_update_irq();
1433   -
1434   - ch = val;
1435   - do {
1436   - ret = write(1, &ch, 1);
1437   - } while (ret != 1);
1438   - s->thr_ipending = 1;
1439   - s->lsr |= UART_LSR_THRE;
1440   - s->lsr |= UART_LSR_TEMT;
1441   - serial_update_irq();
1442   - }
1443   - break;
1444   - case 1:
1445   - if (s->lcr & UART_LCR_DLAB) {
1446   - s->divider = (s->divider & 0x00ff) | (val << 8);
1447   - } else {
1448   - s->ier = val;
1449   - serial_update_irq();
1450   - }
1451   - break;
1452   - case 2:
1453   - break;
1454   - case 3:
1455   - s->lcr = val;
1456   - break;
1457   - case 4:
1458   - s->mcr = val;
1459   - break;
1460   - case 5:
1461   - break;
1462   - case 6:
1463   - s->msr = val;
1464   - break;
1465   - case 7:
1466   - s->scr = val;
1467   - break;
1468   - }
1469   -}
1470   -
1471   -uint32_t serial_ioport_read(CPUState *env, uint32_t addr)
1472   -{
1473   - SerialState *s = &serial_ports[0];
1474   - uint32_t ret;
1475   -
1476   - addr &= 7;
1477   - switch(addr) {
1478   - default:
1479   - case 0:
1480   - if (s->lcr & UART_LCR_DLAB) {
1481   - ret = s->divider & 0xff;
1482   - } else {
1483   - ret = s->rbr;
1484   - s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
1485   - serial_update_irq();
1486   - }
1487   - break;
1488   - case 1:
1489   - if (s->lcr & UART_LCR_DLAB) {
1490   - ret = (s->divider >> 8) & 0xff;
1491   - } else {
1492   - ret = s->ier;
1493   - }
1494   - break;
1495   - case 2:
1496   - ret = s->iir;
1497   - /* reset THR pending bit */
1498   - if ((ret & 0x7) == UART_IIR_THRI)
1499   - s->thr_ipending = 0;
1500   - serial_update_irq();
1501   - break;
1502   - case 3:
1503   - ret = s->lcr;
1504   - break;
1505   - case 4:
1506   - ret = s->mcr;
1507   - break;
1508   - case 5:
1509   - ret = s->lsr;
1510   - break;
1511   - case 6:
1512   - if (s->mcr & UART_MCR_LOOP) {
1513   - /* in loopback, the modem output pins are connected to the
1514   - inputs */
1515   - ret = (s->mcr & 0x0c) << 4;
1516   - ret |= (s->mcr & 0x02) << 3;
1517   - ret |= (s->mcr & 0x01) << 5;
1518   - } else {
1519   - ret = s->msr;
1520   - }
1521   - break;
1522   - case 7:
1523   - ret = s->scr;
1524   - break;
1525   - }
1526   -#ifdef DEBUG_SERIAL
1527   - printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
1528   -#endif
1529   - return ret;
1530   -}
1531   -
1532   -#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
1533   -static int term_got_escape, term_command;
1534   -static unsigned char term_cmd_buf[128];
1535   -
1536   -typedef struct term_cmd_t {
1537   - const unsigned char *name;
1538   - void (*handler)(unsigned char *params);
1539   -} term_cmd_t;
1540   -
1541   -static void do_change_cdrom (unsigned char *params);
1542   -static void do_change_fd0 (unsigned char *params);
1543   -static void do_change_fd1 (unsigned char *params);
  401 +static void do_change_cdrom (unsigned char *params);
  402 +static void do_change_fd0 (unsigned char *params);
  403 +static void do_change_fd1 (unsigned char *params);
1544 404  
1545 405 static term_cmd_t term_cmds[] = {
1546 406 { "changecd", &do_change_cdrom, },
1547 407 { "changefd0", &do_change_fd0, },
1548 408 { "changefd1", &do_change_fd1, },
1549   - { NULL, NULL, },
1550   -};
1551   -
1552   -void term_print_help(void)
1553   -{
1554   - printf("\n"
1555   - "C-a h print this help\n"
1556   - "C-a x exit emulatior\n"
1557   - "C-a d switch on/off debug log\n"
1558   - "C-a s save disk data back to file (if -snapshot)\n"
1559   - "C-a b send break (magic sysrq)\n"
1560   - "C-a c send qemu internal command\n"
1561   - "C-a C-a send C-a\n"
1562   - );
1563   -}
1564   -
1565   -static void do_change_cdrom (unsigned char *params)
1566   -{
1567   - /* Dunno how to do it... */
1568   -}
1569   -
1570   -static void do_change_fd (int fd, unsigned char *params)
1571   -{
1572   - unsigned char *name_start, *name_end, *ros;
1573   - int ro;
1574   -
1575   - for (name_start = params;
1576   - isspace(*name_start); name_start++)
1577   - continue;
1578   - if (*name_start == '\0')
1579   - return;
1580   - for (name_end = name_start;
1581   - !isspace(*name_end) && *name_end != '\0'; name_end++)
1582   - continue;
1583   - for (ros = name_end + 1; isspace(*ros); ros++)
1584   - continue;
1585   - if (ros[0] == 'r' && ros[1] == 'o')
1586   - ro = 1;
1587   - else
1588   - ro = 0;
1589   - *name_end = '\0';
1590   - printf("Change fd %d to %s (%s)\n", fd, name_start, params);
1591   - fdctrl_disk_change(fd, name_start, ro);
1592   -}
1593   -
1594   -static void do_change_fd0 (unsigned char *params)
1595   -{
1596   - do_change_fd(0, params);
1597   -}
1598   -
1599   -static void do_change_fd1 (unsigned char *params)
1600   -{
1601   - do_change_fd(1, params);
1602   -}
1603   -
1604   -static void serial_treat_command ()
1605   -{
1606   - unsigned char *cmd_start, *cmd_end;
1607   - int i;
1608   -
1609   - for (cmd_start = term_cmd_buf; isspace(*cmd_start); cmd_start++)
1610   - continue;
1611   - for (cmd_end = cmd_start;
1612   - !isspace(*cmd_end) && *cmd_end != '\0'; cmd_end++)
1613   - continue;
1614   - for (i = 0; term_cmds[i].name != NULL; i++) {
1615   - if (strlen(term_cmds[i].name) == (cmd_end - cmd_start) &&
1616   - memcmp(term_cmds[i].name, cmd_start, cmd_end - cmd_start) == 0) {
1617   - (*term_cmds[i].handler)(cmd_end + 1);
1618   - return;
1619   - }
1620   - }
1621   - *cmd_end = '\0';
1622   - printf("Unknown term command: %s\n", cmd_start);
1623   -}
1624   -
1625   -extern FILE *logfile;
1626   -
1627   -/* called when a char is received */
1628   -void serial_received_byte(SerialState *s, int ch)
1629   -{
1630   - if (term_command) {
1631   - if (ch == '\n' || ch == '\r' || term_command == 127) {
1632   - printf("\n");
1633   - serial_treat_command();
1634   - term_command = 0;
1635   - } else {
1636   - if (ch == 0x7F || ch == 0x08) {
1637   - if (term_command > 1) {
1638   - term_cmd_buf[--term_command - 1] = '\0';
1639   - printf("\r "
1640   - " ");
1641   - printf("\r> %s", term_cmd_buf);
1642   - }
1643   - } else if (ch > 0x1f) {
1644   - term_cmd_buf[term_command++ - 1] = ch;
1645   - term_cmd_buf[term_command - 1] = '\0';
1646   - printf("\r> %s", term_cmd_buf);
1647   - }
1648   - fflush(stdout);
1649   - }
1650   - } else if (term_got_escape) {
1651   - term_got_escape = 0;
1652   - switch(ch) {
1653   - case 'h':
1654   - term_print_help();
1655   - break;
1656   - case 'x':
1657   - exit(0);
1658   - break;
1659   - case 's':
1660   - {
1661   - int i;
1662   - for (i = 0; i < MAX_DISKS; i++) {
1663   - if (bs_table[i])
1664   - bdrv_commit(bs_table[i]);
1665   - }
1666   - }
1667   - break;
1668   - case 'b':
1669   - /* send break */
1670   - s->rbr = 0;
1671   - s->lsr |= UART_LSR_BI | UART_LSR_DR;
1672   - serial_update_irq();
1673   - break;
1674   - case 'c':
1675   - printf("> ");
1676   - fflush(stdout);
1677   - term_command = 1;
1678   - break;
1679   - case 'd':
1680   - cpu_set_log(CPU_LOG_ALL);
1681   - break;
1682   - case TERM_ESCAPE:
1683   - goto send_char;
1684   - }
1685   - } else if (ch == TERM_ESCAPE) {
1686   - term_got_escape = 1;
1687   - } else {
1688   - send_char:
1689   - s->rbr = ch;
1690   - s->lsr |= UART_LSR_DR;
1691   - serial_update_irq();
1692   - }
1693   -}
1694   -
1695   -void serial_init(void)
1696   -{
1697   - SerialState *s = &serial_ports[0];
1698   -
1699   - s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
1700   - s->iir = UART_IIR_NO_INT;
1701   -
1702   -#if defined(TARGET_I386) || defined (TARGET_PPC)
1703   - register_ioport_write(0x3f8, 8, serial_ioport_write, 1);
1704   - register_ioport_read(0x3f8, 8, serial_ioport_read, 1);
1705   -#endif
1706   -}
1707   -
1708   -/***********************************************************/
1709   -/* ne2000 emulation */
1710   -
1711   -#if defined (TARGET_I386)
1712   -#define NE2000_IOPORT 0x300
1713   -#define NE2000_IRQ 9
1714   -
1715   -#define MAX_ETH_FRAME_SIZE 1514
1716   -
1717   -#define E8390_CMD 0x00 /* The command register (for all pages) */
1718   -/* Page 0 register offsets. */
1719   -#define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */
1720   -#define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */
1721   -#define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */
1722   -#define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */
1723   -#define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */
1724   -#define EN0_TSR 0x04 /* Transmit status reg RD */
1725   -#define EN0_TPSR 0x04 /* Transmit starting page WR */
1726   -#define EN0_NCR 0x05 /* Number of collision reg RD */
1727   -#define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */
1728   -#define EN0_FIFO 0x06 /* FIFO RD */
1729   -#define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */
1730   -#define EN0_ISR 0x07 /* Interrupt status reg RD WR */
1731   -#define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */
1732   -#define EN0_RSARLO 0x08 /* Remote start address reg 0 */
1733   -#define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */
1734   -#define EN0_RSARHI 0x09 /* Remote start address reg 1 */
1735   -#define EN0_RCNTLO 0x0a /* Remote byte count reg WR */
1736   -#define EN0_RCNTHI 0x0b /* Remote byte count reg WR */
1737   -#define EN0_RSR 0x0c /* rx status reg RD */
1738   -#define EN0_RXCR 0x0c /* RX configuration reg WR */
1739   -#define EN0_TXCR 0x0d /* TX configuration reg WR */
1740   -#define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */
1741   -#define EN0_DCFG 0x0e /* Data configuration reg WR */
1742   -#define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */
1743   -#define EN0_IMR 0x0f /* Interrupt mask reg WR */
1744   -#define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */
1745   -
1746   -#define EN1_PHYS 0x11
1747   -#define EN1_CURPAG 0x17
1748   -#define EN1_MULT 0x18
1749   -
1750   -/* Register accessed at EN_CMD, the 8390 base addr. */
1751   -#define E8390_STOP 0x01 /* Stop and reset the chip */
1752   -#define E8390_START 0x02 /* Start the chip, clear reset */
1753   -#define E8390_TRANS 0x04 /* Transmit a frame */
1754   -#define E8390_RREAD 0x08 /* Remote read */
1755   -#define E8390_RWRITE 0x10 /* Remote write */
1756   -#define E8390_NODMA 0x20 /* Remote DMA */
1757   -#define E8390_PAGE0 0x00 /* Select page chip registers */
1758   -#define E8390_PAGE1 0x40 /* using the two high-order bits */
1759   -#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
1760   -
1761   -/* Bits in EN0_ISR - Interrupt status register */
1762   -#define ENISR_RX 0x01 /* Receiver, no error */
1763   -#define ENISR_TX 0x02 /* Transmitter, no error */
1764   -#define ENISR_RX_ERR 0x04 /* Receiver, with error */
1765   -#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
1766   -#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
1767   -#define ENISR_COUNTERS 0x20 /* Counters need emptying */
1768   -#define ENISR_RDC 0x40 /* remote dma complete */
1769   -#define ENISR_RESET 0x80 /* Reset completed */
1770   -#define ENISR_ALL 0x3f /* Interrupts we will enable */
1771   -
1772   -/* Bits in received packet status byte and EN0_RSR*/
1773   -#define ENRSR_RXOK 0x01 /* Received a good packet */
1774   -#define ENRSR_CRC 0x02 /* CRC error */
1775   -#define ENRSR_FAE 0x04 /* frame alignment error */
1776   -#define ENRSR_FO 0x08 /* FIFO overrun */
1777   -#define ENRSR_MPA 0x10 /* missed pkt */
1778   -#define ENRSR_PHY 0x20 /* physical/multicast address */
1779   -#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
1780   -#define ENRSR_DEF 0x80 /* deferring */
1781   -
1782   -/* Transmitted packet status, EN0_TSR. */
1783   -#define ENTSR_PTX 0x01 /* Packet transmitted without error */
1784   -#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
1785   -#define ENTSR_COL 0x04 /* The transmit collided at least once. */
1786   -#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
1787   -#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
1788   -#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
1789   -#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
1790   -#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
1791   -
1792   -#define NE2000_MEM_SIZE 32768
1793   -
1794   -typedef struct NE2000State {
1795   - uint8_t cmd;
1796   - uint32_t start;
1797   - uint32_t stop;
1798   - uint8_t boundary;
1799   - uint8_t tsr;
1800   - uint8_t tpsr;
1801   - uint16_t tcnt;
1802   - uint16_t rcnt;
1803   - uint32_t rsar;
1804   - uint8_t isr;
1805   - uint8_t dcfg;
1806   - uint8_t imr;
1807   - uint8_t phys[6]; /* mac address */
1808   - uint8_t curpag;
1809   - uint8_t mult[8]; /* multicast mask array */
1810   - uint8_t mem[NE2000_MEM_SIZE];
1811   -} NE2000State;
1812   -
1813   -NE2000State ne2000_state;
1814   -int net_fd = -1;
1815   -char network_script[1024];
1816   -
1817   -void ne2000_reset(void)
1818   -{
1819   - NE2000State *s = &ne2000_state;
1820   - int i;
1821   -
1822   - s->isr = ENISR_RESET;
1823   - s->mem[0] = 0x52;
1824   - s->mem[1] = 0x54;
1825   - s->mem[2] = 0x00;
1826   - s->mem[3] = 0x12;
1827   - s->mem[4] = 0x34;
1828   - s->mem[5] = 0x56;
1829   - s->mem[14] = 0x57;
1830   - s->mem[15] = 0x57;
1831   -
1832   - /* duplicate prom data */
1833   - for(i = 15;i >= 0; i--) {
1834   - s->mem[2 * i] = s->mem[i];
1835   - s->mem[2 * i + 1] = s->mem[i];
1836   - }
1837   -}
1838   -
1839   -void ne2000_update_irq(NE2000State *s)
1840   -{
1841   - int isr;
1842   - isr = s->isr & s->imr;
1843   - if (isr)
1844   - pic_set_irq(NE2000_IRQ, 1);
1845   - else
1846   - pic_set_irq(NE2000_IRQ, 0);
1847   -}
1848   -
1849   -int net_init(void)
1850   -{
1851   - struct ifreq ifr;
1852   - int fd, ret, pid, status;
1853   -
1854   - fd = open("/dev/net/tun", O_RDWR);
1855   - if (fd < 0) {
1856   - fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
1857   - return -1;
1858   - }
1859   - memset(&ifr, 0, sizeof(ifr));
1860   - ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1861   - pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
1862   - ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
1863   - if (ret != 0) {
1864   - fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
1865   - close(fd);
1866   - return -1;
1867   - }
1868   - printf("Connected to host network interface: %s\n", ifr.ifr_name);
1869   - fcntl(fd, F_SETFL, O_NONBLOCK);
1870   - net_fd = fd;
1871   -
1872   - /* try to launch network init script */
1873   - pid = fork();
1874   - if (pid >= 0) {
1875   - if (pid == 0) {
1876   - execl(network_script, network_script, ifr.ifr_name, NULL);
1877   - exit(1);
1878   - }
1879   - while (waitpid(pid, &status, 0) != pid);
1880   - if (!WIFEXITED(status) ||
1881   - WEXITSTATUS(status) != 0) {
1882   - fprintf(stderr, "%s: could not launch network script for '%s'\n",
1883   - network_script, ifr.ifr_name);
1884   - }
1885   - }
1886   - return 0;
1887   -}
1888   -
1889   -void net_send_packet(NE2000State *s, const uint8_t *buf, int size)
1890   -{
1891   -#ifdef DEBUG_NE2000
1892   - printf("NE2000: sending packet size=%d\n", size);
1893   -#endif
1894   - write(net_fd, buf, size);
1895   -}
1896   -
1897   -/* return true if the NE2000 can receive more data */
1898   -int ne2000_can_receive(NE2000State *s)
1899   -{
1900   - int avail, index, boundary;
1901   -
1902   - if (s->cmd & E8390_STOP)
1903   - return 0;
1904   - index = s->curpag << 8;
1905   - boundary = s->boundary << 8;
1906   - if (index < boundary)
1907   - avail = boundary - index;
1908   - else
1909   - avail = (s->stop - s->start) - (index - boundary);
1910   - if (avail < (MAX_ETH_FRAME_SIZE + 4))
1911   - return 0;
1912   - return 1;
1913   -}
1914   -
1915   -void ne2000_receive(NE2000State *s, uint8_t *buf, int size)
1916   -{
1917   - uint8_t *p;
1918   - int total_len, next, avail, len, index;
1919   -
1920   -#if defined(DEBUG_NE2000)
1921   - printf("NE2000: received len=%d\n", size);
1922   -#endif
1923   -
1924   - index = s->curpag << 8;
1925   - /* 4 bytes for header */
1926   - total_len = size + 4;
1927   - /* address for next packet (4 bytes for CRC) */
1928   - next = index + ((total_len + 4 + 255) & ~0xff);
1929   - if (next >= s->stop)
1930   - next -= (s->stop - s->start);
1931   - /* prepare packet header */
1932   - p = s->mem + index;
1933   - p[0] = ENRSR_RXOK; /* receive status */
1934   - p[1] = next >> 8;
1935   - p[2] = total_len;
1936   - p[3] = total_len >> 8;
1937   - index += 4;
1938   -
1939   - /* write packet data */
1940   - while (size > 0) {
1941   - avail = s->stop - index;
1942   - len = size;
1943   - if (len > avail)
1944   - len = avail;
1945   - memcpy(s->mem + index, buf, len);
1946   - buf += len;
1947   - index += len;
1948   - if (index == s->stop)
1949   - index = s->start;
1950   - size -= len;
1951   - }
1952   - s->curpag = next >> 8;
1953   -
1954   - /* now we can signal we have receive something */
1955   - s->isr |= ENISR_RX;
1956   - ne2000_update_irq(s);
1957   -}
1958   -
1959   -void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
1960   -{
1961   - NE2000State *s = &ne2000_state;
1962   - int offset, page;
1963   -
1964   - addr &= 0xf;
1965   -#ifdef DEBUG_NE2000
1966   - printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
1967   -#endif
1968   - if (addr == E8390_CMD) {
1969   - /* control register */
1970   - s->cmd = val;
1971   - if (val & E8390_START) {
1972   - /* test specific case: zero length transfert */
1973   - if ((val & (E8390_RREAD | E8390_RWRITE)) &&
1974   - s->rcnt == 0) {
1975   - s->isr |= ENISR_RDC;
1976   - ne2000_update_irq(s);
1977   - }
1978   - if (val & E8390_TRANS) {
1979   - net_send_packet(s, s->mem + (s->tpsr << 8), s->tcnt);
1980   - /* signal end of transfert */
1981   - s->tsr = ENTSR_PTX;
1982   - s->isr |= ENISR_TX;
1983   - ne2000_update_irq(s);
1984   - }
1985   - }
1986   - } else {
1987   - page = s->cmd >> 6;
1988   - offset = addr | (page << 4);
1989   - switch(offset) {
1990   - case EN0_STARTPG:
1991   - s->start = val << 8;
1992   - break;
1993   - case EN0_STOPPG:
1994   - s->stop = val << 8;
1995   - break;
1996   - case EN0_BOUNDARY:
1997   - s->boundary = val;
1998   - break;
1999   - case EN0_IMR:
2000   - s->imr = val;
2001   - ne2000_update_irq(s);
2002   - break;
2003   - case EN0_TPSR:
2004   - s->tpsr = val;
2005   - break;
2006   - case EN0_TCNTLO:
2007   - s->tcnt = (s->tcnt & 0xff00) | val;
2008   - break;
2009   - case EN0_TCNTHI:
2010   - s->tcnt = (s->tcnt & 0x00ff) | (val << 8);
2011   - break;
2012   - case EN0_RSARLO:
2013   - s->rsar = (s->rsar & 0xff00) | val;
2014   - break;
2015   - case EN0_RSARHI:
2016   - s->rsar = (s->rsar & 0x00ff) | (val << 8);
2017   - break;
2018   - case EN0_RCNTLO:
2019   - s->rcnt = (s->rcnt & 0xff00) | val;
2020   - break;
2021   - case EN0_RCNTHI:
2022   - s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
2023   - break;
2024   - case EN0_DCFG:
2025   - s->dcfg = val;
2026   - break;
2027   - case EN0_ISR:
2028   - s->isr &= ~val;
2029   - ne2000_update_irq(s);
2030   - break;
2031   - case EN1_PHYS ... EN1_PHYS + 5:
2032   - s->phys[offset - EN1_PHYS] = val;
2033   - break;
2034   - case EN1_CURPAG:
2035   - s->curpag = val;
2036   - break;
2037   - case EN1_MULT ... EN1_MULT + 7:
2038   - s->mult[offset - EN1_MULT] = val;
2039   - break;
2040   - }
2041   - }
2042   -}
2043   -
2044   -uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr)
2045   -{
2046   - NE2000State *s = &ne2000_state;
2047   - int offset, page, ret;
2048   -
2049   - addr &= 0xf;
2050   - if (addr == E8390_CMD) {
2051   - ret = s->cmd;
2052   - } else {
2053   - page = s->cmd >> 6;
2054   - offset = addr | (page << 4);
2055   - switch(offset) {
2056   - case EN0_TSR:
2057   - ret = s->tsr;
2058   - break;
2059   - case EN0_BOUNDARY:
2060   - ret = s->boundary;
2061   - break;
2062   - case EN0_ISR:
2063   - ret = s->isr;
2064   - break;
2065   - case EN1_PHYS ... EN1_PHYS + 5:
2066   - ret = s->phys[offset - EN1_PHYS];
2067   - break;
2068   - case EN1_CURPAG:
2069   - ret = s->curpag;
2070   - break;
2071   - case EN1_MULT ... EN1_MULT + 7:
2072   - ret = s->mult[offset - EN1_MULT];
2073   - break;
2074   - default:
2075   - ret = 0x00;
2076   - break;
2077   - }
2078   - }
2079   -#ifdef DEBUG_NE2000
2080   - printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
2081   -#endif
2082   - return ret;
2083   -}
2084   -
2085   -void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
2086   -{
2087   - NE2000State *s = &ne2000_state;
2088   - uint8_t *p;
2089   -
2090   -#ifdef DEBUG_NE2000
2091   - printf("NE2000: asic write val=0x%04x\n", val);
2092   -#endif
2093   - p = s->mem + s->rsar;
2094   - if (s->dcfg & 0x01) {
2095   - /* 16 bit access */
2096   - p[0] = val;
2097   - p[1] = val >> 8;
2098   - s->rsar += 2;
2099   - s->rcnt -= 2;
2100   - } else {
2101   - /* 8 bit access */
2102   - p[0] = val;
2103   - s->rsar++;
2104   - s->rcnt--;
2105   - }
2106   - /* wrap */
2107   - if (s->rsar == s->stop)
2108   - s->rsar = s->start;
2109   - if (s->rcnt == 0) {
2110   - /* signal end of transfert */
2111   - s->isr |= ENISR_RDC;
2112   - ne2000_update_irq(s);
2113   - }
2114   -}
2115   -
2116   -uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr)
2117   -{
2118   - NE2000State *s = &ne2000_state;
2119   - uint8_t *p;
2120   - int ret;
2121   -
2122   - p = s->mem + s->rsar;
2123   - if (s->dcfg & 0x01) {
2124   - /* 16 bit access */
2125   - ret = p[0] | (p[1] << 8);
2126   - s->rsar += 2;
2127   - s->rcnt -= 2;
2128   - } else {
2129   - /* 8 bit access */
2130   - ret = p[0];
2131   - s->rsar++;
2132   - s->rcnt--;
2133   - }
2134   - /* wrap */
2135   - if (s->rsar == s->stop)
2136   - s->rsar = s->start;
2137   - if (s->rcnt == 0) {
2138   - /* signal end of transfert */
2139   - s->isr |= ENISR_RDC;
2140   - ne2000_update_irq(s);
2141   - }
2142   -#ifdef DEBUG_NE2000
2143   - printf("NE2000: asic read val=0x%04x\n", ret);
2144   -#endif
2145   - return ret;
2146   -}
2147   -
2148   -void ne2000_reset_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
2149   -{
2150   - /* nothing to do (end of reset pulse) */
2151   -}
2152   -
2153   -uint32_t ne2000_reset_ioport_read(CPUState *env, uint32_t addr)
2154   -{
2155   - ne2000_reset();
2156   - return 0;
2157   -}
2158   -
2159   -void ne2000_init(void)
2160   -{
2161   - register_ioport_write(NE2000_IOPORT, 16, ne2000_ioport_write, 1);
2162   - register_ioport_read(NE2000_IOPORT, 16, ne2000_ioport_read, 1);
2163   -
2164   - register_ioport_write(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_write, 1);
2165   - register_ioport_read(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_read, 1);
2166   - register_ioport_write(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_write, 2);
2167   - register_ioport_read(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_read, 2);
2168   -
2169   - register_ioport_write(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_write, 1);
2170   - register_ioport_read(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_read, 1);
2171   - ne2000_reset();
2172   -}
2173   -#endif
2174   -
2175   -/***********************************************************/
2176   -/* PC floppy disk controler emulation glue */
2177   -#define PC_FDC_DMA 0x2
2178   -#define PC_FDC_IRQ 0x6
2179   -#define PC_FDC_BASE 0x3F0
2180   -
2181   -static void fdctrl_register (unsigned char **disknames, int ro,
2182   - char boot_device)
2183   -{
2184   - int i;
2185   -
2186   - fdctrl_init(PC_FDC_IRQ, PC_FDC_DMA, 0, PC_FDC_BASE, boot_device);
2187   - for (i = 0; i < MAX_FD; i++) {
2188   - if (disknames[i] != NULL)
2189   - fdctrl_disk_change(i, disknames[i], ro);
2190   - }
2191   -}
2192   -
2193   -/***********************************************************/
2194   -/* keyboard emulation */
2195   -
2196   -/* Keyboard Controller Commands */
2197   -#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
2198   -#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
2199   -#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
2200   -#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
2201   -#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
2202   -#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
2203   -#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
2204   -#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
2205   -#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
2206   -#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
2207   -#define KBD_CCMD_READ_INPORT 0xC0 /* read input port */
2208   -#define KBD_CCMD_READ_OUTPORT 0xD0 /* read output port */
2209   -#define KBD_CCMD_WRITE_OUTPORT 0xD1 /* write output port */
2210   -#define KBD_CCMD_WRITE_OBUF 0xD2
2211   -#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
2212   - initiated by the auxiliary device */
2213   -#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
2214   -#define KBD_CCMD_DISABLE_A20 0xDD /* HP vectra only ? */
2215   -#define KBD_CCMD_ENABLE_A20 0xDF /* HP vectra only ? */
2216   -#define KBD_CCMD_RESET 0xFE
2217   -
2218   -/* Keyboard Commands */
2219   -#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
2220   -#define KBD_CMD_ECHO 0xEE
2221   -#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
2222   -#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
2223   -#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
2224   -#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
2225   -#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
2226   -#define KBD_CMD_RESET 0xFF /* Reset */
2227   -
2228   -/* Keyboard Replies */
2229   -#define KBD_REPLY_POR 0xAA /* Power on reset */
2230   -#define KBD_REPLY_ACK 0xFA /* Command ACK */
2231   -#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
2232   -
2233   -/* Status Register Bits */
2234   -#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
2235   -#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
2236   -#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
2237   -#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
2238   -#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
2239   -#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
2240   -#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
2241   -#define KBD_STAT_PERR 0x80 /* Parity error */
2242   -
2243   -/* Controller Mode Register Bits */
2244   -#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
2245   -#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
2246   -#define KBD_MODE_SYS 0x04 /* The system flag (?) */
2247   -#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
2248   -#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
2249   -#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
2250   -#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
2251   -#define KBD_MODE_RFU 0x80
2252   -
2253   -/* Mouse Commands */
2254   -#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
2255   -#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
2256   -#define AUX_SET_RES 0xE8 /* Set resolution */
2257   -#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
2258   -#define AUX_SET_STREAM 0xEA /* Set stream mode */
2259   -#define AUX_POLL 0xEB /* Poll */
2260   -#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
2261   -#define AUX_SET_WRAP 0xEE /* Set wrap mode */
2262   -#define AUX_SET_REMOTE 0xF0 /* Set remote mode */
2263   -#define AUX_GET_TYPE 0xF2 /* Get type */
2264   -#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
2265   -#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
2266   -#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
2267   -#define AUX_SET_DEFAULT 0xF6
2268   -#define AUX_RESET 0xFF /* Reset aux device */
2269   -#define AUX_ACK 0xFA /* Command byte ACK. */
2270   -
2271   -#define MOUSE_STATUS_REMOTE 0x40
2272   -#define MOUSE_STATUS_ENABLED 0x20
2273   -#define MOUSE_STATUS_SCALE21 0x10
2274   -
2275   -#define KBD_QUEUE_SIZE 256
2276   -
2277   -typedef struct {
2278   - uint8_t data[KBD_QUEUE_SIZE];
2279   - int rptr, wptr, count;
2280   -} KBDQueue;
2281   -
2282   -typedef struct KBDState {
2283   - KBDQueue queues[2];
2284   - uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
2285   - uint8_t status;
2286   - uint8_t mode;
2287   - /* keyboard state */
2288   - int kbd_write_cmd;
2289   - int scan_enabled;
2290   - /* mouse state */
2291   - int mouse_write_cmd;
2292   - uint8_t mouse_status;
2293   - uint8_t mouse_resolution;
2294   - uint8_t mouse_sample_rate;
2295   - uint8_t mouse_wrap;
2296   - uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
2297   - uint8_t mouse_detect_state;
2298   - int mouse_dx; /* current values, needed for 'poll' mode */
2299   - int mouse_dy;
2300   - int mouse_dz;
2301   - uint8_t mouse_buttons;
2302   -} KBDState;
2303   -
2304   -KBDState kbd_state;
2305   -int reset_requested;
2306   -
2307   -/* update irq and KBD_STAT_[MOUSE_]OBF */
2308   -/* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
2309   - incorrect, but it avoids having to simulate exact delays */
2310   -static void kbd_update_irq(KBDState *s)
2311   -{
2312   - int irq12_level, irq1_level;
2313   -
2314   - irq1_level = 0;
2315   - irq12_level = 0;
2316   - s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
2317   - if (s->queues[0].count != 0 ||
2318   - s->queues[1].count != 0) {
2319   - s->status |= KBD_STAT_OBF;
2320   - if (s->queues[1].count != 0) {
2321   - s->status |= KBD_STAT_MOUSE_OBF;
2322   - if (s->mode & KBD_MODE_MOUSE_INT)
2323   - irq12_level = 1;
2324   - } else {
2325   - if ((s->mode & KBD_MODE_KBD_INT) &&
2326   - !(s->mode & KBD_MODE_DISABLE_KBD))
2327   - irq1_level = 1;
2328   - }
2329   - }
2330   - pic_set_irq(1, irq1_level);
2331   - pic_set_irq(12, irq12_level);
2332   -}
2333   -
2334   -static void kbd_queue(KBDState *s, int b, int aux)
2335   -{
2336   - KBDQueue *q = &kbd_state.queues[aux];
2337   -
2338   -#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
2339   - if (aux)
2340   - printf("mouse event: 0x%02x\n", b);
2341   -#ifdef DEBUG_KBD
2342   - else
2343   - printf("kbd event: 0x%02x\n", b);
2344   -#endif
2345   -#endif
2346   - if (q->count >= KBD_QUEUE_SIZE)
2347   - return;
2348   - q->data[q->wptr] = b;
2349   - if (++q->wptr == KBD_QUEUE_SIZE)
2350   - q->wptr = 0;
2351   - q->count++;
2352   - kbd_update_irq(s);
2353   -}
2354   -
2355   -void kbd_put_keycode(int keycode)
2356   -{
2357   - KBDState *s = &kbd_state;
2358   - kbd_queue(s, keycode, 0);
2359   -}
  409 + { NULL, NULL, },
  410 +};
2360 411  
2361   -uint32_t kbd_read_status(CPUState *env, uint32_t addr)
  412 +void term_print_help(void)
2362 413 {
2363   - KBDState *s = &kbd_state;
2364   - int val;
2365   - val = s->status;
2366   -#if defined(DEBUG_KBD)
2367   - printf("kbd: read status=0x%02x\n", val);
2368   -#endif
2369   - return val;
  414 + printf("\n"
  415 + "C-a h print this help\n"
  416 + "C-a x exit emulatior\n"
  417 + "C-a d switch on/off debug log\n"
  418 + "C-a s save disk data back to file (if -snapshot)\n"
  419 + "C-a b send break (magic sysrq)\n"
  420 + "C-a c send qemu internal command\n"
  421 + "C-a C-a send C-a\n"
  422 + );
2370 423 }
2371 424  
2372   -void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val)
  425 +static void do_change_cdrom (unsigned char *params)
2373 426 {
2374   - KBDState *s = &kbd_state;
2375   -
2376   -#ifdef DEBUG_KBD
2377   - printf("kbd: write cmd=0x%02x\n", val);
2378   -#endif
2379   - switch(val) {
2380   - case KBD_CCMD_READ_MODE:
2381   - kbd_queue(s, s->mode, 0);
2382   - break;
2383   - case KBD_CCMD_WRITE_MODE:
2384   - case KBD_CCMD_WRITE_OBUF:
2385   - case KBD_CCMD_WRITE_AUX_OBUF:
2386   - case KBD_CCMD_WRITE_MOUSE:
2387   - case KBD_CCMD_WRITE_OUTPORT:
2388   - s->write_cmd = val;
2389   - break;
2390   - case KBD_CCMD_MOUSE_DISABLE:
2391   - s->mode |= KBD_MODE_DISABLE_MOUSE;
2392   - break;
2393   - case KBD_CCMD_MOUSE_ENABLE:
2394   - s->mode &= ~KBD_MODE_DISABLE_MOUSE;
2395   - break;
2396   - case KBD_CCMD_TEST_MOUSE:
2397   - kbd_queue(s, 0x00, 0);
2398   - break;
2399   - case KBD_CCMD_SELF_TEST:
2400   - s->status |= KBD_STAT_SELFTEST;
2401   - kbd_queue(s, 0x55, 0);
2402   - break;
2403   - case KBD_CCMD_KBD_TEST:
2404   - kbd_queue(s, 0x00, 0);
2405   - break;
2406   - case KBD_CCMD_KBD_DISABLE:
2407   - s->mode |= KBD_MODE_DISABLE_KBD;
2408   - kbd_update_irq(s);
2409   - break;
2410   - case KBD_CCMD_KBD_ENABLE:
2411   - s->mode &= ~KBD_MODE_DISABLE_KBD;
2412   - kbd_update_irq(s);
2413   - break;
2414   - case KBD_CCMD_READ_INPORT:
2415   - kbd_queue(s, 0x00, 0);
2416   - break;
2417   - case KBD_CCMD_READ_OUTPORT:
2418   - /* XXX: check that */
2419   -#ifdef TARGET_I386
2420   - val = 0x01 | (((cpu_single_env->a20_mask >> 20) & 1) << 1);
2421   -#else
2422   - val = 0x01;
2423   -#endif
2424   - if (s->status & KBD_STAT_OBF)
2425   - val |= 0x10;
2426   - if (s->status & KBD_STAT_MOUSE_OBF)
2427   - val |= 0x20;
2428   - kbd_queue(s, val, 0);
2429   - break;
2430   -#ifdef TARGET_I386
2431   - case KBD_CCMD_ENABLE_A20:
2432   - cpu_x86_set_a20(env, 1);
2433   - break;
2434   - case KBD_CCMD_DISABLE_A20:
2435   - cpu_x86_set_a20(env, 0);
2436   - break;
2437   -#endif
2438   - case KBD_CCMD_RESET:
2439   - reset_requested = 1;
2440   - cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
2441   - break;
2442   - case 0xff:
2443   - /* ignore that - I don't know what is its use */
2444   - break;
2445   - default:
2446   - fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val);
2447   - break;
2448   - }
  427 + /* Dunno how to do it... */
2449 428 }
2450 429  
2451   -uint32_t kbd_read_data(CPUState *env, uint32_t addr)
  430 +static void do_change_fd (int fd, unsigned char *params)
2452 431 {
2453   - KBDState *s = &kbd_state;
2454   - KBDQueue *q;
2455   - int val, index;
2456   -
2457   - q = &s->queues[0]; /* first check KBD data */
2458   - if (q->count == 0)
2459   - q = &s->queues[1]; /* then check AUX data */
2460   - if (q->count == 0) {
2461   - /* NOTE: if no data left, we return the last keyboard one
2462   - (needed for EMM386) */
2463   - /* XXX: need a timer to do things correctly */
2464   - q = &s->queues[0];
2465   - index = q->rptr - 1;
2466   - if (index < 0)
2467   - index = KBD_QUEUE_SIZE - 1;
2468   - val = q->data[index];
2469   - } else {
2470   - val = q->data[q->rptr];
2471   - if (++q->rptr == KBD_QUEUE_SIZE)
2472   - q->rptr = 0;
2473   - q->count--;
2474   - /* reading deasserts IRQ */
2475   - if (q == &s->queues[0])
2476   - pic_set_irq(1, 0);
2477   - else
2478   - pic_set_irq(12, 0);
2479   - }
2480   - /* reassert IRQs if data left */
2481   - kbd_update_irq(s);
2482   -#ifdef DEBUG_KBD
2483   - printf("kbd: read data=0x%02x\n", val);
2484   -#endif
2485   - return val;
2486   -}
  432 + unsigned char *name_start, *name_end, *ros;
  433 + int ro;
2487 434  
2488   -static void kbd_reset_keyboard(KBDState *s)
2489   -{
2490   - s->scan_enabled = 1;
  435 + for (name_start = params;
  436 + isspace(*name_start); name_start++)
  437 + continue;
  438 + if (*name_start == '\0')
  439 + return;
  440 + for (name_end = name_start;
  441 + !isspace(*name_end) && *name_end != '\0'; name_end++)
  442 + continue;
  443 + for (ros = name_end + 1; isspace(*ros); ros++)
  444 + continue;
  445 + if (ros[0] == 'r' && ros[1] == 'o')
  446 + ro = 1;
  447 + else
  448 + ro = 0;
  449 + *name_end = '\0';
  450 + printf("Change fd %d to %s (%s)\n", fd, name_start, params);
  451 + fdctrl_disk_change(fd, name_start, ro);
2491 452 }
2492 453  
2493   -static void kbd_write_keyboard(KBDState *s, int val)
  454 +static void do_change_fd0 (unsigned char *params)
2494 455 {
2495   - switch(s->kbd_write_cmd) {
2496   - default:
2497   - case -1:
2498   - switch(val) {
2499   - case 0x00:
2500   - kbd_queue(s, KBD_REPLY_ACK, 0);
2501   - break;
2502   - case 0x05:
2503   - kbd_queue(s, KBD_REPLY_RESEND, 0);
2504   - break;
2505   - case KBD_CMD_GET_ID:
2506   - kbd_queue(s, KBD_REPLY_ACK, 0);
2507   - kbd_queue(s, 0xab, 0);
2508   - kbd_queue(s, 0x83, 0);
2509   - break;
2510   - case KBD_CMD_ECHO:
2511   - kbd_queue(s, KBD_CMD_ECHO, 0);
2512   - break;
2513   - case KBD_CMD_ENABLE:
2514   - s->scan_enabled = 1;
2515   - kbd_queue(s, KBD_REPLY_ACK, 0);
2516   - break;
2517   - case KBD_CMD_SET_LEDS:
2518   - case KBD_CMD_SET_RATE:
2519   - s->kbd_write_cmd = val;
2520   - kbd_queue(s, KBD_REPLY_ACK, 0);
2521   - break;
2522   - case KBD_CMD_RESET_DISABLE:
2523   - kbd_reset_keyboard(s);
2524   - s->scan_enabled = 0;
2525   - kbd_queue(s, KBD_REPLY_ACK, 0);
2526   - break;
2527   - case KBD_CMD_RESET_ENABLE:
2528   - kbd_reset_keyboard(s);
2529   - s->scan_enabled = 1;
2530   - kbd_queue(s, KBD_REPLY_ACK, 0);
2531   - break;
2532   - case KBD_CMD_RESET:
2533   - kbd_reset_keyboard(s);
2534   - kbd_queue(s, KBD_REPLY_ACK, 0);
2535   - kbd_queue(s, KBD_REPLY_POR, 0);
2536   - break;
2537   - default:
2538   - kbd_queue(s, KBD_REPLY_ACK, 0);
2539   - break;
2540   - }
2541   - break;
2542   - case KBD_CMD_SET_LEDS:
2543   - kbd_queue(s, KBD_REPLY_ACK, 0);
2544   - s->kbd_write_cmd = -1;
2545   - break;
2546   - case KBD_CMD_SET_RATE:
2547   - kbd_queue(s, KBD_REPLY_ACK, 0);
2548   - s->kbd_write_cmd = -1;
2549   - break;
2550   - }
  456 + do_change_fd(0, params);
2551 457 }
2552 458  
2553   -static void kbd_mouse_send_packet(KBDState *s)
  459 +static void do_change_fd1 (unsigned char *params)
2554 460 {
2555   - unsigned int b;
2556   - int dx1, dy1, dz1;
2557   -
2558   - dx1 = s->mouse_dx;
2559   - dy1 = s->mouse_dy;
2560   - dz1 = s->mouse_dz;
2561   - /* XXX: increase range to 8 bits ? */
2562   - if (dx1 > 127)
2563   - dx1 = 127;
2564   - else if (dx1 < -127)
2565   - dx1 = -127;
2566   - if (dy1 > 127)
2567   - dy1 = 127;
2568   - else if (dy1 < -127)
2569   - dy1 = -127;
2570   - b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
2571   - kbd_queue(s, b, 1);
2572   - kbd_queue(s, dx1 & 0xff, 1);
2573   - kbd_queue(s, dy1 & 0xff, 1);
2574   - /* extra byte for IMPS/2 or IMEX */
2575   - switch(s->mouse_type) {
2576   - default:
2577   - break;
2578   - case 3:
2579   - if (dz1 > 127)
2580   - dz1 = 127;
2581   - else if (dz1 < -127)
2582   - dz1 = -127;
2583   - kbd_queue(s, dz1 & 0xff, 1);
2584   - break;
2585   - case 4:
2586   - if (dz1 > 7)
2587   - dz1 = 7;
2588   - else if (dz1 < -7)
2589   - dz1 = -7;
2590   - b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
2591   - kbd_queue(s, b, 1);
2592   - break;
2593   - }
2594   -
2595   - /* update deltas */
2596   - s->mouse_dx -= dx1;
2597   - s->mouse_dy -= dy1;
2598   - s->mouse_dz -= dz1;
  461 + do_change_fd(1, params);
2599 462 }
2600 463  
2601   -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
  464 +static void term_treat_command(void)
2602 465 {
2603   - KBDState *s = &kbd_state;
2604   -
2605   - /* check if deltas are recorded when disabled */
2606   - if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
2607   - return;
  466 + unsigned char *cmd_start, *cmd_end;
  467 + int i;
2608 468  
2609   - s->mouse_dx += dx;
2610   - s->mouse_dy -= dy;
2611   - s->mouse_dz += dz;
2612   - s->mouse_buttons = buttons_state;
2613   -
2614   - if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
2615   - (s->queues[1].count < (KBD_QUEUE_SIZE - 16))) {
2616   - for(;;) {
2617   - /* if not remote, send event. Multiple events are sent if
2618   - too big deltas */
2619   - kbd_mouse_send_packet(s);
2620   - if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
2621   - break;
  469 + for (cmd_start = term_cmd_buf; isspace(*cmd_start); cmd_start++)
  470 + continue;
  471 + for (cmd_end = cmd_start;
  472 + !isspace(*cmd_end) && *cmd_end != '\0'; cmd_end++)
  473 + continue;
  474 + for (i = 0; term_cmds[i].name != NULL; i++) {
  475 + if (strlen(term_cmds[i].name) == (cmd_end - cmd_start) &&
  476 + memcmp(term_cmds[i].name, cmd_start, cmd_end - cmd_start) == 0) {
  477 + (*term_cmds[i].handler)(cmd_end + 1);
  478 + return;
2622 479 }
2623 480 }
  481 + *cmd_end = '\0';
  482 + printf("Unknown term command: %s\n", cmd_start);
2624 483 }
2625 484  
2626   -static void kbd_write_mouse(KBDState *s, int val)
  485 +extern FILE *logfile;
  486 +
  487 +/* called when a char is received */
  488 +void term_received_byte(int ch)
2627 489 {
2628   -#ifdef DEBUG_MOUSE
2629   - printf("kbd: write mouse 0x%02x\n", val);
2630   -#endif
2631   - switch(s->mouse_write_cmd) {
2632   - default:
2633   - case -1:
2634   - /* mouse command */
2635   - if (s->mouse_wrap) {
2636   - if (val == AUX_RESET_WRAP) {
2637   - s->mouse_wrap = 0;
2638   - kbd_queue(s, AUX_ACK, 1);
2639   - return;
2640   - } else if (val != AUX_RESET) {
2641   - kbd_queue(s, val, 1);
2642   - return;
  490 + if (term_command) {
  491 + if (ch == '\n' || ch == '\r' || term_command == 127) {
  492 + printf("\n");
  493 + term_treat_command();
  494 + term_command = 0;
  495 + } else {
  496 + if (ch == 0x7F || ch == 0x08) {
  497 + if (term_command > 1) {
  498 + term_cmd_buf[--term_command - 1] = '\0';
  499 + printf("\r "
  500 + " ");
  501 + printf("\r> %s", term_cmd_buf);
  502 + }
  503 + } else if (ch > 0x1f) {
  504 + term_cmd_buf[term_command++ - 1] = ch;
  505 + term_cmd_buf[term_command - 1] = '\0';
  506 + printf("\r> %s", term_cmd_buf);
2643 507 }
  508 + fflush(stdout);
2644 509 }
2645   - switch(val) {
2646   - case AUX_SET_SCALE11:
2647   - s->mouse_status &= ~MOUSE_STATUS_SCALE21;
2648   - kbd_queue(s, AUX_ACK, 1);
2649   - break;
2650   - case AUX_SET_SCALE21:
2651   - s->mouse_status |= MOUSE_STATUS_SCALE21;
2652   - kbd_queue(s, AUX_ACK, 1);
2653   - break;
2654   - case AUX_SET_STREAM:
2655   - s->mouse_status &= ~MOUSE_STATUS_REMOTE;
2656   - kbd_queue(s, AUX_ACK, 1);
2657   - break;
2658   - case AUX_SET_WRAP:
2659   - s->mouse_wrap = 1;
2660   - kbd_queue(s, AUX_ACK, 1);
2661   - break;
2662   - case AUX_SET_REMOTE:
2663   - s->mouse_status |= MOUSE_STATUS_REMOTE;
2664   - kbd_queue(s, AUX_ACK, 1);
2665   - break;
2666   - case AUX_GET_TYPE:
2667   - kbd_queue(s, AUX_ACK, 1);
2668   - kbd_queue(s, s->mouse_type, 1);
2669   - break;
2670   - case AUX_SET_RES:
2671   - case AUX_SET_SAMPLE:
2672   - s->mouse_write_cmd = val;
2673   - kbd_queue(s, AUX_ACK, 1);
2674   - break;
2675   - case AUX_GET_SCALE:
2676   - kbd_queue(s, AUX_ACK, 1);
2677   - kbd_queue(s, s->mouse_status, 1);
2678   - kbd_queue(s, s->mouse_resolution, 1);
2679   - kbd_queue(s, s->mouse_sample_rate, 1);
2680   - break;
2681   - case AUX_POLL:
2682   - kbd_queue(s, AUX_ACK, 1);
2683   - kbd_mouse_send_packet(s);
2684   - break;
2685   - case AUX_ENABLE_DEV:
2686   - s->mouse_status |= MOUSE_STATUS_ENABLED;
2687   - kbd_queue(s, AUX_ACK, 1);
2688   - break;
2689   - case AUX_DISABLE_DEV:
2690   - s->mouse_status &= ~MOUSE_STATUS_ENABLED;
2691   - kbd_queue(s, AUX_ACK, 1);
2692   - break;
2693   - case AUX_SET_DEFAULT:
2694   - s->mouse_sample_rate = 100;
2695   - s->mouse_resolution = 2;
2696   - s->mouse_status = 0;
2697   - kbd_queue(s, AUX_ACK, 1);
2698   - break;
2699   - case AUX_RESET:
2700   - s->mouse_sample_rate = 100;
2701   - s->mouse_resolution = 2;
2702   - s->mouse_status = 0;
2703   - kbd_queue(s, AUX_ACK, 1);
2704   - kbd_queue(s, 0xaa, 1);
2705   - kbd_queue(s, s->mouse_type, 1);
  510 + } else if (term_got_escape) {
  511 + term_got_escape = 0;
  512 + switch(ch) {
  513 + case 'h':
  514 + term_print_help();
2706 515 break;
2707   - default:
  516 + case 'x':
  517 + exit(0);
2708 518 break;
2709   - }
2710   - break;
2711   - case AUX_SET_SAMPLE:
2712   - s->mouse_sample_rate = val;
2713   -#if 0
2714   - /* detect IMPS/2 or IMEX */
2715   - switch(s->mouse_detect_state) {
2716   - default:
2717   - case 0:
2718   - if (val == 200)
2719   - s->mouse_detect_state = 1;
  519 + case 's':
  520 + {
  521 + int i;
  522 + for (i = 0; i < MAX_DISKS; i++) {
  523 + if (bs_table[i])
  524 + bdrv_commit(bs_table[i]);
  525 + }
  526 + }
2720 527 break;
2721   - case 1:
2722   - if (val == 100)
2723   - s->mouse_detect_state = 2;
2724   - else if (val == 200)
2725   - s->mouse_detect_state = 3;
2726   - else
2727   - s->mouse_detect_state = 0;
  528 + case 'b':
  529 + serial_receive_break();
2728 530 break;
2729   - case 2:
2730   - if (val == 80)
2731   - s->mouse_type = 3; /* IMPS/2 */
2732   - s->mouse_detect_state = 0;
  531 + case 'c':
  532 + printf("> ");
  533 + fflush(stdout);
  534 + term_command = 1;
2733 535 break;
2734   - case 3:
2735   - if (val == 80)
2736   - s->mouse_type = 4; /* IMEX */
2737   - s->mouse_detect_state = 0;
  536 + case 'd':
  537 + cpu_set_log(CPU_LOG_ALL);
2738 538 break;
  539 + case TERM_ESCAPE:
  540 + goto send_char;
2739 541 }
2740   -#endif
2741   - kbd_queue(s, AUX_ACK, 1);
2742   - s->mouse_write_cmd = -1;
2743   - break;
2744   - case AUX_SET_RES:
2745   - s->mouse_resolution = val;
2746   - kbd_queue(s, AUX_ACK, 1);
2747   - s->mouse_write_cmd = -1;
2748   - break;
  542 + } else if (ch == TERM_ESCAPE) {
  543 + term_got_escape = 1;
  544 + } else {
  545 + send_char:
  546 + serial_receive_byte(ch);
2749 547 }
2750 548 }
2751 549  
2752   -void kbd_write_data(CPUState *env, uint32_t addr, uint32_t val)
2753   -{
2754   - KBDState *s = &kbd_state;
2755   -
2756   -#ifdef DEBUG_KBD
2757   - printf("kbd: write data=0x%02x\n", val);
2758   -#endif
2759   -
2760   - switch(s->write_cmd) {
2761   - case 0:
2762   - kbd_write_keyboard(s, val);
2763   - break;
2764   - case KBD_CCMD_WRITE_MODE:
2765   - s->mode = val;
2766   - kbd_update_irq(s);
2767   - break;
2768   - case KBD_CCMD_WRITE_OBUF:
2769   - kbd_queue(s, val, 0);
2770   - break;
2771   - case KBD_CCMD_WRITE_AUX_OBUF:
2772   - kbd_queue(s, val, 1);
2773   - break;
2774   - case KBD_CCMD_WRITE_OUTPORT:
2775   -#ifdef TARGET_I386
2776   - cpu_x86_set_a20(env, (val >> 1) & 1);
2777   -#endif
2778   - if (!(val & 1)) {
2779   - reset_requested = 1;
2780   - cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
2781   - }
2782   - break;
2783   - case KBD_CCMD_WRITE_MOUSE:
2784   - kbd_write_mouse(s, val);
2785   - break;
2786   - default:
2787   - break;
2788   - }
2789   - s->write_cmd = 0;
2790   -}
  550 +/***********************************************************/
  551 +/* Linux network device redirector */
2791 552  
2792   -void kbd_reset(KBDState *s)
  553 +int net_init(void)
2793 554 {
2794   - KBDQueue *q;
2795   - int i;
2796   -
2797   - s->kbd_write_cmd = -1;
2798   - s->mouse_write_cmd = -1;
2799   - s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
2800   - s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
2801   - for(i = 0; i < 2; i++) {
2802   - q = &s->queues[i];
2803   - q->rptr = 0;
2804   - q->wptr = 0;
2805   - q->count = 0;
  555 + struct ifreq ifr;
  556 + int fd, ret, pid, status;
  557 +
  558 + fd = open("/dev/net/tun", O_RDWR);
  559 + if (fd < 0) {
  560 + fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
  561 + return -1;
2806 562 }
2807   -}
2808   -
2809   -void kbd_init(void)
2810   -{
2811   - kbd_reset(&kbd_state);
2812   -#if defined (TARGET_I386) || defined (TARGET_PPC)
2813   - register_ioport_read(0x60, 1, kbd_read_data, 1);
2814   - register_ioport_write(0x60, 1, kbd_write_data, 1);
2815   - register_ioport_read(0x64, 1, kbd_read_status, 1);
2816   - register_ioport_write(0x64, 1, kbd_write_command, 1);
2817   -#endif
2818   -}
2819   -
2820   -/***********************************************************/
2821   -/* Bochs BIOS debug ports */
2822   -#ifdef TARGET_I386
2823   -void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val)
2824   -{
2825   - switch(addr) {
2826   - /* Bochs BIOS messages */
2827   - case 0x400:
2828   - case 0x401:
2829   - fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
2830   - exit(1);
2831   - case 0x402:
2832   - case 0x403:
2833   -#ifdef DEBUG_BIOS
2834   - fprintf(stderr, "%c", val);
2835   -#endif
2836   - break;
  563 + memset(&ifr, 0, sizeof(ifr));
  564 + ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  565 + pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
  566 + ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
  567 + if (ret != 0) {
  568 + fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
  569 + close(fd);
  570 + return -1;
  571 + }
  572 + printf("Connected to host network interface: %s\n", ifr.ifr_name);
  573 + fcntl(fd, F_SETFL, O_NONBLOCK);
  574 + net_fd = fd;
2837 575  
2838   - /* LGPL'ed VGA BIOS messages */
2839   - case 0x501:
2840   - case 0x502:
2841   - fprintf(stderr, "VGA BIOS panic, line %d\n", val);
2842   - exit(1);
2843   - case 0x500:
2844   - case 0x503:
2845   -#ifdef DEBUG_BIOS
2846   - fprintf(stderr, "%c", val);
2847   -#endif
2848   - break;
  576 + /* try to launch network init script */
  577 + pid = fork();
  578 + if (pid >= 0) {
  579 + if (pid == 0) {
  580 + execl(network_script, network_script, ifr.ifr_name, NULL);
  581 + exit(1);
  582 + }
  583 + while (waitpid(pid, &status, 0) != pid);
  584 + if (!WIFEXITED(status) ||
  585 + WEXITSTATUS(status) != 0) {
  586 + fprintf(stderr, "%s: could not launch network script for '%s'\n",
  587 + network_script, ifr.ifr_name);
  588 + }
2849 589 }
  590 + return 0;
2850 591 }
2851 592  
2852   -void bochs_bios_init(void)
  593 +void net_send_packet(int net_fd, const uint8_t *buf, int size)
2853 594 {
2854   - register_ioport_write(0x400, 1, bochs_bios_write, 2);
2855   - register_ioport_write(0x401, 1, bochs_bios_write, 2);
2856   - register_ioport_write(0x402, 1, bochs_bios_write, 1);
2857   - register_ioport_write(0x403, 1, bochs_bios_write, 1);
2858   -
2859   - register_ioport_write(0x501, 1, bochs_bios_write, 2);
2860   - register_ioport_write(0x502, 1, bochs_bios_write, 2);
2861   - register_ioport_write(0x500, 1, bochs_bios_write, 1);
2862   - register_ioport_write(0x503, 1, bochs_bios_write, 1);
2863   -}
  595 +#ifdef DEBUG_NE2000
  596 + printf("NE2000: sending packet size=%d\n", size);
2864 597 #endif
  598 + write(net_fd, buf, size);
  599 +}
2865 600  
2866 601 /***********************************************************/
2867 602 /* dumb display */
... ... @@ -3015,7 +750,7 @@ int main_loop(void *opaque)
3015 750 /* poll any events */
3016 751 serial_ufd = NULL;
3017 752 pf = ufds;
3018   - if (serial_ok && !(serial_ports[0].lsr & UART_LSR_DR)) {
  753 + if (serial_ok && serial_can_receive()) {
3019 754 serial_ufd = pf;
3020 755 pf->fd = 0;
3021 756 pf->events = POLLIN;
... ... @@ -3023,7 +758,7 @@ int main_loop(void *opaque)
3023 758 }
3024 759 #if defined (TARGET_I386)
3025 760 net_ufd = NULL;
3026   - if (net_fd > 0 && ne2000_can_receive(&ne2000_state)) {
  761 + if (net_fd > 0 && ne2000_can_receive()) {
3027 762 net_ufd = pf;
3028 763 pf->fd = net_fd;
3029 764 pf->events = POLLIN;
... ... @@ -3043,7 +778,7 @@ int main_loop(void *opaque)
3043 778 if (serial_ufd && (serial_ufd->revents & POLLIN)) {
3044 779 n = read(0, &ch, 1);
3045 780 if (n == 1) {
3046   - serial_received_byte(&serial_ports[0], ch);
  781 + term_received_byte(ch);
3047 782 } else {
3048 783 /* Closed, stop polling. */
3049 784 serial_ok = 0;
... ... @@ -3059,7 +794,7 @@ int main_loop(void *opaque)
3059 794 memset(buf + n, 0, 60 - n);
3060 795 n = 60;
3061 796 }
3062   - ne2000_receive(&ne2000_state, buf, n);
  797 + ne2000_receive(buf, n);
3063 798 }
3064 799 }
3065 800 #endif
... ... @@ -3080,10 +815,7 @@ int main_loop(void *opaque)
3080 815 pic_set_irq(0, 1);
3081 816 pic_set_irq(0, 0);
3082 817 timer_irq_pending = 0;
3083   - /* XXX: RTC test */
3084   - if (cmos_data[RTC_REG_B] & 0x50) {
3085   - pic_set_irq(8, 1);
3086   - }
  818 + rtc_timer();
3087 819 #endif
3088 820 }
3089 821 /* XXX: add explicit timer */
... ... @@ -3199,7 +931,7 @@ static uint8_t *signal_stack;
3199 931  
3200 932 int main(int argc, char **argv)
3201 933 {
3202   - int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
  934 + int c, i, use_gdbstub, gdbstub_port, long_index;
3203 935 int snapshot, linux_boot;
3204 936 struct sigaction act;
3205 937 struct itimerval itv;
... ... @@ -3207,7 +939,6 @@ int main(int argc, char **argv)
3207 939 const char *initrd_filename;
3208 940 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
3209 941 const char *kernel_filename, *kernel_cmdline;
3210   - char buf[1024];
3211 942 DisplayState *ds = &display_state;
3212 943  
3213 944 /* we never want that malloc() uses mmap() */
... ... @@ -3438,92 +1169,7 @@ int main(int argc, char **argv)
3438 1169 cpu_single_env = env;
3439 1170  
3440 1171 init_ioports();
3441   -
3442   - /* allocate RAM */
3443   - cpu_register_physical_memory(0, ram_size, 0);
3444   -
3445   -#if defined(TARGET_I386)
3446   - /* RAW PC boot */
3447   -
3448   - /* BIOS load */
3449   - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
3450   - ret = load_image(buf, phys_ram_base + 0x000f0000);
3451   - if (ret != 0x10000) {
3452   - fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
3453   - exit(1);
3454   - }
3455   -
3456   - /* VGA BIOS load */
3457   - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
3458   - ret = load_image(buf, phys_ram_base + 0x000c0000);
3459   -
3460   - /* setup basic memory access */
3461   - cpu_register_physical_memory(0xc0000, 0x10000, 0xc0000 | IO_MEM_ROM);
3462   - cpu_register_physical_memory(0xf0000, 0x10000, 0xf0000 | IO_MEM_ROM);
3463   -
3464   - bochs_bios_init();
3465   -
3466   - if (linux_boot) {
3467   - uint8_t bootsect[512];
3468   -
3469   - if (bs_table[0] == NULL) {
3470   - fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n");
3471   - exit(1);
3472   - }
3473   - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
3474   - ret = load_image(buf, bootsect);
3475   - if (ret != sizeof(bootsect)) {
3476   - fprintf(stderr, "qemu: could not load linux boot sector '%s'\n",
3477   - buf);
3478   - exit(1);
3479   - }
3480   -
3481   - bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
3482   -
3483   - /* now we can load the kernel */
3484   - ret = load_kernel(kernel_filename,
3485   - phys_ram_base + KERNEL_LOAD_ADDR,
3486   - phys_ram_base + KERNEL_PARAMS_ADDR);
3487   - if (ret < 0) {
3488   - fprintf(stderr, "qemu: could not load kernel '%s'\n",
3489   - kernel_filename);
3490   - exit(1);
3491   - }
3492   -
3493   - /* load initrd */
3494   - initrd_size = 0;
3495   - if (initrd_filename) {
3496   - initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
3497   - if (initrd_size < 0) {
3498   - fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
3499   - initrd_filename);
3500   - exit(1);
3501   - }
3502   - }
3503   - if (initrd_size > 0) {
3504   - stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR);
3505   - stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
3506   - }
3507   - pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
3508   - kernel_cmdline);
3509   - stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
3510   - stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
3511   - KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
3512   - /* loader type */
3513   - stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
3514   - }
3515   -#elif defined(TARGET_PPC)
3516   - /* allocate ROM */
3517   - // snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
3518   - snprintf(buf, sizeof(buf), "%s", BIOS_FILENAME);
3519   - printf("load BIOS at %p\n", phys_ram_base + 0x000f0000);
3520   - ret = load_image(buf, phys_ram_base + 0x000f0000);
3521   - if (ret != 0x10000) {
3522   - fprintf(stderr, "qemu: could not load PPC bios '%s' (%d)\n%m\n",
3523   - buf, ret);
3524   - exit(1);
3525   - }
3526   -#endif
  1172 + cpu_calibrate_ticks();
3527 1173  
3528 1174 /* terminal init */
3529 1175 if (nographic) {
... ... @@ -3535,31 +1181,14 @@ int main(int argc, char **argv)
3535 1181 dumb_display_init(ds);
3536 1182 #endif
3537 1183 }
3538   - /* init basic PC hardware */
3539   - register_ioport_write(0x80, 1, ioport80_write, 1);
3540 1184  
3541   - vga_initialize(ds, phys_ram_base + ram_size, ram_size,
3542   - vga_ram_size);
3543   -#if defined (TARGET_I386)
3544   - cmos_init();
3545   -#endif
3546   - pic_init();
3547   - pit_init();
3548   - serial_init();
3549   -#if defined (TARGET_I386)
3550   - ne2000_init();
3551   -#endif
3552   - ide_init();
3553   - kbd_init();
3554   - AUD_init();
3555   - DMA_init();
3556   -#if defined (TARGET_I386)
3557   - SB16_init();
3558   -#endif
3559   -#if defined (TARGET_PPC)
3560   - PPC_end_init();
  1185 +#if defined(TARGET_I386)
  1186 + pc_init(ram_size, vga_ram_size, boot_device,
  1187 + ds, fd_filename, snapshot,
  1188 + kernel_filename, kernel_cmdline, initrd_filename);
  1189 +#elif defined(TARGET_PPC)
  1190 + ppc_init();
3561 1191 #endif
3562   - fdctrl_register((unsigned char **)fd_filename, snapshot, boot_device);
3563 1192  
3564 1193 /* setup cpu signal handlers for MMU / self modifying code handling */
3565 1194 #if !defined(CONFIG_SOFTMMU)
... ...
... ... @@ -29,21 +29,25 @@
29 29 /* vl.c */
30 30 extern int reset_requested;
31 31 extern int64_t ticks_per_sec;
  32 +extern int pit_min_timer_count;
32 33  
33 34 typedef void (IOPortWriteFunc)(struct CPUState *env, uint32_t address, uint32_t data);
34 35 typedef uint32_t (IOPortReadFunc)(struct CPUState *env, uint32_t address);
35 36  
36 37 int register_ioport_read(int start, int length, IOPortReadFunc *func, int size);
37 38 int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size);
38   -void pic_set_irq(int irq, int level);
39 39 int64_t cpu_get_ticks(void);
  40 +uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
40 41  
41   -void kbd_put_keycode(int keycode);
  42 +void net_send_packet(int net_fd, const uint8_t *buf, int size);
42 43  
43   -#define MOUSE_EVENT_LBUTTON 0x01
44   -#define MOUSE_EVENT_RBUTTON 0x02
45   -#define MOUSE_EVENT_MBUTTON 0x04
46   -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
  44 +void hw_error(const char *fmt, ...);
  45 +
  46 +int load_image(const char *filename, uint8_t *addr);
  47 +extern const char *bios_dir;
  48 +
  49 +void pstrcpy(char *buf, int buf_size, const char *str);
  50 +char *pstrcat(char *buf, int buf_size, const char *s);
47 51  
48 52 /* block.c */
49 53 typedef struct BlockDriverState BlockDriverState;
... ... @@ -139,4 +143,78 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
139 143 char boot_device);
140 144 int fdctrl_disk_change (int idx, const unsigned char *filename, int ro);
141 145  
  146 +/* ne2000.c */
  147 +
  148 +#define MAX_ETH_FRAME_SIZE 1514
  149 +
  150 +void ne2000_init(int base, int irq);
  151 +int ne2000_can_receive(void);
  152 +void ne2000_receive(uint8_t *buf, int size);
  153 +
  154 +extern int net_fd;
  155 +
  156 +/* pckbd.c */
  157 +
  158 +void kbd_put_keycode(int keycode);
  159 +
  160 +#define MOUSE_EVENT_LBUTTON 0x01
  161 +#define MOUSE_EVENT_RBUTTON 0x02
  162 +#define MOUSE_EVENT_MBUTTON 0x04
  163 +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
  164 +
  165 +void kbd_init(void);
  166 +
  167 +/* mc146818rtc.c */
  168 +
  169 +typedef struct RTCState {
  170 + uint8_t cmos_data[128];
  171 + uint8_t cmos_index;
  172 + int irq;
  173 +} RTCState;
  174 +
  175 +extern RTCState rtc_state;
  176 +
  177 +void rtc_init(int base, int irq);
  178 +void rtc_timer(void);
  179 +
  180 +/* serial.c */
  181 +
  182 +void serial_init(int base, int irq);
  183 +int serial_can_receive(void);
  184 +void serial_receive_byte(int ch);
  185 +void serial_receive_break(void);
  186 +
  187 +/* i8259.c */
  188 +
  189 +void pic_set_irq(int irq, int level);
  190 +void pic_init(void);
  191 +
  192 +/* i8254.c */
  193 +
  194 +#define PIT_FREQ 1193182
  195 +
  196 +typedef struct PITChannelState {
  197 + int count; /* can be 65536 */
  198 + uint16_t latched_count;
  199 + uint8_t rw_state;
  200 + uint8_t mode;
  201 + uint8_t bcd; /* not supported */
  202 + uint8_t gate; /* timer start */
  203 + int64_t count_load_time;
  204 + int64_t count_last_edge_check_time;
  205 +} PITChannelState;
  206 +
  207 +extern PITChannelState pit_channels[3];
  208 +
  209 +void pit_init(void);
  210 +void pit_set_gate(PITChannelState *s, int val);
  211 +int pit_get_out(PITChannelState *s);
  212 +int pit_get_out_edges(PITChannelState *s);
  213 +
  214 +/* pc.c */
  215 +void pc_init(int ram_size, int vga_ram_size, int boot_device,
  216 + DisplayState *ds, const char **fd_filename, int snapshot,
  217 + const char *kernel_filename, const char *kernel_cmdline,
  218 + const char *initrd_filename);
  219 +
142 220 #endif /* VL_H */
... ...