You need to sign in or sign up before continuing.

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 include config.mak 1 include config.mak
2 2
3 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH) 3 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH)
4 -VPATH=$(SRC_PATH):$(TARGET_PATH) 4 +VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw
5 CFLAGS=-Wall -O2 -g 5 CFLAGS=-Wall -O2 -g
6 LDFLAGS=-g 6 LDFLAGS=-g
7 LIBS= 7 LIBS=
@@ -204,7 +204,8 @@ ifeq ($(ARCH),alpha) @@ -204,7 +204,8 @@ ifeq ($(ARCH),alpha)
204 endif 204 endif
205 205
206 # must use static linking to avoid leaving stuff in virtual address space 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 ifeq ($(TARGET_ARCH), ppc) 209 ifeq ($(TARGET_ARCH), ppc)
209 VL_OBJS+= hw.o 210 VL_OBJS+= hw.o
210 endif 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 * Permission is hereby granted, free of charge, to any person obtaining a copy 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 7 * of this software and associated documentation files (the "Software"), to deal
@@ -51,33 +51,9 @@ @@ -51,33 +51,9 @@
51 #include "vl.h" 51 #include "vl.h"
52 52
53 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" 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 //#define DEBUG_UNUSED_IOPORT 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 #if !defined(CONFIG_SOFTMMU) 57 #if !defined(CONFIG_SOFTMMU)
82 #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024) 58 #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
83 #else 59 #else
@@ -85,7 +61,6 @@ @@ -85,7 +61,6 @@
85 #endif 61 #endif
86 62
87 #if defined (TARGET_I386) 63 #if defined (TARGET_I386)
88 -#define KERNEL_LOAD_ADDR 0x00100000  
89 #elif defined (TARGET_PPC) 64 #elif defined (TARGET_PPC)
90 //#define USE_OPEN_FIRMWARE 65 //#define USE_OPEN_FIRMWARE
91 #if !defined (USE_OPEN_FIRMWARE) 66 #if !defined (USE_OPEN_FIRMWARE)
@@ -96,16 +71,13 @@ @@ -96,16 +71,13 @@
96 #define KERNEL_STACK_ADDR 0x00400000 71 #define KERNEL_STACK_ADDR 0x00400000
97 #endif 72 #endif
98 #endif 73 #endif
99 -#define INITRD_LOAD_ADDR 0x00400000  
100 -#define KERNEL_PARAMS_ADDR 0x00090000  
101 -#define KERNEL_CMDLINE_ADDR 0x00099000  
102 74
103 #define GUI_REFRESH_INTERVAL 30 75 #define GUI_REFRESH_INTERVAL 30
104 76
105 /* XXX: use a two level table to limit memory usage */ 77 /* XXX: use a two level table to limit memory usage */
106 #define MAX_IOPORTS 65536 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 char phys_ram_file[1024]; 81 char phys_ram_file[1024];
110 CPUState *global_env; 82 CPUState *global_env;
111 CPUState *cpu_single_env; 83 CPUState *cpu_single_env;
@@ -119,6 +91,8 @@ int term_inited; @@ -119,6 +91,8 @@ int term_inited;
119 int64_t ticks_per_sec; 91 int64_t ticks_per_sec;
120 int boot_device = 'c'; 92 int boot_device = 'c';
121 static int ram_size; 93 static int ram_size;
  94 +static char network_script[1024];
  95 +int pit_min_timer_count = 0;
122 96
123 /***********************************************************/ 97 /***********************************************************/
124 /* x86 io ports */ 98 /* x86 io ports */
@@ -245,39 +219,6 @@ char *pstrcat(char *buf, int buf_size, const char *s) @@ -245,39 +219,6 @@ char *pstrcat(char *buf, int buf_size, const char *s)
245 return buf; 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 /* return the size or -1 if error */ 222 /* return the size or -1 if error */
282 int load_image(const char *filename, uint8_t *addr) 223 int load_image(const char *filename, uint8_t *addr)
283 { 224 {
@@ -326,10 +267,6 @@ int cpu_inl(CPUState *env, int addr) @@ -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 void hw_error(const char *fmt, ...) 270 void hw_error(const char *fmt, ...)
334 { 271 {
335 va_list ap; 272 va_list ap;
@@ -347,613 +284,6 @@ void hw_error(const char *fmt, ...) @@ -347,613 +284,6 @@ void hw_error(const char *fmt, ...)
347 abort(); 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 #if defined(__powerpc__) 287 #if defined(__powerpc__)
958 288
959 static inline uint32_t get_tbl(void) 289 static inline uint32_t get_tbl(void)
@@ -1036,7 +366,7 @@ void cpu_calibrate_ticks(void) @@ -1036,7 +366,7 @@ void cpu_calibrate_ticks(void)
1036 } 366 }
1037 367
1038 /* compute with 96 bit intermediate result: (a*b)/c */ 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 union { 371 union {
1042 uint64_t ll; 372 uint64_t ll;
@@ -1059,1809 +389,214 @@ static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) @@ -1059,1809 +389,214 @@ static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
1059 return res.ll; 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 static term_cmd_t term_cmds[] = { 405 static term_cmd_t term_cmds[] = {
1546 { "changecd", &do_change_cdrom, }, 406 { "changecd", &do_change_cdrom, },
1547 { "changefd0", &do_change_fd0, }, 407 { "changefd0", &do_change_fd0, },
1548 { "changefd1", &do_change_fd1, }, 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 break; 515 break;
2707 - default: 516 + case 'x':
  517 + exit(0);
2708 break; 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 break; 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 break; 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 break; 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 break; 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 #endif 597 #endif
  598 + write(net_fd, buf, size);
  599 +}
2865 600
2866 /***********************************************************/ 601 /***********************************************************/
2867 /* dumb display */ 602 /* dumb display */
@@ -3015,7 +750,7 @@ int main_loop(void *opaque) @@ -3015,7 +750,7 @@ int main_loop(void *opaque)
3015 /* poll any events */ 750 /* poll any events */
3016 serial_ufd = NULL; 751 serial_ufd = NULL;
3017 pf = ufds; 752 pf = ufds;
3018 - if (serial_ok && !(serial_ports[0].lsr & UART_LSR_DR)) { 753 + if (serial_ok && serial_can_receive()) {
3019 serial_ufd = pf; 754 serial_ufd = pf;
3020 pf->fd = 0; 755 pf->fd = 0;
3021 pf->events = POLLIN; 756 pf->events = POLLIN;
@@ -3023,7 +758,7 @@ int main_loop(void *opaque) @@ -3023,7 +758,7 @@ int main_loop(void *opaque)
3023 } 758 }
3024 #if defined (TARGET_I386) 759 #if defined (TARGET_I386)
3025 net_ufd = NULL; 760 net_ufd = NULL;
3026 - if (net_fd > 0 && ne2000_can_receive(&ne2000_state)) { 761 + if (net_fd > 0 && ne2000_can_receive()) {
3027 net_ufd = pf; 762 net_ufd = pf;
3028 pf->fd = net_fd; 763 pf->fd = net_fd;
3029 pf->events = POLLIN; 764 pf->events = POLLIN;
@@ -3043,7 +778,7 @@ int main_loop(void *opaque) @@ -3043,7 +778,7 @@ int main_loop(void *opaque)
3043 if (serial_ufd && (serial_ufd->revents & POLLIN)) { 778 if (serial_ufd && (serial_ufd->revents & POLLIN)) {
3044 n = read(0, &ch, 1); 779 n = read(0, &ch, 1);
3045 if (n == 1) { 780 if (n == 1) {
3046 - serial_received_byte(&serial_ports[0], ch); 781 + term_received_byte(ch);
3047 } else { 782 } else {
3048 /* Closed, stop polling. */ 783 /* Closed, stop polling. */
3049 serial_ok = 0; 784 serial_ok = 0;
@@ -3059,7 +794,7 @@ int main_loop(void *opaque) @@ -3059,7 +794,7 @@ int main_loop(void *opaque)
3059 memset(buf + n, 0, 60 - n); 794 memset(buf + n, 0, 60 - n);
3060 n = 60; 795 n = 60;
3061 } 796 }
3062 - ne2000_receive(&ne2000_state, buf, n); 797 + ne2000_receive(buf, n);
3063 } 798 }
3064 } 799 }
3065 #endif 800 #endif
@@ -3080,10 +815,7 @@ int main_loop(void *opaque) @@ -3080,10 +815,7 @@ int main_loop(void *opaque)
3080 pic_set_irq(0, 1); 815 pic_set_irq(0, 1);
3081 pic_set_irq(0, 0); 816 pic_set_irq(0, 0);
3082 timer_irq_pending = 0; 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 #endif 819 #endif
3088 } 820 }
3089 /* XXX: add explicit timer */ 821 /* XXX: add explicit timer */
@@ -3199,7 +931,7 @@ static uint8_t *signal_stack; @@ -3199,7 +931,7 @@ static uint8_t *signal_stack;
3199 931
3200 int main(int argc, char **argv) 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 int snapshot, linux_boot; 935 int snapshot, linux_boot;
3204 struct sigaction act; 936 struct sigaction act;
3205 struct itimerval itv; 937 struct itimerval itv;
@@ -3207,7 +939,6 @@ int main(int argc, char **argv) @@ -3207,7 +939,6 @@ int main(int argc, char **argv)
3207 const char *initrd_filename; 939 const char *initrd_filename;
3208 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; 940 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
3209 const char *kernel_filename, *kernel_cmdline; 941 const char *kernel_filename, *kernel_cmdline;
3210 - char buf[1024];  
3211 DisplayState *ds = &display_state; 942 DisplayState *ds = &display_state;
3212 943
3213 /* we never want that malloc() uses mmap() */ 944 /* we never want that malloc() uses mmap() */
@@ -3438,92 +1169,7 @@ int main(int argc, char **argv) @@ -3438,92 +1169,7 @@ int main(int argc, char **argv)
3438 cpu_single_env = env; 1169 cpu_single_env = env;
3439 1170
3440 init_ioports(); 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 /* terminal init */ 1174 /* terminal init */
3529 if (nographic) { 1175 if (nographic) {
@@ -3535,31 +1181,14 @@ int main(int argc, char **argv) @@ -3535,31 +1181,14 @@ int main(int argc, char **argv)
3535 dumb_display_init(ds); 1181 dumb_display_init(ds);
3536 #endif 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 #endif 1191 #endif
3562 - fdctrl_register((unsigned char **)fd_filename, snapshot, boot_device);  
3563 1192
3564 /* setup cpu signal handlers for MMU / self modifying code handling */ 1193 /* setup cpu signal handlers for MMU / self modifying code handling */
3565 #if !defined(CONFIG_SOFTMMU) 1194 #if !defined(CONFIG_SOFTMMU)
@@ -29,21 +29,25 @@ @@ -29,21 +29,25 @@
29 /* vl.c */ 29 /* vl.c */
30 extern int reset_requested; 30 extern int reset_requested;
31 extern int64_t ticks_per_sec; 31 extern int64_t ticks_per_sec;
  32 +extern int pit_min_timer_count;
32 33
33 typedef void (IOPortWriteFunc)(struct CPUState *env, uint32_t address, uint32_t data); 34 typedef void (IOPortWriteFunc)(struct CPUState *env, uint32_t address, uint32_t data);
34 typedef uint32_t (IOPortReadFunc)(struct CPUState *env, uint32_t address); 35 typedef uint32_t (IOPortReadFunc)(struct CPUState *env, uint32_t address);
35 36
36 int register_ioport_read(int start, int length, IOPortReadFunc *func, int size); 37 int register_ioport_read(int start, int length, IOPortReadFunc *func, int size);
37 int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size); 38 int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size);
38 -void pic_set_irq(int irq, int level);  
39 int64_t cpu_get_ticks(void); 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 /* block.c */ 52 /* block.c */
49 typedef struct BlockDriverState BlockDriverState; 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,4 +143,78 @@ void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
139 char boot_device); 143 char boot_device);
140 int fdctrl_disk_change (int idx, const unsigned char *filename, int ro); 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 #endif /* VL_H */ 220 #endif /* VL_H */