aboutsummaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/android_arm.c175
-rw-r--r--hw/arm-misc.h49
-rw-r--r--hw/arm_boot.c251
-rw-r--r--hw/arm_gic.c747
-rw-r--r--hw/arm_pic.c48
-rw-r--r--hw/arm_pic.h25
-rw-r--r--hw/armv7m.c206
-rw-r--r--hw/armv7m_nvic.c407
-rw-r--r--hw/audiodev.h17
-rw-r--r--hw/baum.h29
-rw-r--r--hw/boards.h122
-rw-r--r--hw/cdrom.c157
-rw-r--r--hw/devices.h74
-rw-r--r--hw/dma.c548
-rw-r--r--hw/goldfish_audio.c533
-rw-r--r--hw/goldfish_battery.c261
-rw-r--r--hw/goldfish_device.c200
-rw-r--r--hw/goldfish_device.h58
-rw-r--r--hw/goldfish_events_device.c423
-rw-r--r--hw/goldfish_fb.c405
-rw-r--r--hw/goldfish_interrupt.c190
-rw-r--r--hw/goldfish_memlog.c78
-rw-r--r--hw/goldfish_mmc.c468
-rw-r--r--hw/goldfish_nand.c636
-rw-r--r--hw/goldfish_nand.h28
-rw-r--r--hw/goldfish_nand_reg.h54
-rw-r--r--hw/goldfish_switch.c172
-rw-r--r--hw/goldfish_timer.c256
-rw-r--r--hw/goldfish_trace.c251
-rw-r--r--hw/goldfish_trace.h79
-rw-r--r--hw/goldfish_tty.c226
-rw-r--r--hw/hw.h110
-rw-r--r--hw/irq.c71
-rw-r--r--hw/irq.h34
-rw-r--r--hw/isa.h27
-rw-r--r--hw/mmc.h214
-rw-r--r--hw/pc.h148
-rw-r--r--hw/pci.c701
-rw-r--r--hw/pci.h142
-rw-r--r--hw/pci_host.h93
-rw-r--r--hw/pcmcia.h50
-rw-r--r--hw/power_supply.h109
-rw-r--r--hw/pxa.h227
-rw-r--r--hw/scsi-disk.c809
-rw-r--r--hw/scsi-disk.h36
-rw-r--r--hw/sd.h83
-rw-r--r--hw/smc91c111.c715
-rw-r--r--hw/usb-hid.c896
-rw-r--r--hw/usb-hub.c554
-rw-r--r--hw/usb-msd.c578
-rw-r--r--hw/usb-ohci.c1684
-rw-r--r--hw/usb.c231
-rw-r--r--hw/usb.h291
53 files changed, 0 insertions, 14976 deletions
diff --git a/hw/android_arm.c b/hw/android_arm.c
deleted file mode 100644
index efc8ba1..0000000
--- a/hw/android_arm.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "hw.h"
-#include "boards.h"
-#include "devices.h"
-#include "net.h"
-#include "arm_pic.h"
-#include "sysemu.h"
-#include "goldfish_device.h"
-#include "android/globals.h"
-#include "audio/audio.h"
-#include "arm-misc.h"
-
-#define ARM_CPU_SAVE_VERSION 1
-
-int android_audio_enabled;
-char* audio_input_source = NULL;
-
-void goldfish_memlog_init(uint32_t base);
-
-static struct goldfish_device event0_device = {
- .name = "goldfish_events",
- .id = 0,
- .size = 0x1000,
- .irq_count = 1
-};
-
-static struct goldfish_device nand_device = {
- .name = "goldfish_nand",
- .id = 0,
- .size = 0x1000
-};
-
-static struct goldfish_device trace_device = {
- .name = "qemu_trace",
- .id = -1,
- .size = 0x1000
-};
-
-/* Board init. */
-
-#define TEST_SWITCH 1
-#if TEST_SWITCH
-uint32_t switch_test_write(void *opaque, uint32_t state)
-{
- goldfish_switch_set_state(opaque, state);
- return state;
-}
-#endif
-
-static void android_arm_init(ram_addr_t ram_size, int vga_ram_size,
- const char *boot_device, DisplayState *ds,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- const char *cpu_model)
-{
- CPUState *env;
- qemu_irq *cpu_pic;
- qemu_irq *goldfish_pic;
- int i;
- struct arm_boot_info info;
-
- if (!cpu_model)
- cpu_model = "arm926";
-
- env = cpu_init(cpu_model);
-
- register_savevm( "cpu", 0, ARM_CPU_SAVE_VERSION, cpu_save, cpu_load, env );
-
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- cpu_pic = arm_pic_init_cpu(env);
- goldfish_pic = goldfish_interrupt_init(0xff000000, cpu_pic[ARM_PIC_CPU_IRQ], cpu_pic[ARM_PIC_CPU_FIQ]);
- goldfish_device_init(goldfish_pic, 0xff010000, 0x7f0000, 10, 22);
-
- goldfish_device_bus_init(0xff001000, 1);
-
- goldfish_timer_and_rtc_init(0xff003000, 3);
-
- goldfish_tty_add(serial_hds[0], 0, 0xff002000, 4);
- for(i = 1; i < MAX_SERIAL_PORTS; i++) {
- //printf("android_arm_init serial %d %x\n", i, serial_hds[i]);
- if(serial_hds[i]) {
- goldfish_tty_add(serial_hds[i], i, 0, 0);
- }
- }
-
- for(i = 0; i < MAX_NICS; i++) {
- if (nd_table[i].vlan) {
- if (nd_table[i].model == NULL
- || strcmp(nd_table[i].model, "smc91c111") == 0) {
- struct goldfish_device *smc_device;
- smc_device = qemu_mallocz(sizeof(*smc_device));
- smc_device->name = "smc91x";
- smc_device->id = i;
- smc_device->size = 0x1000;
- smc_device->irq_count = 1;
- goldfish_add_device_no_io(smc_device);
- smc91c111_init(&nd_table[i], smc_device->base, goldfish_pic[smc_device->irq]);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
- exit (1);
- }
- }
- }
-
- goldfish_fb_init(ds, 0);
-#ifdef HAS_AUDIO
- if (android_audio_enabled) {
- AUD_init();
- goldfish_audio_init(0xff004000, 0, audio_input_source);
- }
-#endif
- {
- int idx = drive_get_index( IF_IDE, 0, 0 );
- if (idx >= 0)
- goldfish_mmc_init(0xff005000, 0, drives_table[idx].bdrv);
- }
-
- goldfish_memlog_init(0xff006000);
-
- if (android_hw->hw_battery)
- goldfish_battery_init();
-
- goldfish_add_device_no_io(&event0_device);
- events_dev_init(event0_device.base, goldfish_pic[event0_device.irq]);
-
-#ifdef CONFIG_NAND
- goldfish_add_device_no_io(&nand_device);
- nand_dev_init(nand_device.base);
-#endif
-#ifdef CONFIG_TRACE
- extern const char *trace_filename;
- if(trace_filename != NULL) {
- goldfish_add_device_no_io(&trace_device);
- trace_dev_init(trace_device.base);
- }
-#endif
-
-#if TEST_SWITCH
- {
- void *sw;
- sw = goldfish_switch_add("test", NULL, NULL, 0);
- goldfish_switch_set_state(sw, 1);
- goldfish_switch_add("test2", switch_test_write, sw, 1);
- }
-#endif
-
- memset(&info, 0, sizeof info);
- info.ram_size = ram_size;
- info.kernel_filename = kernel_filename;
- info.kernel_cmdline = kernel_cmdline;
- info.initrd_filename = initrd_filename;
- info.nb_cpus = 1;
- info.board_id = 1441;
-
- arm_load_kernel(env, &info);
-}
-
-QEMUMachine android_arm_machine = {
- "android_arm",
- "ARM Android Emulator",
- android_arm_init,
- NULL
-};
diff --git a/hw/arm-misc.h b/hw/arm-misc.h
deleted file mode 100644
index 707e699..0000000
--- a/hw/arm-misc.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Misc ARM declarations
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- *
- */
-
-#ifndef ARM_MISC_H
-#define ARM_MISC_H 1
-
-#include "cpu.h"
-
-/* The CPU is also modeled as an interrupt controller. */
-#define ARM_PIC_CPU_IRQ 0
-#define ARM_PIC_CPU_FIQ 1
-qemu_irq *arm_pic_init_cpu(CPUState *env);
-
-/* armv7m.c */
-qemu_irq *armv7m_init(int flash_size, int sram_size,
- const char *kernel_filename, const char *cpu_model);
-
-/* arm_boot.c */
-struct arm_boot_info {
- int ram_size;
- const char *kernel_filename;
- const char *kernel_cmdline;
- const char *initrd_filename;
- target_phys_addr_t loader_start;
- int nb_cpus;
- int board_id;
- int (*atag_board)(struct arm_boot_info *info, void *p);
-};
-void arm_load_kernel(CPUState *env, struct arm_boot_info *info);
-
-/* armv7m_nvic.c */
-
-/* Multiplication factor to convert from system clock ticks to qemu timer
- ticks. */
-int system_clock_scale;
-qemu_irq *armv7m_nvic_init(CPUState *env);
-
-/* stellaris_enent.c */
-void stellaris_enet_init(NICInfo *nd, uint32_t base, qemu_irq irq);
-
-#endif /* !ARM_MISC_H */
-
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
deleted file mode 100644
index 5990961..0000000
--- a/hw/arm_boot.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * ARM kernel loader.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "hw.h"
-#include "arm-misc.h"
-#include "sysemu.h"
-
-#define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x00010000
-#define INITRD_LOAD_ADDR 0x00800000
-
-/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
-static uint32_t bootloader[] = {
- 0xe3a00000, /* mov r0, #0 */
- 0xe3a01000, /* mov r1, #0x?? */
- 0xe3811c00, /* orr r1, r1, #0x??00 */
- 0xe59f2000, /* ldr r2, [pc, #0] */
- 0xe59ff000, /* ldr pc, [pc, #0] */
- 0, /* Address of kernel args. Set by integratorcp_init. */
- 0 /* Kernel entry point. Set by integratorcp_init. */
-};
-
-/* Entry point for secondary CPUs. Enable interrupt controller and
- Issue WFI until start address is written to system controller. */
-static uint32_t smpboot[] = {
- 0xe3a00201, /* mov r0, #0x10000000 */
- 0xe3800601, /* orr r0, r0, #0x001000000 */
- 0xe3a01001, /* mov r1, #1 */
- 0xe5801100, /* str r1, [r0, #0x100] */
- 0xe3a00201, /* mov r0, #0x10000000 */
- 0xe3800030, /* orr r0, #0x30 */
- 0xe320f003, /* wfi */
- 0xe5901000, /* ldr r1, [r0] */
- 0xe3110003, /* tst r1, #3 */
- 0x1afffffb, /* bne <wfi> */
- 0xe12fff11 /* bx r1 */
-};
-
-static void main_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
-
- cpu_reset(env);
- if (env->boot_info)
- arm_load_kernel(env, env->boot_info);
-
- /* TODO: Reset secondary CPUs. */
-}
-
-static void set_kernel_args(struct arm_boot_info *info,
- int initrd_size, void *base)
-{
- uint32_t *p;
-
- p = (uint32_t *)(base + KERNEL_ARGS_ADDR);
- /* ATAG_CORE */
- stl_raw(p++, 5);
- stl_raw(p++, 0x54410001);
- stl_raw(p++, 1);
- stl_raw(p++, 0x1000);
- stl_raw(p++, 0);
- /* ATAG_MEM */
- /* TODO: handle multiple chips on one ATAG list */
- stl_raw(p++, 4);
- stl_raw(p++, 0x54410002);
- stl_raw(p++, info->ram_size);
- stl_raw(p++, info->loader_start);
- if (initrd_size) {
- /* ATAG_INITRD2 */
- stl_raw(p++, 4);
- stl_raw(p++, 0x54420005);
- stl_raw(p++, info->loader_start + INITRD_LOAD_ADDR);
- stl_raw(p++, initrd_size);
- }
- if (info->kernel_cmdline && *info->kernel_cmdline) {
- /* ATAG_CMDLINE */
- int cmdline_size;
-
- cmdline_size = strlen(info->kernel_cmdline);
- memcpy(p + 2, info->kernel_cmdline, cmdline_size + 1);
- cmdline_size = (cmdline_size >> 2) + 1;
- stl_raw(p++, cmdline_size + 2);
- stl_raw(p++, 0x54410009);
- p += cmdline_size;
- }
- if (info->atag_board) {
- /* ATAG_BOARD */
- int atag_board_len;
-
- atag_board_len = (info->atag_board(info, p + 2) + 3) >> 2;
- stl_raw(p++, 2 + atag_board_len);
- stl_raw(p++, 0x414f4d50);
- p += atag_board_len;
- }
- /* ATAG_END */
- stl_raw(p++, 0);
- stl_raw(p++, 0);
-}
-
-static void set_kernel_args_old(struct arm_boot_info *info,
- int initrd_size, void *base)
-{
- uint32_t *p;
- unsigned char *s;
-
- /* see linux/include/asm-arm/setup.h */
- p = (uint32_t *)(base + KERNEL_ARGS_ADDR);
- /* page_size */
- stl_raw(p++, 4096);
- /* nr_pages */
- stl_raw(p++, info->ram_size / 4096);
- /* ramdisk_size */
- stl_raw(p++, 0);
-#define FLAG_READONLY 1
-#define FLAG_RDLOAD 4
-#define FLAG_RDPROMPT 8
- /* flags */
- stl_raw(p++, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT);
- /* rootdev */
- stl_raw(p++, (31 << 8) | 0); /* /dev/mtdblock0 */
- /* video_num_cols */
- stl_raw(p++, 0);
- /* video_num_rows */
- stl_raw(p++, 0);
- /* video_x */
- stl_raw(p++, 0);
- /* video_y */
- stl_raw(p++, 0);
- /* memc_control_reg */
- stl_raw(p++, 0);
- /* unsigned char sounddefault */
- /* unsigned char adfsdrives */
- /* unsigned char bytes_per_char_h */
- /* unsigned char bytes_per_char_v */
- stl_raw(p++, 0);
- /* pages_in_bank[4] */
- stl_raw(p++, 0);
- stl_raw(p++, 0);
- stl_raw(p++, 0);
- stl_raw(p++, 0);
- /* pages_in_vram */
- stl_raw(p++, 0);
- /* initrd_start */
- if (initrd_size)
- stl_raw(p++, info->loader_start + INITRD_LOAD_ADDR);
- else
- stl_raw(p++, 0);
- /* initrd_size */
- stl_raw(p++, initrd_size);
- /* rd_start */
- stl_raw(p++, 0);
- /* system_rev */
- stl_raw(p++, 0);
- /* system_serial_low */
- stl_raw(p++, 0);
- /* system_serial_high */
- stl_raw(p++, 0);
- /* mem_fclk_21285 */
- stl_raw(p++, 0);
- /* zero unused fields */
- memset(p, 0, 256 + 1024 -
- (p - ((uint32_t *)(base + KERNEL_ARGS_ADDR))));
- s = base + KERNEL_ARGS_ADDR + 256 + 1024;
- if (info->kernel_cmdline)
- strcpy (s, info->kernel_cmdline);
- else
- stb_raw(s, 0);
-}
-
-void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
-{
- int kernel_size;
- int initrd_size;
- int n;
- int is_linux = 0;
- uint64_t elf_entry;
- target_ulong entry;
- uint32_t pd;
- void *loader_phys;
-
- /* Load the kernel. */
- if (!info->kernel_filename) {
- fprintf(stderr, "Kernel image must be specified\n");
- exit(1);
- }
-
- if (!env->boot_info) {
- if (info->nb_cpus == 0)
- info->nb_cpus = 1;
- env->boot_info = info;
- qemu_register_reset(main_cpu_reset, env);
- }
-
- pd = cpu_get_physical_page_desc(info->loader_start);
- loader_phys = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (info->loader_start & ~TARGET_PAGE_MASK);
-
- /* Assume that raw images are linux kernels, and ELF images are not. */
- kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL);
- entry = elf_entry;
- if (kernel_size < 0) {
- kernel_size = load_uboot(info->kernel_filename, &entry, &is_linux);
- }
- if (kernel_size < 0) {
- kernel_size = load_image(info->kernel_filename,
- loader_phys + KERNEL_LOAD_ADDR);
- entry = info->loader_start + KERNEL_LOAD_ADDR;
- is_linux = 1;
- }
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- info->kernel_filename);
- exit(1);
- }
- if (!is_linux) {
- /* Jump to the entry point. */
- env->regs[15] = entry & 0xfffffffe;
- env->thumb = entry & 1;
- } else {
- if (info->initrd_filename) {
- initrd_size = load_image(info->initrd_filename,
- loader_phys + INITRD_LOAD_ADDR);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initrd '%s'\n",
- info->initrd_filename);
- exit(1);
- }
- } else {
- initrd_size = 0;
- }
- bootloader[1] |= info->board_id & 0xff;
- bootloader[2] |= (info->board_id >> 8) & 0xff;
- bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR;
- bootloader[6] = entry;
- for (n = 0; n < sizeof(bootloader) / 4; n++)
- stl_raw(loader_phys + (n * 4), bootloader[n]);
- if (info->nb_cpus > 1)
- for (n = 0; n < sizeof(smpboot) / 4; n++)
- stl_raw(loader_phys + info->ram_size + (n * 4), smpboot[n]);
- if (old_param)
- set_kernel_args_old(info, initrd_size, loader_phys);
- else
- set_kernel_args(info, initrd_size, loader_phys);
- }
-}
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
deleted file mode 100644
index 54e99f4..0000000
--- a/hw/arm_gic.c
+++ /dev/null
@@ -1,747 +0,0 @@
-/*
- * ARM Generic/Distributed Interrupt Controller
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-/* This file contains implementation code for the RealView EB interrupt
- controller, MPCore distributed interrupt controller and ARMv7-M
- Nested Vectored Interrupt Controller. */
-
-//#define DEBUG_GIC
-
-#ifdef DEBUG_GIC
-#define DPRINTF(fmt, args...) \
-do { printf("arm_gic: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-#ifdef NVIC
-static const uint8_t gic_id[] =
-{ 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 };
-#define GIC_DIST_OFFSET 0
-/* The NVIC has 16 internal vectors. However these are not exposed
- through the normal GIC interface. */
-#define GIC_BASE_IRQ 32
-#else
-static const uint8_t gic_id[] =
-{ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-#define GIC_DIST_OFFSET 0x1000
-#define GIC_BASE_IRQ 0
-#endif
-
-typedef struct gic_irq_state
-{
- /* ??? The documentation seems to imply the enable bits are global, even
- for per-cpu interrupts. This seems strange. */
- unsigned enabled:1;
- unsigned pending:NCPU;
- unsigned active:NCPU;
- unsigned level:1;
- unsigned model:1; /* 0 = N:N, 1 = 1:N */
- unsigned trigger:1; /* nonzero = edge triggered. */
-} gic_irq_state;
-
-#define ALL_CPU_MASK ((1 << NCPU) - 1)
-
-#define GIC_SET_ENABLED(irq) s->irq_state[irq].enabled = 1
-#define GIC_CLEAR_ENABLED(irq) s->irq_state[irq].enabled = 0
-#define GIC_TEST_ENABLED(irq) s->irq_state[irq].enabled
-#define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm)
-#define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm)
-#define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0)
-#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
-#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
-#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
-#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
-#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
-#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
-#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
-#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
-#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
-#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
-#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
-#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
-#define GIC_GET_PRIORITY(irq, cpu) \
- (((irq) < 32) ? s->priority1[irq][cpu] : s->priority2[(irq) - 32])
-#ifdef NVIC
-#define GIC_TARGET(irq) 1
-#else
-#define GIC_TARGET(irq) s->irq_target[irq]
-#endif
-
-typedef struct gic_state
-{
- uint32_t base;
- qemu_irq parent_irq[NCPU];
- int enabled;
- int cpu_enabled[NCPU];
-
- gic_irq_state irq_state[GIC_NIRQ];
-#ifndef NVIC
- int irq_target[GIC_NIRQ];
-#endif
- int priority1[32][NCPU];
- int priority2[GIC_NIRQ - 32];
- int last_active[GIC_NIRQ][NCPU];
-
- int priority_mask[NCPU];
- int running_irq[NCPU];
- int running_priority[NCPU];
- int current_pending[NCPU];
-
- qemu_irq *in;
-#ifdef NVIC
- void *nvic;
-#endif
-} gic_state;
-
-/* TODO: Many places that call this routine could be optimized. */
-/* Update interrupt status after enabled or pending bits have been changed. */
-static void gic_update(gic_state *s)
-{
- int best_irq;
- int best_prio;
- int irq;
- int level;
- int cpu;
- int cm;
-
- for (cpu = 0; cpu < NCPU; cpu++) {
- cm = 1 << cpu;
- s->current_pending[cpu] = 1023;
- if (!s->enabled || !s->cpu_enabled[cpu]) {
- qemu_irq_lower(s->parent_irq[cpu]);
- return;
- }
- best_prio = 0x100;
- best_irq = 1023;
- for (irq = 0; irq < GIC_NIRQ; irq++) {
- if (GIC_TEST_ENABLED(irq) && GIC_TEST_PENDING(irq, cm)) {
- if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
- best_prio = GIC_GET_PRIORITY(irq, cpu);
- best_irq = irq;
- }
- }
- }
- level = 0;
- if (best_prio <= s->priority_mask[cpu]) {
- s->current_pending[cpu] = best_irq;
- if (best_prio < s->running_priority[cpu]) {
- DPRINTF("Raised pending IRQ %d\n", best_irq);
- level = 1;
- }
- }
- qemu_set_irq(s->parent_irq[cpu], level);
- }
-}
-
-static void __attribute__((unused))
-gic_set_pending_private(gic_state *s, int cpu, int irq)
-{
- int cm = 1 << cpu;
-
- if (GIC_TEST_PENDING(irq, cm))
- return;
-
- DPRINTF("Set %d pending cpu %d\n", irq, cpu);
- GIC_SET_PENDING(irq, cm);
- gic_update(s);
-}
-
-/* Process a change in an external IRQ input. */
-static void gic_set_irq(void *opaque, int irq, int level)
-{
- gic_state *s = (gic_state *)opaque;
- /* The first external input line is internal interrupt 32. */
- irq += 32;
- if (level == GIC_TEST_LEVEL(irq, ALL_CPU_MASK))
- return;
-
- if (level) {
- GIC_SET_LEVEL(irq, ALL_CPU_MASK);
- if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq)) {
- DPRINTF("Set %d pending mask %x\n", irq, GIC_TARGET(irq));
- GIC_SET_PENDING(irq, GIC_TARGET(irq));
- }
- } else {
- GIC_CLEAR_LEVEL(irq, ALL_CPU_MASK);
- }
- gic_update(s);
-}
-
-static void gic_set_running_irq(gic_state *s, int cpu, int irq)
-{
- s->running_irq[cpu] = irq;
- if (irq == 1023) {
- s->running_priority[cpu] = 0x100;
- } else {
- s->running_priority[cpu] = GIC_GET_PRIORITY(irq, cpu);
- }
- gic_update(s);
-}
-
-static uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
-{
- int new_irq;
- int cm = 1 << cpu;
- new_irq = s->current_pending[cpu];
- if (new_irq == 1023
- || GIC_GET_PRIORITY(new_irq, cpu) >= s->running_priority[cpu]) {
- DPRINTF("ACK no pending IRQ\n");
- return 1023;
- }
- s->last_active[new_irq][cpu] = s->running_irq[cpu];
- /* Clear pending flags for both level and edge triggered interrupts.
- Level triggered IRQs will be reasserted once they become inactive. */
- GIC_CLEAR_PENDING(new_irq, GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : cm);
- gic_set_running_irq(s, cpu, new_irq);
- DPRINTF("ACK %d\n", new_irq);
- return new_irq;
-}
-
-static void gic_complete_irq(gic_state * s, int cpu, int irq)
-{
- int update = 0;
- int cm = 1 << cpu;
- DPRINTF("EOI %d\n", irq);
- if (s->running_irq[cpu] == 1023)
- return; /* No active IRQ. */
- if (irq != 1023) {
- /* Mark level triggered interrupts as pending if they are still
- raised. */
- if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq)
- && GIC_TEST_LEVEL(irq, cm) && (GIC_TARGET(irq) & cm) != 0) {
- DPRINTF("Set %d pending mask %x\n", irq, cm);
- GIC_SET_PENDING(irq, cm);
- update = 1;
- }
- }
- if (irq != s->running_irq[cpu]) {
- /* Complete an IRQ that is not currently running. */
- int tmp = s->running_irq[cpu];
- while (s->last_active[tmp][cpu] != 1023) {
- if (s->last_active[tmp][cpu] == irq) {
- s->last_active[tmp][cpu] = s->last_active[irq][cpu];
- break;
- }
- tmp = s->last_active[tmp][cpu];
- }
- if (update) {
- gic_update(s);
- }
- } else {
- /* Complete the current running IRQ. */
- gic_set_running_irq(s, cpu, s->last_active[s->running_irq[cpu]][cpu]);
- }
-}
-
-static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
-{
- gic_state *s = (gic_state *)opaque;
- uint32_t res;
- int irq;
- int i;
- int cpu;
- int cm;
- int mask;
-
- cpu = gic_get_current_cpu();
- cm = 1 << cpu;
- offset -= s->base + GIC_DIST_OFFSET;
- if (offset < 0x100) {
-#ifndef NVIC
- if (offset == 0)
- return s->enabled;
- if (offset == 4)
- return ((GIC_NIRQ / 32) - 1) | ((NCPU - 1) << 5);
- if (offset < 0x08)
- return 0;
-#endif
- goto bad_reg;
- } else if (offset < 0x200) {
- /* Interrupt Set/Clear Enable. */
- if (offset < 0x180)
- irq = (offset - 0x100) * 8;
- else
- irq = (offset - 0x180) * 8;
- irq += GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_ENABLED(irq + i)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x300) {
- /* Interrupt Set/Clear Pending. */
- if (offset < 0x280)
- irq = (offset - 0x200) * 8;
- else
- irq = (offset - 0x280) * 8;
- irq += GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- mask = (irq < 32) ? cm : ALL_CPU_MASK;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_PENDING(irq + i, mask)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x400) {
- /* Interrupt Active. */
- irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- mask = (irq < 32) ? cm : ALL_CPU_MASK;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_ACTIVE(irq + i, mask)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x800) {
- /* Interrupt Priority. */
- irq = (offset - 0x400) + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = GIC_GET_PRIORITY(irq, cpu);
-#ifndef NVIC
- } else if (offset < 0xc00) {
- /* Interrupt CPU Target. */
- irq = (offset - 0x800) + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq >= 29 && irq <= 31) {
- res = cm;
- } else {
- res = GIC_TARGET(irq);
- }
- } else if (offset < 0xf00) {
- /* Interrupt Configuration. */
- irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- for (i = 0; i < 4; i++) {
- if (GIC_TEST_MODEL(irq + i))
- res |= (1 << (i * 2));
- if (GIC_TEST_TRIGGER(irq + i))
- res |= (2 << (i * 2));
- }
-#endif
- } else if (offset < 0xfe0) {
- goto bad_reg;
- } else /* offset >= 0xfe0 */ {
- if (offset & 3) {
- res = 0;
- } else {
- res = gic_id[(offset - 0xfe0) >> 2];
- }
- }
- return res;
-bad_reg:
- cpu_abort(cpu_single_env, "gic_dist_readb: Bad offset %x\n", (int)offset);
- return 0;
-}
-
-static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = gic_dist_readb(opaque, offset);
- val |= gic_dist_readb(opaque, offset + 1) << 8;
- return val;
-}
-
-static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
-#ifdef NVIC
- gic_state *s = (gic_state *)opaque;
- uint32_t addr;
- addr = offset - s->base;
- if (addr < 0x100 || addr > 0xd00)
- return nvic_readl(s->nvic, addr);
-#endif
- val = gic_dist_readw(opaque, offset);
- val |= gic_dist_readw(opaque, offset + 2) << 16;
- return val;
-}
-
-static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_state *s = (gic_state *)opaque;
- int irq;
- int i;
- int cpu;
-
- cpu = gic_get_current_cpu();
- offset -= s->base + GIC_DIST_OFFSET;
- if (offset < 0x100) {
-#ifdef NVIC
- goto bad_reg;
-#else
- if (offset == 0) {
- s->enabled = (value & 1);
- DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
- } else if (offset < 4) {
- /* ignored. */
- } else {
- goto bad_reg;
- }
-#endif
- } else if (offset < 0x180) {
- /* Interrupt Set Enable. */
- irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 16)
- value = 0xff;
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- int mask = (irq < 32) ? (1 << cpu) : GIC_TARGET(irq);
- if (!GIC_TEST_ENABLED(irq + i))
- DPRINTF("Enabled IRQ %d\n", irq + i);
- GIC_SET_ENABLED(irq + i);
- /* If a raised level triggered IRQ enabled then mark
- is as pending. */
- if (GIC_TEST_LEVEL(irq + i, mask)
- && !GIC_TEST_TRIGGER(irq + i)) {
- DPRINTF("Set %d pending mask %x\n", irq + i, mask);
- GIC_SET_PENDING(irq + i, mask);
- }
- }
- }
- } else if (offset < 0x200) {
- /* Interrupt Clear Enable. */
- irq = (offset - 0x180) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 16)
- value = 0;
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- if (GIC_TEST_ENABLED(irq + i))
- DPRINTF("Disabled IRQ %d\n", irq + i);
- GIC_CLEAR_ENABLED(irq + i);
- }
- }
- } else if (offset < 0x280) {
- /* Interrupt Set Pending. */
- irq = (offset - 0x200) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 16)
- irq = 0;
-
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- GIC_SET_PENDING(irq + i, GIC_TARGET(irq));
- }
- }
- } else if (offset < 0x300) {
- /* Interrupt Clear Pending. */
- irq = (offset - 0x280) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- for (i = 0; i < 8; i++) {
- /* ??? This currently clears the pending bit for all CPUs, even
- for per-CPU interrupts. It's unclear whether this is the
- corect behavior. */
- if (value & (1 << i)) {
- GIC_CLEAR_PENDING(irq + i, ALL_CPU_MASK);
- }
- }
- } else if (offset < 0x400) {
- /* Interrupt Active. */
- goto bad_reg;
- } else if (offset < 0x800) {
- /* Interrupt Priority. */
- irq = (offset - 0x400) + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 32) {
- s->priority1[irq][cpu] = value;
- } else {
- s->priority2[irq - 32] = value;
- }
-#ifndef NVIC
- } else if (offset < 0xc00) {
- /* Interrupt CPU Target. */
- irq = (offset - 0x800) + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 29)
- value = 0;
- else if (irq < 32)
- value = ALL_CPU_MASK;
- s->irq_target[irq] = value & ALL_CPU_MASK;
- } else if (offset < 0xf00) {
- /* Interrupt Configuration. */
- irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 32)
- value |= 0xaa;
- for (i = 0; i < 4; i++) {
- if (value & (1 << (i * 2))) {
- GIC_SET_MODEL(irq + i);
- } else {
- GIC_CLEAR_MODEL(irq + i);
- }
- if (value & (2 << (i * 2))) {
- GIC_SET_TRIGGER(irq + i);
- } else {
- GIC_CLEAR_TRIGGER(irq + i);
- }
- }
-#endif
- } else {
- /* 0xf00 is only handled for 32-bit writes. */
- goto bad_reg;
- }
- gic_update(s);
- return;
-bad_reg:
- cpu_abort(cpu_single_env, "gic_dist_writeb: Bad offset %x\n", (int)offset);
-}
-
-static void gic_dist_writew(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_dist_writeb(opaque, offset, value & 0xff);
- gic_dist_writeb(opaque, offset + 1, value >> 8);
-}
-
-static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_state *s = (gic_state *)opaque;
-#ifdef NVIC
- uint32_t addr;
- addr = offset - s->base;
- if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) {
- nvic_writel(s->nvic, addr, value);
- return;
- }
-#endif
- if (offset - s->base == GIC_DIST_OFFSET + 0xf00) {
- int cpu;
- int irq;
- int mask;
-
- cpu = gic_get_current_cpu();
- irq = value & 0x3ff;
- switch ((value >> 24) & 3) {
- case 0:
- mask = (value >> 16) & ALL_CPU_MASK;
- break;
- case 1:
- mask = 1 << cpu;
- break;
- case 2:
- mask = ALL_CPU_MASK ^ (1 << cpu);
- break;
- default:
- DPRINTF("Bad Soft Int target filter\n");
- mask = ALL_CPU_MASK;
- break;
- }
- GIC_SET_PENDING(irq, mask);
- gic_update(s);
- return;
- }
- gic_dist_writew(opaque, offset, value & 0xffff);
- gic_dist_writew(opaque, offset + 2, value >> 16);
-}
-
-static CPUReadMemoryFunc *gic_dist_readfn[] = {
- gic_dist_readb,
- gic_dist_readw,
- gic_dist_readl
-};
-
-static CPUWriteMemoryFunc *gic_dist_writefn[] = {
- gic_dist_writeb,
- gic_dist_writew,
- gic_dist_writel
-};
-
-#ifndef NVIC
-static uint32_t gic_cpu_read(gic_state *s, int cpu, int offset)
-{
- switch (offset) {
- case 0x00: /* Control */
- return s->cpu_enabled[cpu];
- case 0x04: /* Priority mask */
- return s->priority_mask[cpu];
- case 0x08: /* Binary Point */
- /* ??? Not implemented. */
- return 0;
- case 0x0c: /* Acknowledge */
- return gic_acknowledge_irq(s, cpu);
- case 0x14: /* Runing Priority */
- return s->running_priority[cpu];
- case 0x18: /* Highest Pending Interrupt */
- return s->current_pending[cpu];
- default:
- cpu_abort(cpu_single_env, "gic_cpu_read: Bad offset %x\n",
- (int)offset);
- return 0;
- }
-}
-
-static void gic_cpu_write(gic_state *s, int cpu, int offset, uint32_t value)
-{
- switch (offset) {
- case 0x00: /* Control */
- s->cpu_enabled[cpu] = (value & 1);
- DPRINTF("CPU %sabled\n", s->cpu_enabled ? "En" : "Dis");
- break;
- case 0x04: /* Priority mask */
- s->priority_mask[cpu] = (value & 0xff);
- break;
- case 0x08: /* Binary Point */
- /* ??? Not implemented. */
- break;
- case 0x10: /* End Of Interrupt */
- return gic_complete_irq(s, cpu, value & 0x3ff);
- default:
- cpu_abort(cpu_single_env, "gic_cpu_write: Bad offset %x\n",
- (int)offset);
- return;
- }
- gic_update(s);
-}
-#endif
-
-static void gic_reset(gic_state *s)
-{
- int i;
- memset(s->irq_state, 0, GIC_NIRQ * sizeof(gic_irq_state));
- for (i = 0 ; i < NCPU; i++) {
- s->priority_mask[i] = 0xf0;
- s->current_pending[i] = 1023;
- s->running_irq[i] = 1023;
- s->running_priority[i] = 0x100;
-#ifdef NVIC
- /* The NVIC doesn't have per-cpu interfaces, so enable by default. */
- s->cpu_enabled[i] = 1;
-#else
- s->cpu_enabled[i] = 0;
-#endif
- }
- for (i = 0; i < 16; i++) {
- GIC_SET_ENABLED(i);
- GIC_SET_TRIGGER(i);
- }
-#ifdef NVIC
- /* The NVIC is always enabled. */
- s->enabled = 1;
-#else
- s->enabled = 0;
-#endif
-}
-
-static void gic_save(QEMUFile *f, void *opaque)
-{
- gic_state *s = (gic_state *)opaque;
- int i;
- int j;
-
- qemu_put_be32(f, s->enabled);
- for (i = 0; i < NCPU; i++) {
- qemu_put_be32(f, s->cpu_enabled[i]);
-#ifndef NVIC
- qemu_put_be32(f, s->irq_target[i]);
-#endif
- for (j = 0; j < 32; j++)
- qemu_put_be32(f, s->priority1[j][i]);
- for (j = 0; j < GIC_NIRQ; j++)
- qemu_put_be32(f, s->last_active[j][i]);
- qemu_put_be32(f, s->priority_mask[i]);
- qemu_put_be32(f, s->running_irq[i]);
- qemu_put_be32(f, s->running_priority[i]);
- qemu_put_be32(f, s->current_pending[i]);
- }
- for (i = 0; i < GIC_NIRQ - 32; i++) {
- qemu_put_be32(f, s->priority2[i]);
- }
- for (i = 0; i < GIC_NIRQ; i++) {
- qemu_put_byte(f, s->irq_state[i].enabled);
- qemu_put_byte(f, s->irq_state[i].pending);
- qemu_put_byte(f, s->irq_state[i].active);
- qemu_put_byte(f, s->irq_state[i].level);
- qemu_put_byte(f, s->irq_state[i].model);
- qemu_put_byte(f, s->irq_state[i].trigger);
- }
-}
-
-static int gic_load(QEMUFile *f, void *opaque, int version_id)
-{
- gic_state *s = (gic_state *)opaque;
- int i;
- int j;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->enabled = qemu_get_be32(f);
- for (i = 0; i < NCPU; i++) {
- s->cpu_enabled[i] = qemu_get_be32(f);
-#ifndef NVIC
- s->irq_target[i] = qemu_get_be32(f);
-#endif
- for (j = 0; j < 32; j++)
- s->priority1[j][i] = qemu_get_be32(f);
- for (j = 0; j < GIC_NIRQ; j++)
- s->last_active[j][i] = qemu_get_be32(f);
- s->priority_mask[i] = qemu_get_be32(f);
- s->running_irq[i] = qemu_get_be32(f);
- s->running_priority[i] = qemu_get_be32(f);
- s->current_pending[i] = qemu_get_be32(f);
- }
- for (i = 0; i < GIC_NIRQ - 32; i++) {
- s->priority2[i] = qemu_get_be32(f);
- }
- for (i = 0; i < GIC_NIRQ; i++) {
- s->irq_state[i].enabled = qemu_get_byte(f);
- s->irq_state[i].pending = qemu_get_byte(f);
- s->irq_state[i].active = qemu_get_byte(f);
- s->irq_state[i].level = qemu_get_byte(f);
- s->irq_state[i].model = qemu_get_byte(f);
- s->irq_state[i].trigger = qemu_get_byte(f);
- }
-
- return 0;
-}
-
-static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq)
-{
- gic_state *s;
- int iomemtype;
- int i;
-
- s = (gic_state *)qemu_mallocz(sizeof(gic_state));
- if (!s)
- return NULL;
- s->in = qemu_allocate_irqs(gic_set_irq, s, GIC_NIRQ);
- for (i = 0; i < NCPU; i++) {
- s->parent_irq[i] = parent_irq[i];
- }
- iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
- gic_dist_writefn, s);
- cpu_register_physical_memory(base + GIC_DIST_OFFSET, 0x00001000,
- iomemtype);
- s->base = base;
- gic_reset(s);
- register_savevm("arm_gic", -1, 1, gic_save, gic_load, s);
- return s;
-}
diff --git a/hw/arm_pic.c b/hw/arm_pic.c
deleted file mode 100644
index 1fe55b7..0000000
--- a/hw/arm_pic.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Generic ARM Programmable Interrupt Controller support.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL
- */
-
-#include "hw.h"
-#include "arm-misc.h"
-
-/* Stub functions for hardware that doesn't exist. */
-void pic_info(void)
-{
-}
-
-void irq_info(void)
-{
-}
-
-
-/* Input 0 is IRQ and input 1 is FIQ. */
-static void arm_pic_cpu_handler(void *opaque, int irq, int level)
-{
- CPUState *env = (CPUState *)opaque;
- switch (irq) {
- case ARM_PIC_CPU_IRQ:
- if (level)
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- else
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
- break;
- case ARM_PIC_CPU_FIQ:
- if (level)
- cpu_interrupt(env, CPU_INTERRUPT_FIQ);
- else
- cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ);
- break;
- default:
- cpu_abort(env, "arm_pic_cpu_handler: Bad interrput line %d\n", irq);
- }
-}
-
-qemu_irq *arm_pic_init_cpu(CPUState *env)
-{
- return qemu_allocate_irqs(arm_pic_cpu_handler, env, 2);
-}
diff --git a/hw/arm_pic.h b/hw/arm_pic.h
deleted file mode 100644
index 7886bcf..0000000
--- a/hw/arm_pic.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Generic ARM Programmable Interrupt Controller support.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- *
- * Arm hardware uses a wide variety of interrupt handling hardware.
- * This provides a generic framework for connecting interrupt sources and
- * inputs.
- */
-
-#ifndef ARM_INTERRUPT_H
-#define ARM_INTERRUPT_H 1
-
-#include "irq.h"
-
-/* The CPU is also modeled as an interrupt controller. */
-#define ARM_PIC_CPU_IRQ 0
-#define ARM_PIC_CPU_FIQ 1
-qemu_irq *arm_pic_init_cpu(CPUState *env);
-
-#endif /* !ARM_INTERRUPT_H */
-
diff --git a/hw/armv7m.c b/hw/armv7m.c
deleted file mode 100644
index b2bad3c..0000000
--- a/hw/armv7m.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * ARMV7M System emulation.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "hw.h"
-#include "arm-misc.h"
-#include "sysemu.h"
-
-/* Bitbanded IO. Each word corresponds to a single bit. */
-
-/* Get the byte address of the real memory for a bitband acess. */
-static inline uint32_t bitband_addr(uint32_t addr)
-{
- uint32_t res;
-
- res = addr & 0xe0000000;
- res |= (addr & 0x1ffffff) >> 5;
- return res;
-
-}
-
-static uint32_t bitband_readb(void *opaque, target_phys_addr_t offset)
-{
- uint8_t v;
- cpu_physical_memory_read(bitband_addr(offset), &v, 1);
- return (v & (1 << ((offset >> 2) & 7))) != 0;
-}
-
-static void bitband_writeb(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- uint32_t addr;
- uint8_t mask;
- uint8_t v;
- addr = bitband_addr(offset);
- mask = (1 << ((offset >> 2) & 7));
- cpu_physical_memory_read(addr, &v, 1);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, &v, 1);
-}
-
-static uint32_t bitband_readw(void *opaque, target_phys_addr_t offset)
-{
- uint32_t addr;
- uint16_t mask;
- uint16_t v;
- addr = bitband_addr(offset) & ~1;
- mask = (1 << ((offset >> 2) & 15));
- mask = tswap16(mask);
- cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
- return (v & mask) != 0;
-}
-
-static void bitband_writew(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- uint32_t addr;
- uint16_t mask;
- uint16_t v;
- addr = bitband_addr(offset) & ~1;
- mask = (1 << ((offset >> 2) & 15));
- mask = tswap16(mask);
- cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, (uint8_t *)&v, 2);
-}
-
-static uint32_t bitband_readl(void *opaque, target_phys_addr_t offset)
-{
- uint32_t addr;
- uint32_t mask;
- uint32_t v;
- addr = bitband_addr(offset) & ~3;
- mask = (1 << ((offset >> 2) & 31));
- mask = tswap32(mask);
- cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
- return (v & mask) != 0;
-}
-
-static void bitband_writel(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- uint32_t addr;
- uint32_t mask;
- uint32_t v;
- addr = bitband_addr(offset) & ~3;
- mask = (1 << ((offset >> 2) & 31));
- mask = tswap32(mask);
- cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, (uint8_t *)&v, 4);
-}
-
-static CPUReadMemoryFunc *bitband_readfn[] = {
- bitband_readb,
- bitband_readw,
- bitband_readl
-};
-
-static CPUWriteMemoryFunc *bitband_writefn[] = {
- bitband_writeb,
- bitband_writew,
- bitband_writel
-};
-
-static void armv7m_bitband_init(void)
-{
- int iomemtype;
-
- iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn,
- NULL);
- cpu_register_physical_memory(0x22000000, 0x02000000, iomemtype);
- cpu_register_physical_memory(0x42000000, 0x02000000, iomemtype);
-}
-
-/* Board init. */
-/* Init CPU and memory for a v7-M based board.
- flash_size and sram_size are in kb.
- Returns the NVIC array. */
-
-qemu_irq *armv7m_init(int flash_size, int sram_size,
- const char *kernel_filename, const char *cpu_model)
-{
- CPUState *env;
- qemu_irq *pic;
- uint32_t pc;
- int image_size;
- uint64_t entry;
- uint64_t lowaddr;
-
- flash_size *= 1024;
- sram_size *= 1024;
-
- if (!cpu_model)
- cpu_model = "cortex-m3";
- env = cpu_init(cpu_model);
- if (!env) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
-
-#if 0
- /* > 32Mb SRAM gets complicated because it overlaps the bitband area.
- We don't have proper commandline options, so allocate half of memory
- as SRAM, up to a maximum of 32Mb, and the rest as code. */
- if (ram_size > (512 + 32) * 1024 * 1024)
- ram_size = (512 + 32) * 1024 * 1024;
- sram_size = (ram_size / 2) & TARGET_PAGE_MASK;
- if (sram_size > 32 * 1024 * 1024)
- sram_size = 32 * 1024 * 1024;
- code_size = ram_size - sram_size;
-#endif
-
- /* Flash programming is done via the SCU, so pretend it is ROM. */
- cpu_register_physical_memory(0, flash_size, IO_MEM_ROM);
- cpu_register_physical_memory(0x20000000, sram_size,
- flash_size + IO_MEM_RAM);
- armv7m_bitband_init();
-
- pic = armv7m_nvic_init(env);
-
- image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL);
- if (image_size < 0) {
- image_size = load_image(kernel_filename, phys_ram_base);
- lowaddr = 0;
- }
- if (image_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
-
- /* If the image was loaded at address zero then assume it is a
- regular ROM image and perform the normal CPU reset sequence.
- Otherwise jump directly to the entry point. */
- if (lowaddr == 0) {
- env->regs[13] = tswap32(*(uint32_t *)phys_ram_base);
- pc = tswap32(*(uint32_t *)(phys_ram_base + 4));
- } else {
- pc = entry;
- }
- env->thumb = pc & 1;
- env->regs[15] = pc & ~1;
-
- /* Hack to map an additional page of ram at the top of the address
- space. This stops qemu complaining about executing code outside RAM
- when returning from an exception. */
- cpu_register_physical_memory(0xfffff000, 0x1000, IO_MEM_RAM + ram_size);
-
- return pic;
-}
-
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
deleted file mode 100644
index c55c958..0000000
--- a/hw/armv7m_nvic.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * ARM Nested Vectored Interrupt Controller
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- *
- * The ARMv7M System controller is fairly tightly tied in with the
- * NVIC. Much of that is also implemented here.
- */
-
-#include "hw.h"
-#include "qemu-timer.h"
-#include "arm-misc.h"
-
-/* 32 internal lines (16 used for system exceptions) plus 64 external
- interrupt lines. */
-#define GIC_NIRQ 96
-#define NCPU 1
-#define NVIC 1
-
-/* Only a single "CPU" interface is present. */
-static inline int
-gic_get_current_cpu(void)
-{
- return 0;
-}
-
-static uint32_t nvic_readl(void *opaque, uint32_t offset);
-static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
-
-#include "arm_gic.c"
-
-typedef struct {
- struct {
- uint32_t control;
- uint32_t reload;
- int64_t tick;
- QEMUTimer *timer;
- } systick;
- gic_state *gic;
-} nvic_state;
-
-/* qemu timers run at 1GHz. We want something closer to 1MHz. */
-#define SYSTICK_SCALE 1000ULL
-
-#define SYSTICK_ENABLE (1 << 0)
-#define SYSTICK_TICKINT (1 << 1)
-#define SYSTICK_CLKSOURCE (1 << 2)
-#define SYSTICK_COUNTFLAG (1 << 16)
-
-/* Conversion factor from qemu timer to SysTick frequencies. */
-static inline int64_t systick_scale(nvic_state *s)
-{
- if (s->systick.control & SYSTICK_CLKSOURCE)
- return system_clock_scale;
- else
- return 1000;
-}
-
-static void systick_reload(nvic_state *s, int reset)
-{
- if (reset)
- s->systick.tick = qemu_get_clock(vm_clock);
- s->systick.tick += (s->systick.reload + 1) * systick_scale(s);
- qemu_mod_timer(s->systick.timer, s->systick.tick);
-}
-
-static void systick_timer_tick(void * opaque)
-{
- nvic_state *s = (nvic_state *)opaque;
- s->systick.control |= SYSTICK_COUNTFLAG;
- if (s->systick.control & SYSTICK_TICKINT) {
- /* Trigger the interrupt. */
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
- }
- if (s->systick.reload == 0) {
- s->systick.control &= ~SYSTICK_ENABLE;
- } else {
- systick_reload(s, 0);
- }
-}
-
-/* The external routines use the hardware vector numbering, ie. the first
- IRQ is #16. The internal GIC routines use #32 as the first IRQ. */
-void armv7m_nvic_set_pending(void *opaque, int irq)
-{
- nvic_state *s = (nvic_state *)opaque;
- if (irq >= 16)
- irq += 16;
- gic_set_pending_private(s->gic, 0, irq);
-}
-
-/* Make pending IRQ active. */
-int armv7m_nvic_acknowledge_irq(void *opaque)
-{
- nvic_state *s = (nvic_state *)opaque;
- uint32_t irq;
-
- irq = gic_acknowledge_irq(s->gic, 0);
- if (irq == 1023)
- cpu_abort(cpu_single_env, "Interrupt but no vector\n");
- if (irq >= 32)
- irq -= 16;
- return irq;
-}
-
-void armv7m_nvic_complete_irq(void *opaque, int irq)
-{
- nvic_state *s = (nvic_state *)opaque;
- if (irq >= 16)
- irq += 16;
- gic_complete_irq(s->gic, 0, irq);
-}
-
-static uint32_t nvic_readl(void *opaque, uint32_t offset)
-{
- nvic_state *s = (nvic_state *)opaque;
- uint32_t val;
- int irq;
-
- switch (offset) {
- case 4: /* Interrupt Control Type. */
- return (GIC_NIRQ / 32) - 1;
- case 0x10: /* SysTick Control and Status. */
- val = s->systick.control;
- s->systick.control &= ~SYSTICK_COUNTFLAG;
- return val;
- case 0x14: /* SysTick Reload Value. */
- return s->systick.reload;
- case 0x18: /* SysTick Current Value. */
- {
- int64_t t;
- if ((s->systick.control & SYSTICK_ENABLE) == 0)
- return 0;
- t = qemu_get_clock(vm_clock);
- if (t >= s->systick.tick)
- return 0;
- val = ((s->systick.tick - (t + 1)) / systick_scale(s)) + 1;
- /* The interrupt in triggered when the timer reaches zero.
- However the counter is not reloaded until the next clock
- tick. This is a hack to return zero during the first tick. */
- if (val > s->systick.reload)
- val = 0;
- return val;
- }
- case 0x1c: /* SysTick Calibration Value. */
- return 10000;
- case 0xd00: /* CPUID Base. */
- return cpu_single_env->cp15.c0_cpuid;
- case 0xd04: /* Interrypt Control State. */
- /* VECTACTIVE */
- val = s->gic->running_irq[0];
- if (val == 1023) {
- val = 0;
- } else if (val >= 32) {
- val -= 16;
- }
- /* RETTOBASE */
- if (s->gic->running_irq[0] == 1023
- || s->gic->last_active[s->gic->running_irq[0]][0] == 1023) {
- val |= (1 << 11);
- }
- /* VECTPENDING */
- if (s->gic->current_pending[0] != 1023)
- val |= (s->gic->current_pending[0] << 12);
- /* ISRPENDING */
- for (irq = 32; irq < GIC_NIRQ; irq++) {
- if (s->gic->irq_state[irq].pending) {
- val |= (1 << 22);
- break;
- }
- }
- /* PENDSTSET */
- if (s->gic->irq_state[ARMV7M_EXCP_SYSTICK].pending)
- val |= (1 << 26);
- /* PENDSVSET */
- if (s->gic->irq_state[ARMV7M_EXCP_PENDSV].pending)
- val |= (1 << 28);
- /* NMIPENDSET */
- if (s->gic->irq_state[ARMV7M_EXCP_NMI].pending)
- val |= (1 << 31);
- return val;
- case 0xd08: /* Vector Table Offset. */
- return cpu_single_env->v7m.vecbase;
- case 0xd0c: /* Application Interrupt/Reset Control. */
- return 0xfa05000;
- case 0xd10: /* System Control. */
- /* TODO: Implement SLEEPONEXIT. */
- return 0;
- case 0xd14: /* Configuration Control. */
- /* TODO: Implement Configuration Control bits. */
- return 0;
- case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */
- irq = offset - 0xd14;
- val = 0;
- val = s->gic->priority1[irq++][0];
- val = s->gic->priority1[irq++][0] << 8;
- val = s->gic->priority1[irq++][0] << 16;
- val = s->gic->priority1[irq][0] << 24;
- return val;
- case 0xd24: /* System Handler Status. */
- val = 0;
- if (s->gic->irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0);
- if (s->gic->irq_state[ARMV7M_EXCP_BUS].active) val |= (1 << 1);
- if (s->gic->irq_state[ARMV7M_EXCP_USAGE].active) val |= (1 << 3);
- if (s->gic->irq_state[ARMV7M_EXCP_SVC].active) val |= (1 << 7);
- if (s->gic->irq_state[ARMV7M_EXCP_DEBUG].active) val |= (1 << 8);
- if (s->gic->irq_state[ARMV7M_EXCP_PENDSV].active) val |= (1 << 10);
- if (s->gic->irq_state[ARMV7M_EXCP_SYSTICK].active) val |= (1 << 11);
- if (s->gic->irq_state[ARMV7M_EXCP_USAGE].pending) val |= (1 << 12);
- if (s->gic->irq_state[ARMV7M_EXCP_MEM].pending) val |= (1 << 13);
- if (s->gic->irq_state[ARMV7M_EXCP_BUS].pending) val |= (1 << 14);
- if (s->gic->irq_state[ARMV7M_EXCP_SVC].pending) val |= (1 << 15);
- if (s->gic->irq_state[ARMV7M_EXCP_MEM].enabled) val |= (1 << 16);
- if (s->gic->irq_state[ARMV7M_EXCP_BUS].enabled) val |= (1 << 17);
- if (s->gic->irq_state[ARMV7M_EXCP_USAGE].enabled) val |= (1 << 18);
- return val;
- case 0xd28: /* Configurable Fault Status. */
- /* TODO: Implement Fault Status. */
- cpu_abort(cpu_single_env,
- "Not implemented: Configurable Fault Status.");
- return 0;
- case 0xd2c: /* Hard Fault Status. */
- case 0xd30: /* Debug Fault Status. */
- case 0xd34: /* Mem Manage Address. */
- case 0xd38: /* Bus Fault Address. */
- case 0xd3c: /* Aux Fault Status. */
- /* TODO: Implement fault status registers. */
- goto bad_reg;
- case 0xd40: /* PFR0. */
- return 0x00000030;
- case 0xd44: /* PRF1. */
- return 0x00000200;
- case 0xd48: /* DFR0. */
- return 0x00100000;
- case 0xd4c: /* AFR0. */
- return 0x00000000;
- case 0xd50: /* MMFR0. */
- return 0x00000030;
- case 0xd54: /* MMFR1. */
- return 0x00000000;
- case 0xd58: /* MMFR2. */
- return 0x00000000;
- case 0xd5c: /* MMFR3. */
- return 0x00000000;
- case 0xd60: /* ISAR0. */
- return 0x01141110;
- case 0xd64: /* ISAR1. */
- return 0x02111000;
- case 0xd68: /* ISAR2. */
- return 0x21112231;
- case 0xd6c: /* ISAR3. */
- return 0x01111110;
- case 0xd70: /* ISAR4. */
- return 0x01310102;
- /* TODO: Implement debug registers. */
- default:
- bad_reg:
- cpu_abort(cpu_single_env, "NVIC: Bad read offset 0x%x\n", offset);
- }
-}
-
-static void nvic_writel(void *opaque, uint32_t offset, uint32_t value)
-{
- nvic_state *s = (nvic_state *)opaque;
- uint32_t oldval;
- switch (offset) {
- case 0x10: /* SysTick Control and Status. */
- oldval = s->systick.control;
- s->systick.control &= 0xfffffff8;
- s->systick.control |= value & 7;
- if ((oldval ^ value) & SYSTICK_ENABLE) {
- int64_t now = qemu_get_clock(vm_clock);
- if (value & SYSTICK_ENABLE) {
- if (s->systick.tick) {
- s->systick.tick += now;
- qemu_mod_timer(s->systick.timer, s->systick.tick);
- } else {
- systick_reload(s, 1);
- }
- } else {
- qemu_del_timer(s->systick.timer);
- s->systick.tick -= now;
- if (s->systick.tick < 0)
- s->systick.tick = 0;
- }
- } else if ((oldval ^ value) & SYSTICK_CLKSOURCE) {
- /* This is a hack. Force the timer to be reloaded
- when the reference clock is changed. */
- systick_reload(s, 1);
- }
- break;
- case 0x14: /* SysTick Reload Value. */
- s->systick.reload = value;
- break;
- case 0x18: /* SysTick Current Value. Writes reload the timer. */
- systick_reload(s, 1);
- s->systick.control &= ~SYSTICK_COUNTFLAG;
- break;
- case 0xd04: /* Interrupt Control State. */
- if (value & (1 << 31)) {
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI);
- }
- if (value & (1 << 28)) {
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV);
- } else if (value & (1 << 27)) {
- s->gic->irq_state[ARMV7M_EXCP_PENDSV].pending = 0;
- gic_update(s->gic);
- }
- if (value & (1 << 26)) {
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
- } else if (value & (1 << 25)) {
- s->gic->irq_state[ARMV7M_EXCP_SYSTICK].pending = 0;
- gic_update(s->gic);
- }
- break;
- case 0xd08: /* Vector Table Offset. */
- cpu_single_env->v7m.vecbase = value & 0xffffff80;
- break;
- case 0xd0c: /* Application Interrupt/Reset Control. */
- if ((value >> 16) == 0x05fa) {
- if (value & 2) {
- cpu_abort(cpu_single_env, "VECTCLRACTIVE not implemented");
- }
- if (value & 5) {
- cpu_abort(cpu_single_env, "System reset");
- }
- }
- break;
- case 0xd10: /* System Control. */
- case 0xd14: /* Configuration Control. */
- /* TODO: Implement control registers. */
- goto bad_reg;
- case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */
- {
- int irq;
- irq = offset - 0xd14;
- s->gic->priority1[irq++][0] = value & 0xff;
- s->gic->priority1[irq++][0] = (value >> 8) & 0xff;
- s->gic->priority1[irq++][0] = (value >> 16) & 0xff;
- s->gic->priority1[irq][0] = (value >> 24) & 0xff;
- gic_update(s->gic);
- }
- break;
- case 0xd24: /* System Handler Control. */
- /* TODO: Real hardware allows you to set/clear the active bits
- under some circumstances. We don't implement this. */
- s->gic->irq_state[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
- s->gic->irq_state[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
- s->gic->irq_state[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
- break;
- case 0xd28: /* Configurable Fault Status. */
- case 0xd2c: /* Hard Fault Status. */
- case 0xd30: /* Debug Fault Status. */
- case 0xd34: /* Mem Manage Address. */
- case 0xd38: /* Bus Fault Address. */
- case 0xd3c: /* Aux Fault Status. */
- goto bad_reg;
- default:
- bad_reg:
- cpu_abort(cpu_single_env, "NVIC: Bad write offset 0x%x\n", offset);
- }
-}
-
-static void nvic_save(QEMUFile *f, void *opaque)
-{
- nvic_state *s = (nvic_state *)opaque;
-
- qemu_put_be32(f, s->systick.control);
- qemu_put_be32(f, s->systick.reload);
- qemu_put_be64(f, s->systick.tick);
- qemu_put_timer(f, s->systick.timer);
-}
-
-static int nvic_load(QEMUFile *f, void *opaque, int version_id)
-{
- nvic_state *s = (nvic_state *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->systick.control = qemu_get_be32(f);
- s->systick.reload = qemu_get_be32(f);
- s->systick.tick = qemu_get_be64(f);
- qemu_get_timer(f, s->systick.timer);
-
- return 0;
-}
-
-qemu_irq *armv7m_nvic_init(CPUState *env)
-{
- nvic_state *s;
- qemu_irq *parent;
-
- parent = arm_pic_init_cpu(env);
- s = (nvic_state *)qemu_mallocz(sizeof(nvic_state));
- s->gic = gic_init(0xe000e000, &parent[ARM_PIC_CPU_IRQ]);
- s->gic->nvic = s;
- s->systick.timer = qemu_new_timer(vm_clock, systick_timer_tick, s);
- if (env->v7m.nvic)
- cpu_abort(env, "CPU can only have one NVIC\n");
- env->v7m.nvic = s;
- register_savevm("armv7m_nvic", -1, 1, nvic_save, nvic_load, s);
- return s->gic->in;
-}
diff --git a/hw/audiodev.h b/hw/audiodev.h
deleted file mode 100644
index 5f4a211..0000000
--- a/hw/audiodev.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* es1370.c */
-int es1370_init (PCIBus *bus, AudioState *s);
-
-/* sb16.c */
-int SB16_init (AudioState *s, qemu_irq *pic);
-
-/* adlib.c */
-int Adlib_init (AudioState *s, qemu_irq *pic);
-
-/* gus.c */
-int GUS_init (AudioState *s, qemu_irq *pic);
-
-/* ac97.c */
-int ac97_init (PCIBus *buf, AudioState *s);
-
-/* cs4231a.c */
-int cs4231a_init (AudioState *s, qemu_irq *pic);
diff --git a/hw/baum.h b/hw/baum.h
deleted file mode 100644
index ac34b30..0000000
--- a/hw/baum.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QEMU Baum
- *
- * Copyright (c) 2008 Samuel Thibault
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* usb device */
-USBDevice *usb_baum_init(void);
-
-/* char device */
-CharDriverState *chr_baum_init(void);
diff --git a/hw/boards.h b/hw/boards.h
deleted file mode 100644
index cfb7c42..0000000
--- a/hw/boards.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Declarations for use by board files for creating devices. */
-
-#ifndef HW_BOARDS_H
-#define HW_BOARDS_H
-
-typedef void QEMUMachineInitFunc(ram_addr_t ram_size, int vga_ram_size,
- const char *boot_device, DisplayState *ds,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- const char *cpu_model);
-
-typedef struct QEMUMachine {
- const char *name;
- const char *desc;
- QEMUMachineInitFunc *init;
-#define RAMSIZE_FIXED (1 << 0)
- ram_addr_t ram_require;
- int nodisk_ok;
- struct QEMUMachine *next;
-} QEMUMachine;
-
-int qemu_register_machine(QEMUMachine *m);
-void register_machines(void);
-
-/* Axis ETRAX. */
-extern QEMUMachine bareetraxfs_machine;
-
-/* pc.c */
-extern QEMUMachine pc_machine;
-extern QEMUMachine isapc_machine;
-
-/* ppc.c */
-extern QEMUMachine prep_machine;
-extern QEMUMachine core99_machine;
-extern QEMUMachine heathrow_machine;
-extern QEMUMachine ref405ep_machine;
-extern QEMUMachine taihu_machine;
-
-/* mips_r4k.c */
-extern QEMUMachine mips_machine;
-
-/* mips_jazz.c */
-extern QEMUMachine mips_magnum_machine;
-extern QEMUMachine mips_pica61_machine;
-
-/* mips_malta.c */
-extern QEMUMachine mips_malta_machine;
-
-/* mips_mipssim.c */
-extern QEMUMachine mips_mipssim_machine;
-
-/* shix.c */
-extern QEMUMachine shix_machine;
-
-/* r2d.c */
-extern QEMUMachine r2d_machine;
-
-/* sun4m.c */
-extern QEMUMachine ss5_machine, ss10_machine, ss600mp_machine, ss20_machine;
-extern QEMUMachine voyager_machine, ss_lx_machine, ss4_machine, scls_machine;
-extern QEMUMachine sbook_machine;
-extern QEMUMachine ss2_machine;
-extern QEMUMachine ss1000_machine, ss2000_machine;
-
-/* sun4u.c */
-extern QEMUMachine sun4u_machine;
-extern QEMUMachine sun4v_machine;
-
-/* integratorcp.c */
-extern QEMUMachine integratorcp_machine;
-
-/* versatilepb.c */
-extern QEMUMachine versatilepb_machine;
-extern QEMUMachine versatileab_machine;
-
-/* realview.c */
-extern QEMUMachine realview_machine;
-
-/* spitz.c */
-extern QEMUMachine akitapda_machine;
-extern QEMUMachine spitzpda_machine;
-extern QEMUMachine borzoipda_machine;
-extern QEMUMachine terrierpda_machine;
-
-/* palm.c */
-extern QEMUMachine palmte_machine;
-
-/* nseries.c */
-extern QEMUMachine n800_machine;
-extern QEMUMachine n810_machine;
-
-/* gumstix.c */
-extern QEMUMachine connex_machine;
-extern QEMUMachine verdex_machine;
-
-/* stellaris.c */
-extern QEMUMachine lm3s811evb_machine;
-extern QEMUMachine lm3s6965evb_machine;
-
-/* an5206.c */
-extern QEMUMachine an5206_machine;
-
-/* mcf5208.c */
-extern QEMUMachine mcf5208evb_machine;
-
-/* dummy_m68k.c */
-extern QEMUMachine dummy_m68k_machine;
-
-/* mainstone.c */
-extern QEMUMachine mainstone2_machine;
-
-/* musicpal.c */
-extern QEMUMachine musicpal_machine;
-
-/* tosa.c */
-extern QEMUMachine tosapda_machine;
-
-/* android_arm.c */
-extern QEMUMachine android_arm_machine;
-
-#endif
diff --git a/hw/cdrom.c b/hw/cdrom.c
deleted file mode 100644
index 2aa4d3b..0000000
--- a/hw/cdrom.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * QEMU ATAPI CD-ROM Emulator
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* ??? Most of the ATAPI emulation is still in ide.c. It should be moved
- here. */
-
-#include "qemu-common.h"
-#include "scsi-disk.h"
-
-static void lba_to_msf(uint8_t *buf, int lba)
-{
- lba += 150;
- buf[0] = (lba / 75) / 60;
- buf[1] = (lba / 75) % 60;
- buf[2] = lba % 75;
-}
-
-/* same toc as bochs. Return -1 if error or the toc length */
-/* XXX: check this */
-int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
-{
- uint8_t *q;
- int len;
-
- if (start_track > 1 && start_track != 0xaa)
- return -1;
- q = buf + 2;
- *q++ = 1; /* first session */
- *q++ = 1; /* last session */
- if (start_track <= 1) {
- *q++ = 0; /* reserved */
- *q++ = 0x14; /* ADR, control */
- *q++ = 1; /* track number */
- *q++ = 0; /* reserved */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, 0);
- q += 3;
- } else {
- /* sector 0 */
- cpu_to_be32wu((uint32_t *)q, 0);
- q += 4;
- }
- }
- /* lead out track */
- *q++ = 0; /* reserved */
- *q++ = 0x16; /* ADR, control */
- *q++ = 0xaa; /* track number */
- *q++ = 0; /* reserved */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, nb_sectors);
- q += 3;
- } else {
- cpu_to_be32wu((uint32_t *)q, nb_sectors);
- q += 4;
- }
- len = q - buf;
- cpu_to_be16wu((uint16_t *)buf, len - 2);
- return len;
-}
-
-/* mostly same info as PearPc */
-int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
-{
- uint8_t *q;
- int len;
-
- q = buf + 2;
- *q++ = 1; /* first session */
- *q++ = 1; /* last session */
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa0; /* lead-in */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 1; /* first track */
- *q++ = 0x00; /* disk type */
- *q++ = 0x00;
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa1;
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 1; /* last track */
- *q++ = 0x00;
- *q++ = 0x00;
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa2; /* lead-out */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, nb_sectors);
- q += 3;
- } else {
- cpu_to_be32wu((uint32_t *)q, nb_sectors);
- q += 4;
- }
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* ADR, control */
- *q++ = 0; /* track number */
- *q++ = 1; /* point */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- if (msf) {
- *q++ = 0;
- lba_to_msf(q, 0);
- q += 3;
- } else {
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
- }
-
- len = q - buf;
- cpu_to_be16wu((uint16_t *)buf, len - 2);
- return len;
-}
-
-
diff --git a/hw/devices.h b/hw/devices.h
deleted file mode 100644
index 45fead9..0000000
--- a/hw/devices.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef QEMU_DEVICES_H
-#define QEMU_DEVICES_H
-
-/* Devices that have nowhere better to go. */
-
-/* smc91c111.c */
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
-
-/* ssd0323.c */
-int ssd0323_xfer_ssi(void *opaque, int data);
-void *ssd0323_init(DisplayState *ds, qemu_irq *cmd_p);
-
-/* ads7846.c */
-struct ads7846_state_s;
-uint32_t ads7846_read(void *opaque);
-void ads7846_write(void *opaque, uint32_t value);
-struct ads7846_state_s *ads7846_init(qemu_irq penirq);
-
-/* tsc210x.c */
-struct uwire_slave_s;
-struct mouse_transform_info_s;
-struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio);
-struct uwire_slave_s *tsc2301_init(qemu_irq penirq, qemu_irq kbirq,
- qemu_irq dav, AudioState *audio);
-struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip);
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
-void tsc210x_set_transform(struct uwire_slave_s *chip,
- struct mouse_transform_info_s *info);
-void tsc210x_key_event(struct uwire_slave_s *chip, int key, int down);
-
-/* tsc2005.c */
-void *tsc2005_init(qemu_irq pintdav);
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
-void tsc2005_set_transform(void *opaque, struct mouse_transform_info_s *info);
-
-/* stellaris_input.c */
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
-
-/* blizzard.c */
-void *s1d13745_init(qemu_irq gpio_int, DisplayState *ds);
-void s1d13745_write(void *opaque, int dc, uint16_t value);
-void s1d13745_write_block(void *opaque, int dc,
- void *buf, size_t len, int pitch);
-uint16_t s1d13745_read(void *opaque, int dc);
-
-/* cbus.c */
-struct cbus_s {
- qemu_irq clk;
- qemu_irq dat;
- qemu_irq sel;
-};
-struct cbus_s *cbus_init(qemu_irq dat_out);
-void cbus_attach(struct cbus_s *bus, void *slave_opaque);
-
-void *retu_init(qemu_irq irq, int vilma);
-void *tahvo_init(qemu_irq irq, int betty);
-
-void retu_key_event(void *retu, int state);
-
-/* tusb6010.c */
-struct tusb_s;
-struct tusb_s *tusb6010_init(qemu_irq intr);
-int tusb6010_sync_io(struct tusb_s *s);
-int tusb6010_async_io(struct tusb_s *s);
-void tusb6010_power(struct tusb_s *s, int on);
-
-/* tc6393xb.c */
-struct tc6393xb_s;
-struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq);
-void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line,
- qemu_irq handler);
-qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s);
-
-#endif
diff --git a/hw/dma.c b/hw/dma.c
deleted file mode 100644
index 00c6332..0000000
--- a/hw/dma.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * QEMU DMA emulation
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw.h"
-#include "isa.h"
-
-/* #define DEBUG_DMA */
-
-#define dolog(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#ifdef DEBUG_DMA
-#define lwarn(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define linfo(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define ldebug(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#else
-#define lwarn(...)
-#define linfo(...)
-#define ldebug(...)
-#endif
-
-#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
-
-struct dma_regs {
- int now[2];
- uint16_t base[2];
- uint8_t mode;
- uint8_t page;
- uint8_t pageh;
- uint8_t dack;
- uint8_t eop;
- DMA_transfer_handler transfer_handler;
- void *opaque;
-};
-
-#define ADDR 0
-#define COUNT 1
-
-static struct dma_cont {
- uint8_t status;
- uint8_t command;
- uint8_t mask;
- uint8_t flip_flop;
- int dshift;
- struct dma_regs regs[4];
-} dma_controllers[2];
-
-enum {
- CMD_MEMORY_TO_MEMORY = 0x01,
- CMD_FIXED_ADDRESS = 0x02,
- CMD_BLOCK_CONTROLLER = 0x04,
- CMD_COMPRESSED_TIME = 0x08,
- CMD_CYCLIC_PRIORITY = 0x10,
- CMD_EXTENDED_WRITE = 0x20,
- CMD_LOW_DREQ = 0x40,
- CMD_LOW_DACK = 0x80,
- CMD_NOT_SUPPORTED = CMD_MEMORY_TO_MEMORY | CMD_FIXED_ADDRESS
- | CMD_COMPRESSED_TIME | CMD_CYCLIC_PRIORITY | CMD_EXTENDED_WRITE
- | CMD_LOW_DREQ | CMD_LOW_DACK
-
-};
-
-static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
-
-static void write_page (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].page = data;
-}
-
-static void write_pageh (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].pageh = data;
-}
-
-static uint32_t read_page (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].page;
-}
-
-static uint32_t read_pageh (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].pageh;
-}
-
-static inline void init_chan (struct dma_cont *d, int ichan)
-{
- struct dma_regs *r;
-
- r = d->regs + ichan;
- r->now[ADDR] = r->base[ADDR] << d->dshift;
- r->now[COUNT] = 0;
-}
-
-static inline int getff (struct dma_cont *d)
-{
- int ff;
-
- ff = d->flip_flop;
- d->flip_flop = !ff;
- return ff;
-}
-
-static uint32_t read_chan (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan, nreg, iport, ff, val, dir;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
-
- dir = ((r->mode >> 5) & 1) ? -1 : 1;
- ff = getff (d);
- if (nreg)
- val = (r->base[COUNT] << d->dshift) - r->now[COUNT];
- else
- val = r->now[ADDR] + r->now[COUNT] * dir;
-
- ldebug ("read_chan %#x -> %d\n", iport, val);
- return (val >> (d->dshift + (ff << 3))) & 0xff;
-}
-
-static void write_chan (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int iport, ichan, nreg;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
- if (getff (d)) {
- r->base[nreg] = (r->base[nreg] & 0xff) | ((data << 8) & 0xff00);
- init_chan (d, ichan);
- } else {
- r->base[nreg] = (r->base[nreg] & 0xff00) | (data & 0xff);
- }
-}
-
-static void write_cont (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int iport, ichan = 0;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* command */
- if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
- dolog ("command %#x not supported\n", data);
- return;
- }
- d->command = data;
- break;
-
- case 0x09:
- ichan = data & 3;
- if (data & 4) {
- d->status |= 1 << (ichan + 4);
- }
- else {
- d->status &= ~(1 << (ichan + 4));
- }
- d->status &= ~(1 << ichan);
- break;
-
- case 0x0a: /* single mask */
- if (data & 4)
- d->mask |= 1 << (data & 3);
- else
- d->mask &= ~(1 << (data & 3));
- break;
-
- case 0x0b: /* mode */
- {
- ichan = data & 3;
-#ifdef DEBUG_DMA
- {
- int op, ai, dir, opmode;
- op = (data >> 2) & 3;
- ai = (data >> 4) & 1;
- dir = (data >> 5) & 1;
- opmode = (data >> 6) & 3;
-
- linfo ("ichan %d, op %d, ai %d, dir %d, opmode %d\n",
- ichan, op, ai, dir, opmode);
- }
-#endif
- d->regs[ichan].mode = data;
- break;
- }
-
- case 0x0c: /* clear flip flop */
- d->flip_flop = 0;
- break;
-
- case 0x0d: /* reset */
- d->flip_flop = 0;
- d->mask = ~0;
- d->status = 0;
- d->command = 0;
- break;
-
- case 0x0e: /* clear mask for all channels */
- d->mask = 0;
- break;
-
- case 0x0f: /* write mask for all channels */
- d->mask = data;
- break;
-
- default:
- dolog ("unknown iport %#x\n", iport);
- break;
- }
-
-#ifdef DEBUG_DMA
- if (0xc != iport) {
- linfo ("write_cont: nport %#06x, ichan % 2d, val %#06x\n",
- nport, ichan, data);
- }
-#endif
-}
-
-static uint32_t read_cont (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int iport, val;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* status */
- val = d->status;
- d->status &= 0xf0;
- break;
- case 0x0f: /* mask */
- val = d->mask;
- break;
- default:
- val = 0;
- break;
- }
-
- ldebug ("read_cont: nport %#06x, iport %#04x val %#x\n", nport, iport, val);
- return val;
-}
-
-int DMA_get_channel_mode (int nchan)
-{
- return dma_controllers[nchan > 3].regs[nchan & 3].mode;
-}
-
-void DMA_hold_DREQ (int nchan)
-{
- int ncont, ichan;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("held cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status |= 1 << (ichan + 4);
-}
-
-void DMA_release_DREQ (int nchan)
-{
- int ncont, ichan;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("released cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status &= ~(1 << (ichan + 4));
-}
-
-static void channel_run (int ncont, int ichan)
-{
- int n;
- struct dma_regs *r = &dma_controllers[ncont].regs[ichan];
-#ifdef DEBUG_DMA
- int dir, opmode;
-
- dir = (r->mode >> 5) & 1;
- opmode = (r->mode >> 6) & 3;
-
- if (dir) {
- dolog ("DMA in address decrement mode\n");
- }
- if (opmode != 1) {
- dolog ("DMA not in single mode select %#x\n", opmode);
- }
-#endif
-
- r = dma_controllers[ncont].regs + ichan;
- n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
- r->now[COUNT], (r->base[COUNT] + 1) << ncont);
- r->now[COUNT] = n;
- ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont);
-}
-
-void DMA_run (void)
-{
- struct dma_cont *d;
- int icont, ichan;
-
- d = dma_controllers;
-
- for (icont = 0; icont < 2; icont++, d++) {
- for (ichan = 0; ichan < 4; ichan++) {
- int mask;
-
- mask = 1 << ichan;
-
- if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4))))
- channel_run (icont, ichan);
- }
- }
-}
-
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
-{
- struct dma_regs *r;
- int ichan, ncont;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
-
- r = dma_controllers[ncont].regs + ichan;
- r->transfer_handler = transfer_handler;
- r->opaque = opaque;
-}
-
-int DMA_read_memory (int nchan, void *buf, int pos, int len)
-{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
- target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
-
- if (r->mode & 0x20) {
- int i;
- uint8_t *p = buf;
-
- cpu_physical_memory_read (addr - pos - len, buf, len);
- /* What about 16bit transfers? */
- for (i = 0; i < len >> 1; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
- }
- else
- cpu_physical_memory_read (addr + pos, buf, len);
-
- return len;
-}
-
-int DMA_write_memory (int nchan, void *buf, int pos, int len)
-{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
- target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
-
- if (r->mode & 0x20) {
- int i;
- uint8_t *p = buf;
-
- cpu_physical_memory_write (addr - pos - len, buf, len);
- /* What about 16bit transfers? */
- for (i = 0; i < len; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
- }
- else
- cpu_physical_memory_write (addr + pos, buf, len);
-
- return len;
-}
-
-/* request the emulator to transfer a new DMA memory block ASAP */
-void DMA_schedule(int nchan)
-{
- CPUState *env = cpu_single_env;
- if (env)
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-}
-
-static void dma_reset(void *opaque)
-{
- struct dma_cont *d = opaque;
- write_cont (d, (0x0d << d->dshift), 0);
-}
-
-static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
-{
- dolog ("unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n",
- nchan, dma_pos, dma_len);
- return dma_pos;
-}
-
-/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
-static void dma_init2(struct dma_cont *d, int base, int dshift,
- int page_base, int pageh_base)
-{
- static const int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
- int i;
-
- d->dshift = dshift;
- for (i = 0; i < 8; i++) {
- register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
- register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
- }
- for (i = 0; i < LENOFA (page_port_list); i++) {
- register_ioport_write (page_base + page_port_list[i], 1, 1,
- write_page, d);
- register_ioport_read (page_base + page_port_list[i], 1, 1,
- read_page, d);
- if (pageh_base >= 0) {
- register_ioport_write (pageh_base + page_port_list[i], 1, 1,
- write_pageh, d);
- register_ioport_read (pageh_base + page_port_list[i], 1, 1,
- read_pageh, d);
- }
- }
- for (i = 0; i < 8; i++) {
- register_ioport_write (base + ((i + 8) << dshift), 1, 1,
- write_cont, d);
- register_ioport_read (base + ((i + 8) << dshift), 1, 1,
- read_cont, d);
- }
- qemu_register_reset(dma_reset, d);
- dma_reset(d);
- for (i = 0; i < LENOFA (d->regs); ++i) {
- d->regs[i].transfer_handler = dma_phony_handler;
- }
-}
-
-static void dma_save (QEMUFile *f, void *opaque)
-{
- struct dma_cont *d = opaque;
- int i;
-
- /* qemu_put_8s (f, &d->status); */
- qemu_put_8s (f, &d->command);
- qemu_put_8s (f, &d->mask);
- qemu_put_8s (f, &d->flip_flop);
- qemu_put_be32 (f, d->dshift);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- qemu_put_be32 (f, r->now[0]);
- qemu_put_be32 (f, r->now[1]);
- qemu_put_be16s (f, &r->base[0]);
- qemu_put_be16s (f, &r->base[1]);
- qemu_put_8s (f, &r->mode);
- qemu_put_8s (f, &r->page);
- qemu_put_8s (f, &r->pageh);
- qemu_put_8s (f, &r->dack);
- qemu_put_8s (f, &r->eop);
- }
-}
-
-static int dma_load (QEMUFile *f, void *opaque, int version_id)
-{
- struct dma_cont *d = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- /* qemu_get_8s (f, &d->status); */
- qemu_get_8s (f, &d->command);
- qemu_get_8s (f, &d->mask);
- qemu_get_8s (f, &d->flip_flop);
- d->dshift=qemu_get_be32 (f);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- r->now[0]=qemu_get_be32 (f);
- r->now[1]=qemu_get_be32 (f);
- qemu_get_be16s (f, &r->base[0]);
- qemu_get_be16s (f, &r->base[1]);
- qemu_get_8s (f, &r->mode);
- qemu_get_8s (f, &r->page);
- qemu_get_8s (f, &r->pageh);
- qemu_get_8s (f, &r->dack);
- qemu_get_8s (f, &r->eop);
- }
- return 0;
-}
-
-void DMA_init (int high_page_enable)
-{
- dma_init2(&dma_controllers[0], 0x00, 0, 0x80,
- high_page_enable ? 0x480 : -1);
- dma_init2(&dma_controllers[1], 0xc0, 1, 0x88,
- high_page_enable ? 0x488 : -1);
- register_savevm ("dma", 0, 1, dma_save, dma_load, &dma_controllers[0]);
- register_savevm ("dma", 1, 1, dma_save, dma_load, &dma_controllers[1]);
-}
diff --git a/hw/goldfish_audio.c b/hw/goldfish_audio.c
deleted file mode 100644
index d0a44b5..0000000
--- a/hw/goldfish_audio.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_device.h"
-#include "audio/audio.h"
-#include "qemu_debug.h"
-#include "android/globals.h"
-
-#define DEBUG 1
-
-#if DEBUG
-# define D(...) VERBOSE_PRINT(audio,__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-extern void dprint(const char* fmt, ...);
-
-/* define USE_QEMU_AUDIO_IN to 1 to use QEMU's audio subsystem to
- * implement the audio input. if 0, this will try to read a .wav file
- * directly...
- */
-#define USE_QEMU_AUDIO_IN 1
-
-enum {
- /* audio status register */
- AUDIO_INT_STATUS = 0x00,
- /* set this to enable IRQ */
- AUDIO_INT_ENABLE = 0x04,
- /* set these to specify buffer addresses */
- AUDIO_SET_WRITE_BUFFER_1 = 0x08,
- AUDIO_SET_WRITE_BUFFER_2 = 0x0C,
- /* set number of bytes in buffer to write */
- AUDIO_WRITE_BUFFER_1 = 0x10,
- AUDIO_WRITE_BUFFER_2 = 0x14,
-
- /* true if audio input is supported */
- AUDIO_READ_SUPPORTED = 0x18,
- /* buffer to use for audio input */
- AUDIO_SET_READ_BUFFER = 0x1C,
-
- /* driver writes number of bytes to read */
- AUDIO_START_READ = 0x20,
-
- /* number of bytes available in read buffer */
- AUDIO_READ_BUFFER_AVAILABLE = 0x24,
-
- /* AUDIO_INT_STATUS bits */
-
- /* this bit set when it is safe to write more bytes to the buffer */
- AUDIO_INT_WRITE_BUFFER_1_EMPTY = 1U << 0,
- AUDIO_INT_WRITE_BUFFER_2_EMPTY = 1U << 1,
- AUDIO_INT_READ_BUFFER_FULL = 1U << 2,
-};
-
-
-struct goldfish_audio_state {
- struct goldfish_device dev;
- // pointers to our two write buffers
- uint32_t buffer_1, buffer_2;
- uint32_t read_buffer;
- // buffer flags
- uint32_t int_status;
- // irq enable mask for int_status
- uint32_t int_enable;
-
-#if USE_QEMU_AUDIO_IN
- uint32_t read_pos;
- uint32_t read_size;
-#else
- // path to file or device to use for input
- const char* input_source;
- // true if input is a wav file
- int input_is_wav;
- // true if we need to convert stereo -> mono
- int input_is_stereo;
- // file descriptor to use for input
- int input_fd;
-#endif
-
- // number of bytes available in the read buffer
- int read_buffer_available;
-
- // set to 1 or 2 to indicate which buffer we are writing from, or zero if both buffers are empty
- int current_buffer;
-
- // current data to write
- uint8* data_1;
- uint32_t data_1_length;
- uint8* data_2;
- uint32_t data_2_length;
-
-
- // for QEMU sound output
- QEMUSoundCard card;
- SWVoiceOut *voice;
-#if USE_QEMU_AUDIO_IN
- SWVoiceIn* voicein;
-#endif
-};
-
-/* update this whenever you change the goldfish_audio_state structure */
-#define AUDIO_STATE_SAVE_VERSION 1
-
-#define QFIELD_STRUCT struct goldfish_audio_state
-QFIELD_BEGIN(audio_state_fields)
- QFIELD_INT32(buffer_1),
- QFIELD_INT32(buffer_2),
- QFIELD_INT32(read_buffer),
- QFIELD_INT32(int_status),
- QFIELD_INT32(int_enable),
-#if USE_QEMU_AUDIO_IN
- QFIELD_INT32(read_pos),
- QFIELD_INT32(read_size),
-#endif
- QFIELD_INT32(read_buffer_available),
- QFIELD_INT32(current_buffer),
- QFIELD_INT32(data_1_length),
- QFIELD_INT32(data_2_length),
-QFIELD_END
-
-static void audio_state_save( QEMUFile* f, void* opaque )
-{
- struct goldfish_audio_state* s = opaque;
-
- qemu_put_struct(f, audio_state_fields, s);
-
- /* we can't write data_1 and data_2 directly */
- qemu_put_be32( f, s->data_1 - phys_ram_base );
- qemu_put_be32( f, s->data_2 - phys_ram_base );
-}
-
-static int audio_state_load( QEMUFile* f, void* opaque, int version_id )
-{
- struct goldfish_audio_state* s = opaque;
- int ret;
-
- if (version_id != AUDIO_STATE_SAVE_VERSION)
- return -1;
-
- ret = qemu_get_struct(f, audio_state_fields, s);
- if (!ret) {
- s->data_1 = qemu_get_be32(f) + phys_ram_base;
- s->data_2 = qemu_get_be32(f) + phys_ram_base;
- }
- return -1;
-}
-
-static void enable_audio(struct goldfish_audio_state *s, int enable)
-{
- // enable or disable the output voice
- if (s->voice != NULL)
- AUD_set_active_out(s->voice, (enable & (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY)) != 0);
-
- if (s->voicein)
- AUD_set_active_in (s->voicein, (enable & AUDIO_INT_READ_BUFFER_FULL) != 0);
- // reset buffer information
- s->data_1_length = 0;
- s->data_2_length = 0;
- s->current_buffer = 0;
- s->read_pos = 0;
-}
-
-#if USE_QEMU_AUDIO_IN
-static void start_read(struct goldfish_audio_state *s, uint32_t count)
-{
- //printf( "... goldfish audio start_read, count=%d\n", count );
- s->read_size = count;
- s->read_buffer_available = 0;
- s->read_pos = 0;
-}
-#else
-static void start_read(struct goldfish_audio_state *s, uint32_t count)
-{
- uint8 wav_header[44];
- int result;
-
- if (!s->input_source) return;
-
- if (s->input_fd < 0) {
- s->input_fd = open(s->input_source, O_BINARY | O_RDONLY);
-
- if (s->input_fd < 0) {
- fprintf(stderr, "goldfish_audio could not open %s for audio input\n", s->input_source);
- s->input_source = NULL; // set to to avoid endless retries
- return;
- }
-
- // skip WAV header if we have a WAV file
- if (s->input_is_wav) {
- if (read(s->input_fd, wav_header, sizeof(wav_header)) != sizeof(wav_header)) {
- fprintf(stderr, "goldfish_audio could not read WAV file header %s\n", s->input_source);
- s->input_fd = -1;
- s->input_source = NULL; // set to to avoid endless retries
- return;
- }
-
- // is the WAV file stereo?
- s->input_is_stereo = (wav_header[22] == 2);
- } else {
- // assume input from an audio device is stereo
- s->input_is_stereo = 1;
- }
- }
-
- uint8* buffer = (uint8*)phys_ram_base + s->read_buffer;
- if (s->input_is_stereo) {
- // need to read twice as much data
- count *= 2;
- }
-
-try_again:
- result = read(s->input_fd, buffer, count);
- if (result == 0 && s->input_is_wav) {
- // end of file, so seek back to the beginning
- lseek(s->input_fd, sizeof(wav_header), SEEK_SET);
- goto try_again;
- }
-
- if (result > 0 && s->input_is_stereo) {
- // we need to convert stereo to mono
- uint8* src = (uint8*)buffer;
- uint8* dest = src;
- int count = result/2;
- while (count-- > 0) {
- int sample1 = src[0] | (src[1] << 8);
- int sample2 = src[2] | (src[3] << 8);
- int sample = (sample1 + sample2) >> 1;
- dst[0] = (uint8_t) sample;
- dst[1] = (uint8_t)(sample >> 8);
- src += 4;
- dst += 2;
- }
-
- // we reduced the number of bytes by 2
- result /= 2;
- }
-
- s->read_buffer_available = (result > 0 ? result : 0);
- s->int_status |= AUDIO_INT_READ_BUFFER_FULL;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
-}
-#endif
-
-static uint32_t goldfish_audio_read(void *opaque, target_phys_addr_t offset)
-{
- uint32_t ret;
- struct goldfish_audio_state *s = opaque;
- offset -= s->dev.base;
- switch(offset) {
- case AUDIO_INT_STATUS:
- // return current buffer status flags
- ret = s->int_status & s->int_enable;
- if(ret) {
- goldfish_device_set_irq(&s->dev, 0, 0);
- }
- return ret;
-
- case AUDIO_READ_SUPPORTED:
-#if USE_QEMU_AUDIO_IN
- D("%s: AUDIO_READ_SUPPORTED returns %d", __FUNCTION__,
- (s->voicein != NULL));
- return (s->voicein != NULL);
-#else
- return (s->input_source ? 1 : 0);
-#endif
-
- case AUDIO_READ_BUFFER_AVAILABLE:
- D("%s: AUDIO_READ_BUFFER_AVAILABLE returns %d", __FUNCTION__,
- s->read_buffer_available);
- return s->read_buffer_available;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_audio_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_audio_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- struct goldfish_audio_state *s = opaque;
- offset -= s->dev.base;
-
- switch(offset) {
- case AUDIO_INT_ENABLE:
- /* enable buffer empty interrupts */
- D("%s: AUDIO_INT_ENABLE %d", __FUNCTION__, val );
- enable_audio(s, val);
- s->int_enable = val;
- s->int_status = (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY);
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
- case AUDIO_SET_WRITE_BUFFER_1:
- /* save pointer to buffer 1 */
- s->buffer_1 = val;
- break;
- case AUDIO_SET_WRITE_BUFFER_2:
- /* save pointer to buffer 2 */
- s->buffer_2 = val;
- break;
- case AUDIO_WRITE_BUFFER_1:
- /* record that data in buffer 1 is ready to write */
- if (s->current_buffer == 0) s->current_buffer = 1;
- s->data_1 = phys_ram_base + s->buffer_1;
- s->data_1_length = val;
- s->int_status &= ~AUDIO_INT_WRITE_BUFFER_1_EMPTY;
- break;
- case AUDIO_WRITE_BUFFER_2:
- /* record that data in buffer 2 is ready to write */
- if (s->current_buffer == 0) s->current_buffer = 2;
- s->data_2 = phys_ram_base + s->buffer_2;
- s->data_2_length = val;
- s->int_status &= ~AUDIO_INT_WRITE_BUFFER_2_EMPTY;
- break;
-
- case AUDIO_SET_READ_BUFFER:
- /* save pointer to the read buffer */
- s->read_buffer = val;
- D( "%s: AUDIO_SET_READ_BUFFER %p", __FUNCTION__, (void*)val );
- break;
-
- case AUDIO_START_READ:
- D( "%s: AUDIO_START_READ %d", __FUNCTION__, val );
- start_read(s, val);
- s->int_status &= ~AUDIO_INT_READ_BUFFER_FULL;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_audio_write: Bad offset %x\n", offset);
- }
-}
-
-static void goldfish_audio_callback(void *opaque, int free)
-{
- struct goldfish_audio_state *s = opaque;
- int new_status = 0;
-
- /* loop until free is zero or both buffers are empty */
- while (free && s->current_buffer) {
-
- /* write data in buffer 1 */
- while (free && s->current_buffer == 1) {
- int write = s->data_1_length;
- if (write > free) write = free;
-
- int written = AUD_write(s->voice, s->data_1, write);
- if (written) {
- D("%s: sent %d bytes to audio output", __FUNCTION__, write);
- s->data_1 += written;
- s->data_1_length -= written;
- free -= written;
-
- if (s->data_1_length == 0) {
- new_status |= AUDIO_INT_WRITE_BUFFER_1_EMPTY;
- s->current_buffer = (s->data_2_length ? 2 : 0);
- }
- } else {
- break;
- }
- }
-
- /* write data in buffer 2 */
- while (free && s->current_buffer == 2) {
- int write = s->data_2_length;
- if (write > free) write = free;
-
- int written = AUD_write(s->voice, s->data_2, write);
- if (written) {
- D("%s: sent %d bytes to audio output", __FUNCTION__, write);
- s->data_2 += written;
- s->data_2_length -= written;
- free -= written;
-
- if (s->data_2_length == 0) {
- new_status |= AUDIO_INT_WRITE_BUFFER_2_EMPTY;
- s->current_buffer = (s->data_1_length ? 1 : 0);
- }
- } else {
- break;
- }
- }
- }
-
- if (new_status && new_status != s->int_status) {
- s->int_status |= new_status;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- }
-}
-
-#if USE_QEMU_AUDIO_IN
-static void
-goldfish_audio_in_callback(void *opaque, int avail)
-{
- struct goldfish_audio_state *s = opaque;
- int new_status = 0;
-
- if (s->read_pos >= s->read_size)
- return;
-
- if (0 && s->read_size > 0)
- D("%s: in %d (pos=%d size=%d)", __FUNCTION__,
- avail, s->read_pos, s->read_size );
-
- while (avail > 0) {
- int pos = s->read_pos;
- int missing = s->read_size - pos;
- uint8* buffer = (uint8*)phys_ram_base + s->read_buffer + pos;
- int read;
- int avail2 = (avail > missing) ? missing : avail;
-
- read = AUD_read(s->voicein, buffer, avail2);
- if (read == 0)
- break;
-
- if (avail2 > 0)
- D("%s: AUD_read(%d) returned %d", __FUNCTION__, avail2, read);
-
- s->read_buffer_available += read;
-
- avail -= read;
- pos += read;
- if (pos == s->read_size) {
- new_status |= AUDIO_INT_READ_BUFFER_FULL;
- D("%s: AUDIO_INT_READ_BUFFER_FULL available=%d", __FUNCTION__, s->read_buffer_available);
- }
- s->read_pos = pos;
- }
-
- if (new_status && new_status != s->int_status) {
- s->int_status |= new_status;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- }
-}
-#endif /* USE_QEMU_AUDIO_IN */
-
-static CPUReadMemoryFunc *goldfish_audio_readfn[] = {
- goldfish_audio_read,
- goldfish_audio_read,
- goldfish_audio_read
-};
-
-static CPUWriteMemoryFunc *goldfish_audio_writefn[] = {
- goldfish_audio_write,
- goldfish_audio_write,
- goldfish_audio_write
-};
-
-void goldfish_audio_init(uint32_t base, int id, const char* input_source)
-{
- struct goldfish_audio_state *s;
- audsettings_t as;
-
- /* nothing to do if no audio input and output */
- if (!android_hw->hw_audioOutput && !android_hw->hw_audioInput)
- return;
-
- s = (struct goldfish_audio_state *)qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish_audio";
- s->dev.id = id;
- s->dev.base = base;
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
-
-#ifndef USE_QEMU_AUDIO_IN
- s->input_fd = -1;
- if (input_source) {
- s->input_source = input_source;
- char* extension = strrchr(input_source, '.');
- if (extension && strcasecmp(extension, ".wav") == 0) {
- s->input_is_wav = 1;
- }
- }
-#endif
-
- AUD_register_card( &glob_audio_state, "goldfish_audio", &s->card);
-
- as.freq = 44100;
- as.nchannels = 2;
- as.fmt = AUD_FMT_S16;
- as.endianness = AUDIO_HOST_ENDIANNESS;
-
- if (android_hw->hw_audioOutput) {
- s->voice = AUD_open_out (
- &s->card,
- s->voice,
- "goldfish_audio",
- s,
- goldfish_audio_callback,
- &as
- );
- if (!s->voice) {
- dprint("warning: opening audio output failed\n");
- return;
- }
- }
-
-#if USE_QEMU_AUDIO_IN
- as.freq = 8000;
- as.nchannels = 1;
- as.fmt = AUD_FMT_S16;
- as.endianness = AUDIO_HOST_ENDIANNESS;
-
- if (android_hw->hw_audioInput) {
- s->voicein = AUD_open_in (
- &s->card,
- NULL,
- "goldfish_audio_in",
- s,
- goldfish_audio_in_callback,
- &as
- );
- if (!s->voicein) {
- dprint("warning: opening audio input failed\n");
- }
- }
-#endif
-
- goldfish_device_add(&s->dev, goldfish_audio_readfn, goldfish_audio_writefn, s);
-
- register_savevm( "audio_state", 0, AUDIO_STATE_SAVE_VERSION,
- audio_state_save, audio_state_load, s );
-}
-
diff --git a/hw/goldfish_battery.c b/hw/goldfish_battery.c
deleted file mode 100644
index d9ef785..0000000
--- a/hw/goldfish_battery.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_device.h"
-#include "power_supply.h"
-
-
-enum {
- /* status register */
- BATTERY_INT_STATUS = 0x00,
- /* set this to enable IRQ */
- BATTERY_INT_ENABLE = 0x04,
-
- BATTERY_AC_ONLINE = 0x08,
- BATTERY_STATUS = 0x0C,
- BATTERY_HEALTH = 0x10,
- BATTERY_PRESENT = 0x14,
- BATTERY_CAPACITY = 0x18,
-
- BATTERY_STATUS_CHANGED = 1U << 0,
- AC_STATUS_CHANGED = 1U << 1,
- BATTERY_INT_MASK = BATTERY_STATUS_CHANGED | AC_STATUS_CHANGED,
-};
-
-
-struct goldfish_battery_state {
- struct goldfish_device dev;
- // IRQs
- uint32_t int_status;
- // irq enable mask for int_status
- uint32_t int_enable;
-
- int ac_online;
- int status;
- int health;
- int present;
- int capacity;
-};
-
-/* update this each time you update the battery_state struct */
-#define BATTERY_STATE_SAVE_VERSION 1
-
-#define QFIELD_STRUCT struct goldfish_battery_state
-QFIELD_BEGIN(goldfish_battery_fields)
- QFIELD_INT32(int_status),
- QFIELD_INT32(int_enable),
- QFIELD_INT32(ac_online),
- QFIELD_INT32(status),
- QFIELD_INT32(health),
- QFIELD_INT32(present),
- QFIELD_INT32(capacity),
-QFIELD_END
-
-static void goldfish_battery_save(QEMUFile* f, void* opaque)
-{
- struct goldfish_battery_state* s = opaque;
-
- qemu_put_struct(f, goldfish_battery_fields, s);
-}
-
-static int goldfish_battery_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct goldfish_battery_state* s = opaque;
-
- if (version_id != BATTERY_STATE_SAVE_VERSION)
- return -1;
-
- return qemu_get_struct(f, goldfish_battery_fields, s);
-}
-
-static struct goldfish_battery_state *battery_state;
-
-static uint32_t goldfish_battery_read(void *opaque, target_phys_addr_t offset)
-{
- uint32_t ret;
- struct goldfish_battery_state *s = opaque;
- offset -= s->dev.base;
- switch(offset) {
- case BATTERY_INT_STATUS:
- // return current buffer status flags
- ret = s->int_status & s->int_enable;
- if (ret) {
- goldfish_device_set_irq(&s->dev, 0, 0);
- s->int_status = 0;
- }
- return ret;
-
- case BATTERY_INT_ENABLE:
- return s->int_enable;
- case BATTERY_AC_ONLINE:
- return s->ac_online;
- case BATTERY_STATUS:
- return s->status;
- case BATTERY_HEALTH:
- return s->health;
- case BATTERY_PRESENT:
- return s->present;
- case BATTERY_CAPACITY:
- return s->capacity;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_battery_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_battery_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- struct goldfish_battery_state *s = opaque;
- offset -= s->dev.base;
-
- switch(offset) {
- case BATTERY_INT_ENABLE:
- /* enable interrupts */
- s->int_enable = val;
-// s->int_status = (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY);
-// goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_audio_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_battery_readfn[] = {
- goldfish_battery_read,
- goldfish_battery_read,
- goldfish_battery_read
-};
-
-
-static CPUWriteMemoryFunc *goldfish_battery_writefn[] = {
- goldfish_battery_write,
- goldfish_battery_write,
- goldfish_battery_write
-};
-
-void goldfish_battery_init()
-{
- struct goldfish_battery_state *s;
-
- s = (struct goldfish_battery_state *)qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish-battery";
- s->dev.base = 0; // will be allocated dynamically
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
-
- // default values for the battery
- s->ac_online = 1;
- s->status = POWER_SUPPLY_STATUS_CHARGING;
- s->health = POWER_SUPPLY_HEALTH_GOOD;
- s->present = 1; // battery is present
- s->capacity = 50; // 50% charged
-
- battery_state = s;
-
- goldfish_device_add(&s->dev, goldfish_battery_readfn, goldfish_battery_writefn, s);
-
- register_savevm( "battery_state", 0, BATTERY_STATE_SAVE_VERSION,
- goldfish_battery_save, goldfish_battery_load, s);
-}
-
-void goldfish_battery_set_prop(int ac, int property, int value)
-{
- int new_status = (ac ? AC_STATUS_CHANGED : BATTERY_STATUS_CHANGED);
-
- if (ac) {
- switch (property) {
- case POWER_SUPPLY_PROP_ONLINE:
- battery_state->ac_online = value;
- break;
- }
- } else {
- switch (property) {
- case POWER_SUPPLY_PROP_STATUS:
- battery_state->status = value;
- break;
- case POWER_SUPPLY_PROP_HEALTH:
- battery_state->health = value;
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- battery_state->present = value;
- break;
- case POWER_SUPPLY_PROP_CAPACITY:
- battery_state->capacity = value;
- break;
- }
- }
-
- if (new_status != battery_state->int_status) {
- battery_state->int_status |= new_status;
- goldfish_device_set_irq(&battery_state->dev, 0, (battery_state->int_status & battery_state->int_enable));
- }
-}
-
-void goldfish_battery_display(void (* callback)(void *data, const char* string), void *data)
-{
- char buffer[100];
- char* value;
-
- sprintf(buffer, "AC: %s\r\n", (battery_state->ac_online ? "online" : "offline"));
- callback(data, buffer);
-
- switch (battery_state->status) {
- case POWER_SUPPLY_STATUS_CHARGING:
- value = "Charging";
- break;
- case POWER_SUPPLY_STATUS_DISCHARGING:
- value = "Discharging";
- break;
- case POWER_SUPPLY_STATUS_NOT_CHARGING:
- value = "Not charging";
- break;
- case POWER_SUPPLY_STATUS_FULL:
- value = "Full";
- break;
- default:
- value = "Unknown";
- break;
- }
- sprintf(buffer, "status: %s\r\n", value);
- callback(data, buffer);
-
- switch (battery_state->health) {
- case POWER_SUPPLY_HEALTH_GOOD:
- value = "Good";
- break;
- case POWER_SUPPLY_HEALTH_OVERHEAT:
- value = "Overhead";
- break;
- case POWER_SUPPLY_HEALTH_DEAD:
- value = "Dead";
- break;
- case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
- value = "Overvoltage";
- break;
- case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
- value = "Unspecified failure";
- break;
- default:
- value = "Unknown";
- break;
- }
- sprintf(buffer, "health: %s\r\n", value);
- callback(data, buffer);
-
- sprintf(buffer, "present: %s\r\n", (battery_state->present ? "true" : "false"));
- callback(data, buffer);
-
- sprintf(buffer, "capacity: %d\r\n", battery_state->capacity);
- callback(data, buffer);
-}
diff --git a/hw/goldfish_device.c b/hw/goldfish_device.c
deleted file mode 100644
index 2c9dd6e..0000000
--- a/hw/goldfish_device.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "arm_pic.h"
-#include "goldfish_device.h"
-
-#define PDEV_BUS_OP_DONE (0x00)
-#define PDEV_BUS_OP_REMOVE_DEV (0x04)
-#define PDEV_BUS_OP_ADD_DEV (0x08)
-
-#define PDEV_BUS_OP_INIT (0x00)
-
-#define PDEV_BUS_OP (0x00)
-#define PDEV_BUS_GET_NAME (0x04)
-#define PDEV_BUS_NAME_LEN (0x08)
-#define PDEV_BUS_ID (0x0c)
-#define PDEV_BUS_IO_BASE (0x10)
-#define PDEV_BUS_IO_SIZE (0x14)
-#define PDEV_BUS_IRQ (0x18)
-#define PDEV_BUS_IRQ_COUNT (0x1c)
-
-struct bus_state {
- struct goldfish_device dev;
- struct goldfish_device *current;
-};
-
-qemu_irq *goldfish_pic;
-static struct goldfish_device *first_device;
-static struct goldfish_device *last_device;
-uint32_t goldfish_free_base;
-uint32_t goldfish_free_irq;
-
-void goldfish_device_set_irq(struct goldfish_device *dev, int irq, int level)
-{
- if(irq >= dev->irq_count)
- cpu_abort (cpu_single_env, "goldfish_device_set_irq: Bad irq %d >= %d\n", irq, dev->irq_count);
- else
- qemu_set_irq(goldfish_pic[dev->irq + irq], level);
-}
-
-int goldfish_add_device_no_io(struct goldfish_device *dev)
-{
- if(dev->base == 0) {
- dev->base = goldfish_free_base;
- goldfish_free_base += dev->size;
- }
- if(dev->irq == 0 && dev->irq_count > 0) {
- dev->irq = goldfish_free_irq;
- goldfish_free_irq += dev->irq_count;
- }
- //printf("goldfish_add_device: %s, base %x %x, irq %d %d\n",
- // dev->name, dev->base, dev->size, dev->irq, dev->irq_count);
- dev->next = NULL;
- if(last_device) {
- last_device->next = dev;
- }
- else {
- first_device = dev;
- }
- last_device = dev;
- return 0;
-}
-
-int goldfish_device_add(struct goldfish_device *dev,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque)
-{
- int iomemtype;
- goldfish_add_device_no_io(dev);
- iomemtype = cpu_register_io_memory(0, mem_read,
- mem_write, opaque);
- cpu_register_physical_memory(dev->base, dev->size, iomemtype);
- return 0;
-}
-
-static uint32_t goldfish_bus_read(void *opaque, target_phys_addr_t offset)
-{
- struct bus_state *s = (struct bus_state *)opaque;
- offset -= s->dev.base;
-
- switch (offset) {
- case PDEV_BUS_OP:
- if(s->current) {
- s->current->reported_state = 1;
- s->current = s->current->next;
- }
- else {
- s->current = first_device;
- }
- while(s->current && s->current->reported_state == 1)
- s->current = s->current->next;
- if(s->current)
- return PDEV_BUS_OP_ADD_DEV;
- else {
- goldfish_device_set_irq(&s->dev, 0, 0);
- return PDEV_BUS_OP_DONE;
- }
-
- case PDEV_BUS_NAME_LEN:
- return s->current ? strlen(s->current->name) : 0;
- case PDEV_BUS_ID:
- return s->current ? s->current->id : 0;
- case PDEV_BUS_IO_BASE:
- return s->current ? s->current->base : 0;
- case PDEV_BUS_IO_SIZE:
- return s->current ? s->current->size : 0;
- case PDEV_BUS_IRQ:
- return s->current ? s->current->irq : 0;
- case PDEV_BUS_IRQ_COUNT:
- return s->current ? s->current->irq_count : 0;
- default:
- cpu_abort (cpu_single_env, "goldfish_bus_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_bus_op_init(struct bus_state *s)
-{
- struct goldfish_device *dev = first_device;
- while(dev) {
- dev->reported_state = 0;
- dev = dev->next;
- }
- s->current = NULL;
- goldfish_device_set_irq(&s->dev, 0, first_device != NULL);
-}
-
-static void goldfish_bus_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct bus_state *s = (struct bus_state *)opaque;
- offset -= s->dev.base;
-
- switch(offset) {
- case PDEV_BUS_OP:
- switch(value) {
- case PDEV_BUS_OP_INIT:
- goldfish_bus_op_init(s);
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_bus_write: Bad PDEV_BUS_OP value %x\n", value);
- };
- break;
- case PDEV_BUS_GET_NAME:
- if(s->current)
- pmemcpy(value, s->current->name, strlen(s->current->name));
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_bus_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_bus_readfn[] = {
- goldfish_bus_read,
- goldfish_bus_read,
- goldfish_bus_read
-};
-
-static CPUWriteMemoryFunc *goldfish_bus_writefn[] = {
- goldfish_bus_write,
- goldfish_bus_write,
- goldfish_bus_write
-};
-
-
-static struct bus_state bus_state = {
- .dev = {
- .name = "goldfish_device_bus",
- .id = -1,
- .base = 0x10001000,
- .size = 0x1000,
- .irq = 1,
- .irq_count = 1,
- }
-};
-
-void goldfish_device_init(qemu_irq *pic, uint32_t base, uint32_t size, uint32_t irq, uint32_t irq_count)
-{
- goldfish_pic = pic;
- goldfish_free_base = base;
- goldfish_free_irq = irq;
-}
-
-int goldfish_device_bus_init(uint32_t base, uint32_t irq)
-{
- bus_state.dev.base = base;
- bus_state.dev.irq = irq;
-
- return goldfish_device_add(&bus_state.dev, goldfish_bus_readfn, goldfish_bus_writefn, &bus_state);
-}
-
diff --git a/hw/goldfish_device.h b/hw/goldfish_device.h
deleted file mode 100644
index abe102e..0000000
--- a/hw/goldfish_device.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef GOLDFISH_DEVICE_H
-#define GOLDFISH_DEVICE_H
-
-struct goldfish_device {
- struct goldfish_device *next;
- struct goldfish_device *prev;
- uint32_t reported_state;
- void *cookie;
- const char *name;
- uint32_t id;
- uint32_t base; // filled in by goldfish_device_add if 0
- uint32_t size;
- uint32_t irq; // filled in by goldfish_device_add if 0
- uint32_t irq_count;
-};
-
-
-void goldfish_device_set_irq(struct goldfish_device *dev, int irq, int level);
-int goldfish_device_add(struct goldfish_device *dev,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque);
-
-int goldfish_add_device_no_io(struct goldfish_device *dev);
-
-void goldfish_device_init(qemu_irq *pic, uint32_t base, uint32_t size, uint32_t irq, uint32_t irq_count);
-int goldfish_device_bus_init(uint32_t base, uint32_t irq);
-
-// device init functions:
-qemu_irq *goldfish_interrupt_init(uint32_t base, qemu_irq parent_irq, qemu_irq parent_fiq);
-void goldfish_timer_and_rtc_init(uint32_t timerbase, int timerirq);
-int goldfish_tty_add(CharDriverState *cs, int id, uint32_t base, int irq);
-void goldfish_fb_init(DisplayState *ds, int id);
-void goldfish_audio_init(uint32_t base, int id, const char* input_source);
-void goldfish_battery_init();
-void goldfish_battery_set_prop(int ac, int property, int value);
-void goldfish_battery_display(void (* callback)(void *data, const char* string), void *data);
-void goldfish_mmc_init(uint32_t base, int id, BlockDriverState* bs);
-void *goldfish_switch_add(char *name, uint32_t (*writefn)(void *opaque, uint32_t state), void *writeopaque, int id);
-void goldfish_switch_set_state(void *opaque, uint32_t state);
-
-// these do not add a device
-void trace_dev_init(uint32_t base);
-void events_dev_init(uint32_t base, qemu_irq irq);
-void nand_dev_init(uint32_t base);
-
-#endif
diff --git a/hw/goldfish_events_device.c b/hw/goldfish_events_device.c
deleted file mode 100644
index 4cb2904..0000000
--- a/hw/goldfish_events_device.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "android/hw-events.h"
-#include "irq.h"
-
-#if 0
-// From kernel...
-#define EV_SYN 0x00
-#define EV_KEY 0x01
-#define EV_REL 0x02
-#define EV_ABS 0x03
-#define EV_MSC 0x04
-#define EV_SW 0x05
-#define EV_LED 0x11
-#define EV_SND 0x12
-#define EV_REP 0x14
-#define EV_FF 0x15
-#define EV_PWR 0x16
-#define EV_FF_STATUS 0x17
-#define EV_MAX 0x1f
-
-#define BTN_MISC 0x100
-#define BTN_0 0x100
-#define BTN_1 0x101
-#define BTN_2 0x102
-#define BTN_3 0x103
-#define BTN_4 0x104
-#define BTN_5 0x105
-#define BTN_6 0x106
-#define BTN_7 0x107
-#define BTN_8 0x108
-#define BTN_9 0x109
-
-#define BTN_MOUSE 0x110
-#define BTN_LEFT 0x110
-#define BTN_RIGHT 0x111
-#define BTN_MIDDLE 0x112
-#define BTN_SIDE 0x113
-#define BTN_EXTRA 0x114
-#define BTN_FORWARD 0x115
-#define BTN_BACK 0x116
-#define BTN_TASK 0x117
-
-#define BTN_JOYSTICK 0x120
-#define BTN_TRIGGER 0x120
-#define BTN_THUMB 0x121
-#define BTN_THUMB2 0x122
-#define BTN_TOP 0x123
-#define BTN_TOP2 0x124
-#define BTN_PINKIE 0x125
-#define BTN_BASE 0x126
-#define BTN_BASE2 0x127
-#define BTN_BASE3 0x128
-#define BTN_BASE4 0x129
-#define BTN_BASE5 0x12a
-#define BTN_BASE6 0x12b
-#define BTN_DEAD 0x12f
-
-#define BTN_GAMEPAD 0x130
-#define BTN_A 0x130
-#define BTN_B 0x131
-#define BTN_C 0x132
-#define BTN_X 0x133
-#define BTN_Y 0x134
-#define BTN_Z 0x135
-#define BTN_TL 0x136
-#define BTN_TR 0x137
-#define BTN_TL2 0x138
-#define BTN_TR2 0x139
-#define BTN_SELECT 0x13a
-#define BTN_START 0x13b
-#define BTN_MODE 0x13c
-#define BTN_THUMBL 0x13d
-#define BTN_THUMBR 0x13e
-
-#define BTN_DIGI 0x140
-#define BTN_TOOL_PEN 0x140
-#define BTN_TOOL_RUBBER 0x141
-#define BTN_TOOL_BRUSH 0x142
-#define BTN_TOOL_PENCIL 0x143
-#define BTN_TOOL_AIRBRUSH 0x144
-#define BTN_TOOL_FINGER 0x145
-#define BTN_TOOL_MOUSE 0x146
-#define BTN_TOOL_LENS 0x147
-#define BTN_TOUCH 0x14a
-#define BTN_STYLUS 0x14b
-#define BTN_STYLUS2 0x14c
-#define BTN_TOOL_DOUBLETAP 0x14d
-#define BTN_TOOL_TRIPLETAP 0x14e
-
-#define BTN_WHEEL 0x150
-#define BTN_GEAR_DOWN 0x150
-#define BTN_GEAR_UP 0x151
-
-#define REL_X 0x00
-#define REL_Y 0x01
-
-#define ABS_X 0x00
-#define ABS_Y 0x01
-#define ABS_Z 0x02
-#define ABS_RX 0x03
-#define ABS_RY 0x04
-#define ABS_RZ 0x05
-#define ABS_THROTTLE 0x06
-#define ABS_RUDDER 0x07
-#define ABS_WHEEL 0x08
-#define ABS_GAS 0x09
-#define ABS_BRAKE 0x0a
-#define ABS_HAT0X 0x10
-#define ABS_HAT0Y 0x11
-#define ABS_HAT1X 0x12
-#define ABS_HAT1Y 0x13
-#define ABS_HAT2X 0x14
-#define ABS_HAT2Y 0x15
-#define ABS_HAT3X 0x16
-#define ABS_HAT3Y 0x17
-#define ABS_PRESSURE 0x18
-#define ABS_DISTANCE 0x19
-#define ABS_TILT_X 0x1a
-#define ABS_TILT_Y 0x1b
-#define ABS_TOOL_WIDTH 0x1c
-#define ABS_VOLUME 0x20
-#define ABS_MISC 0x28
-#define ABS_MAX 0x3f
-#endif
-
-#define MAX_EVENTS 256*4
-
-enum {
- REG_READ = 0x00,
- REG_SET_PAGE = 0x00,
- REG_LEN = 0x04,
- REG_DATA = 0x08,
-
- PAGE_NAME = 0x00000,
- PAGE_EVBITS = 0x10000,
- PAGE_ABSDATA = 0x20000 | EV_ABS,
-};
-
-typedef struct
-{
- uint32_t base;
- qemu_irq irq;
- int pending;
- int page;
-
- unsigned events[MAX_EVENTS];
- unsigned first;
- unsigned last;
-
- const char *name;
- struct {
- size_t len;
- uint8_t *bits;
- } ev_bits[EV_MAX + 1];
- int32_t *abs_info;
- size_t abs_info_count;
-} events_state;
-
-/* modify this each time you change the events_device structure. you
- * will also need to upadte events_state_load and events_state_save
- */
-#define EVENTS_STATE_SAVE_VERSION 1
-
-#undef QFIELD_STRUCT
-#define QFIELD_STRUCT events_state
-
-QFIELD_BEGIN(events_state_fields)
- QFIELD_INT32(pending),
- QFIELD_INT32(page),
- QFIELD_BUFFER(events),
- QFIELD_INT32(first),
- QFIELD_INT32(last),
-QFIELD_END
-
-static void events_state_save(QEMUFile* f, void* opaque)
-{
- events_state* s = opaque;
-
- qemu_put_struct(f, events_state_fields, s);
-}
-
-static int events_state_load(QEMUFile* f, void* opaque, int version_id)
-{
- events_state* s = opaque;
-
- if (version_id != EVENTS_STATE_SAVE_VERSION)
- return -1;
-
- return qemu_get_struct(f, events_state_fields, s);
-}
-
-extern const char* android_skin_keycharmap;
-
-static void enqueue_event(events_state *s, unsigned int type, unsigned int code, int value)
-{
- int enqueued = s->last - s->first;
-
- if (enqueued < 0)
- enqueued += MAX_EVENTS;
-
- if (enqueued + 3 >= MAX_EVENTS-1) {
- fprintf(stderr, "##KBD: Full queue, lose event\n");
- return;
- }
-
- if(s->first == s->last){
- qemu_irq_raise(s->irq);
- }
-
- //fprintf(stderr, "##KBD: type=%d code=%d value=%d\n", type, code, value);
-
- s->events[s->last] = type;
- s->last = (s->last + 1) & (MAX_EVENTS-1);
- s->events[s->last] = code;
- s->last = (s->last + 1) & (MAX_EVENTS-1);
- s->events[s->last] = value;
- s->last = (s->last + 1) & (MAX_EVENTS-1);
-}
-
-static unsigned dequeue_event(events_state *s)
-{
- unsigned n;
-
- if(s->first == s->last) {
- return 0;
- }
-
- n = s->events[s->first];
-
- s->first = (s->first + 1) & (MAX_EVENTS - 1);
-
- if(s->first == s->last) {
- qemu_irq_lower(s->irq);
- }
-
- return n;
-}
-
-static int get_page_len(events_state *s)
-{
- int page = s->page;
- if (page == PAGE_NAME)
- return strlen(s->name);
- if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX)
- return s->ev_bits[page - PAGE_EVBITS].len;
- if (page == PAGE_ABSDATA)
- return s->abs_info_count * sizeof(s->abs_info[0]);
- return 0;
-}
-
-static int get_page_data(events_state *s, int offset)
-{
- int page_len = get_page_len(s);
- int page = s->page;
- if (offset > page_len)
- return 0;
- if (page == PAGE_NAME)
- return s->name[offset];
- if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX)
- return s->ev_bits[page - PAGE_EVBITS].bits[offset];
- if (page == PAGE_ABSDATA)
- return s->abs_info[offset / sizeof(s->abs_info[0])];
- return 0;
-}
-
-static uint32_t events_read(void *x, target_phys_addr_t off)
-{
- events_state *s = (events_state *) x;
- int offset = off - s->base;
- if (offset == REG_READ)
- return dequeue_event(s);
- else if (offset == REG_LEN)
- return get_page_len(s);
- else if (offset >= REG_DATA)
- return get_page_data(s, offset - REG_DATA);
- return 0; // this shouldn't happen, if the driver does the right thing
-}
-
-static void events_write(void *x, target_phys_addr_t off, uint32_t val)
-{
- events_state *s = (events_state *) x;
- int offset = off - s->base;
- if (offset == REG_SET_PAGE)
- s->page = val;
-}
-
-static CPUReadMemoryFunc *events_readfn[] = {
- events_read,
- events_read,
- events_read
-};
-
-static CPUWriteMemoryFunc *events_writefn[] = {
- events_write,
- events_write,
- events_write
-};
-
-static void events_put_keycode(void *x, int keycode)
-{
- events_state *s = (events_state *) x;
-
- enqueue_event(s, EV_KEY, keycode&0x1ff, (keycode&0x200) ? 1 : 0);
-}
-
-static void events_put_mouse(void *opaque, int dx, int dy, int dz, int buttons_state)
-{
- events_state *s = (events_state *) opaque;
- if (dz == 0) {
- enqueue_event(s, EV_ABS, ABS_X, dx);
- enqueue_event(s, EV_ABS, ABS_Y, dy);
- enqueue_event(s, EV_ABS, ABS_Z, dz);
- enqueue_event(s, EV_KEY, BTN_TOUCH, buttons_state&1);
- } else {
- enqueue_event(s, EV_REL, REL_X, dx);
- enqueue_event(s, EV_REL, REL_Y, dy);
- }
- enqueue_event(s, EV_SYN, 0, 0);
-}
-
-static void events_put_generic(void* opaque, int type, int code, int value)
-{
- events_state *s = (events_state *) opaque;
-
- enqueue_event(s, type, code, value);
-}
-
-static int events_set_bits(events_state *s, int type, int bitl, int bith)
-{
- uint8_t *bits;
- uint8_t maskl, maskh;
- int il, ih;
- il = bitl / 8;
- ih = bith / 8;
- if (ih >= s->ev_bits[type].len) {
- bits = qemu_mallocz(ih + 1);
- if (bits == NULL)
- return -ENOMEM;
- memcpy(bits, s->ev_bits[type].bits, s->ev_bits[type].len);
- qemu_free(s->ev_bits[type].bits);
- s->ev_bits[type].bits = bits;
- s->ev_bits[type].len = ih + 1;
- }
- else
- bits = s->ev_bits[type].bits;
- maskl = 0xffU << (bitl & 7);
- maskh = 0xffU >> (7 - (bith & 7));
- if (il >= ih)
- maskh &= maskl;
- else {
- bits[il] |= maskl;
- while (++il < ih)
- bits[il] = 0xff;
- }
- bits[ih] |= maskh;
- return 0;
-}
-
-#if 0
-static int events_set_abs_info(events_state *s, int axis, int32_t min, int32_t max, int32_t fuzz, int32_t flat)
-{
- int32_t *info;
- if (axis * 4 >= s->abs_info_count) {
- info = qemu_mallocz((axis + 1) * 4 * sizeof(int32_t));
- if (info == NULL)
- return -ENOMEM;
- memcpy(info, s->abs_info, s->abs_info_count);
- qemu_free(s->abs_info);
- s->abs_info = info;
- s->abs_info_count = (axis + 1) * 4;
- }
- else
- info = s->abs_info;
- info += axis * 4;
- *info++ = min;
- *info++ = max;
- *info++ = fuzz;
- *info++ = flat;
-}
-#endif
-
-void events_dev_init(uint32_t base, qemu_irq irq)
-{
- events_state *s;
- int iomemtype;
-
- s = (events_state *) qemu_mallocz(sizeof(events_state));
- s->name = android_skin_keycharmap;
- events_set_bits(s, EV_SYN, EV_SYN, EV_ABS);
- events_set_bits(s, EV_SYN, EV_SW, EV_SW);
- events_set_bits(s, EV_KEY, 1, 0x1ff);
- events_set_bits(s, EV_REL, REL_X, REL_Y);
- events_set_bits(s, EV_ABS, ABS_X, ABS_Z);
- events_set_bits(s, EV_SW, 0, 0);
- iomemtype = cpu_register_io_memory(0, events_readfn, events_writefn, s);
-
- cpu_register_physical_memory(base, 0xfff, iomemtype);
-
- qemu_add_kbd_event_handler(events_put_keycode, s);
- qemu_add_mouse_event_handler(events_put_mouse, s, 1);
- qemu_add_generic_event_handler(events_put_generic, s);
-
- s->base = base;
- s->irq = irq;
-
- s->first = 0;
- s->last = 0;
-
- register_savevm( "events_state", 0, EVENTS_STATE_SAVE_VERSION,
- events_state_save, events_state_load, s );
-}
-
diff --git a/hw/goldfish_fb.c b/hw/goldfish_fb.c
deleted file mode 100644
index 71cede2..0000000
--- a/hw/goldfish_fb.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "android/android.h"
-#include "goldfish_device.h"
-#include "framebuffer.h"
-
-enum {
- FB_GET_WIDTH = 0x00,
- FB_GET_HEIGHT = 0x04,
- FB_INT_STATUS = 0x08,
- FB_INT_ENABLE = 0x0c,
- FB_SET_BASE = 0x10,
- FB_SET_ROTATION = 0x14,
- FB_SET_BLANK = 0x18,
- FB_GET_PHYS_WIDTH = 0x1c,
- FB_GET_PHYS_HEIGHT = 0x20,
-
- FB_INT_VSYNC = 1U << 0,
- FB_INT_BASE_UPDATE_DONE = 1U << 1
-};
-
-struct goldfish_fb_state {
- struct goldfish_device dev;
- QFrameBuffer* qfbuff;
- uint32_t fb_base;
- uint32_t base_valid : 1;
- uint32_t need_update : 1;
- uint32_t need_int : 1;
- uint32_t set_rotation : 2;
- uint32_t blank : 1;
- uint32_t int_status;
- uint32_t int_enable;
- int rotation; /* 0, 1, 2 or 3 */
-};
-
-#define GOLDFISH_FB_SAVE_VERSION 1
-
-static void goldfish_fb_save(QEMUFile* f, void* opaque)
-{
- struct goldfish_fb_state* s = opaque;
-
- QFrameBuffer* q = s->qfbuff;
-
- qemu_put_be32(f, q->width);
- qemu_put_be32(f, q->height);
- qemu_put_be32(f, q->pitch);
- qemu_put_byte(f, q->rotation);
-
- qemu_put_be32(f, s->fb_base);
- qemu_put_byte(f, s->base_valid);
- qemu_put_byte(f, s->need_update);
- qemu_put_byte(f, s->need_int);
- qemu_put_byte(f, s->set_rotation);
- qemu_put_byte(f, s->blank);
- qemu_put_be32(f, s->int_status);
- qemu_put_be32(f, s->int_enable);
- qemu_put_be32(f, s->rotation);
-}
-
-static int goldfish_fb_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct goldfish_fb_state* s = opaque;
-
- QFrameBuffer* q = s->qfbuff;
- int ret = -1;
- int ds_w, ds_h, ds_pitch, ds_rot;
-
- if (version_id != GOLDFISH_FB_SAVE_VERSION)
- goto Exit;
-
- ds_w = qemu_get_be32(f);
- ds_h = qemu_get_be32(f);
- ds_pitch = qemu_get_be32(f);
- ds_rot = qemu_get_byte(f);
-
- if (q->width != ds_w ||
- q->height != ds_h ||
- q->pitch != ds_pitch ||
- q->rotation != ds_rot )
- {
- /* XXX: We should be able to force a resize/rotation from here ? */
- fprintf(stderr, "%s: framebuffer dimensions mismatch\n", __FUNCTION__);
- goto Exit;
- }
-
- s->fb_base = qemu_get_be32(f);
- s->base_valid = qemu_get_byte(f);
- s->need_update = qemu_get_byte(f);
- s->need_int = qemu_get_byte(f);
- s->set_rotation = qemu_get_byte(f);
- s->blank = qemu_get_byte(f);
- s->int_status = qemu_get_be32(f);
- s->int_enable = qemu_get_be32(f);
- s->rotation = qemu_get_be32(f);
-
- /* force a refresh */
- s->need_update = 1;
-
- ret = 0;
-Exit:
- return ret;
-}
-
-
-#define STATS 0
-
-#if STATS
-static int stats_counter;
-static long stats_total;
-static int stats_full_updates;
-static long stats_total_full_updates;
-#endif
-
-static void goldfish_fb_update_display(void *opaque)
-{
- struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque;
- uint32_t addr;
- uint32_t base;
-
- uint8_t* dst_line;
- uint8_t* src_line;
- int y_first, y_last = 0;
- int full_update = 0;
- int width, height, pitch;
-
- base = s->fb_base;
- if(base == 0)
- return;
-
- if((s->int_enable & FB_INT_VSYNC) && !(s->int_status & FB_INT_VSYNC)) {
- s->int_status |= FB_INT_VSYNC;
- goldfish_device_set_irq(&s->dev, 0, 1);
- }
-
- y_first = -1;
- addr = base;
- if(s->need_update) {
- full_update = 1;
- if(s->need_int) {
- s->int_status |= FB_INT_BASE_UPDATE_DONE;
- if(s->int_enable & FB_INT_BASE_UPDATE_DONE)
- goldfish_device_set_irq(&s->dev, 0, 1);
- }
- s->need_int = 0;
- s->need_update = 0;
- }
-
- src_line = phys_ram_base + base;
- dst_line = s->qfbuff->pixels;
- pitch = s->qfbuff->pitch;
- width = s->qfbuff->width;
- height = s->qfbuff->height;
-
-#if STATS
- if (full_update)
- stats_full_updates += 1;
- if (++stats_counter == 120) {
- stats_total += stats_counter;
- stats_total_full_updates += stats_full_updates;
-
- printf( "full update stats: peak %.2f %% total %.2f %%\n",
- stats_full_updates*100.0/stats_counter,
- stats_total_full_updates*100.0/stats_total );
-
- stats_counter = 0;
- stats_full_updates = 0;
- }
-#endif /* STATS */
-
- if (s->blank)
- {
- memset( dst_line, 0, height*pitch );
- y_first = 0;
- y_last = height-1;
- }
- else if (full_update)
- {
- int yy;
-
- for (yy = 0; yy < height; yy++, dst_line += pitch, src_line += width*2)
- {
- uint16_t* src = (uint16_t*) src_line;
- uint16_t* dst = (uint16_t*) dst_line;
- int nn;
-
- for (nn = 0; nn < width; nn++) {
- unsigned spix = src[nn];
- unsigned dpix = dst[nn];
-#if WORDS_BIGENDIAN
- spix = ((spix << 8) | (spix >> 8)) & 0xffff;
-#else
- if (spix != dpix)
- break;
-#endif
- }
-
- if (nn == width)
- continue;
-
-#if WORDS_BIGENDIAN
- for ( ; nn < width; nn++ ) {
- unsigned spix = src[nn];
- dst[nn] = (uint16_t)((spix << 8) | (spix >> 8));
- }
-#else
- memcpy( dst+nn, src+nn, (width-nn)*2 );
-#endif
-
- y_first = (y_first < 0) ? yy : y_first;
- y_last = yy;
- }
- }
- else /* not a full update, should not happen very often with Android */
- {
- int yy;
-
- for (yy = 0; yy < height; yy++, dst_line += pitch, src_line += width*2)
- {
- uint16_t* src = (uint16_t*) src_line;
- uint16_t* dst = (uint16_t*) dst_line;
- int len = width*2;
-#if WORDS_BIGENDIAN
- int nn;
-#endif
- int dirty = 0;
-
- while (len > 0) {
- int len2 = TARGET_PAGE_SIZE - (addr & (TARGET_PAGE_SIZE-1));
-
- if (len2 > len)
- len2 = len;
-
- dirty |= cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
- addr += len2;
- len -= len2;
- }
-
- if (!dirty)
- continue;
-
-#if WORDS_BIGENDIAN
- for (nn = 0; nn < width; nn++ ) {
- unsigned spix = src[nn];
- dst[nn] = (uint16_t)((spix << 8) | (spix >> 8));
- }
-#else
- memcpy( dst, src, width*2 );
-#endif
-
- y_first = (y_first < 0) ? yy : y_first;
- y_last = yy;
- }
- }
-
- if (y_first < 0)
- return;
-
- y_last += 1;
- //printf("goldfish_fb_update_display %d %d, base %x\n", first, last, base);
-
- cpu_physical_memory_reset_dirty(base + y_first * width * 2,
- base + y_last * width * 2,
- VGA_DIRTY_FLAG);
-
- qframebuffer_update( s->qfbuff, 0, y_first, width, y_last-y_first );
-}
-
-static void goldfish_fb_invalidate_display(void * opaque)
-{
- // is this called?
- struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque;
- s->need_update = 1;
-}
-
-static void goldfish_fb_detach_display(void* opaque)
-{
- struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque;
- s->qfbuff = NULL;
-}
-
-static uint32_t goldfish_fb_read(void *opaque, target_phys_addr_t offset)
-{
- uint32_t ret;
- struct goldfish_fb_state *s = opaque;
- offset -= s->dev.base;
- switch(offset) {
- case FB_GET_WIDTH:
- ret = s->qfbuff->width;
- //printf("FB_GET_WIDTH => %d\n", ret);
- return ret;
-
- case FB_GET_HEIGHT:
- ret = s->qfbuff->height;
- //printf( "FB_GET_HEIGHT = %d\n", ret);
- return ret;
-
- case FB_INT_STATUS:
- ret = s->int_status & s->int_enable;
- if(ret) {
- s->int_status &= ~ret;
- goldfish_device_set_irq(&s->dev, 0, 0);
- }
- return ret;
-
- case FB_GET_PHYS_WIDTH:
- ret = s->qfbuff->phys_width_mm;
- //printf( "FB_GET_PHYS_WIDTH => %d\n", ret );
- return ret;
-
- case FB_GET_PHYS_HEIGHT:
- ret = s->qfbuff->phys_height_mm;
- //printf( "FB_GET_PHYS_HEIGHT => %d\n", ret );
- return ret;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_fb_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_fb_write(void *opaque, target_phys_addr_t offset,
- uint32_t val)
-{
- struct goldfish_fb_state *s = opaque;
- offset -= s->dev.base;
- switch(offset) {
- case FB_INT_ENABLE:
- s->int_enable = val;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
- case FB_SET_BASE: {
- int need_resize = !s->base_valid;
- s->fb_base = val;
- s->int_status &= ~FB_INT_BASE_UPDATE_DONE;
- s->need_update = 1;
- s->need_int = 1;
- s->base_valid = 1;
- if(s->set_rotation != s->rotation) {
- //printf("FB_SET_BASE: rotation : %d => %d\n", s->rotation, s->set_rotation);
- s->rotation = s->set_rotation;
- need_resize = 1;
- }
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- if (need_resize) {
- //printf("FB_SET_BASE: need resize (rotation=%d)\n", s->rotation );
- qframebuffer_rotate( s->qfbuff, s->rotation );
- }
- } break;
- case FB_SET_ROTATION:
- //printf( "FB_SET_ROTATION %d\n", val);
- s->set_rotation = val;
- break;
- case FB_SET_BLANK:
- s->blank = val;
- s->need_update = 1;
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_fb_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_fb_readfn[] = {
- goldfish_fb_read,
- goldfish_fb_read,
- goldfish_fb_read
-};
-
-static CPUWriteMemoryFunc *goldfish_fb_writefn[] = {
- goldfish_fb_write,
- goldfish_fb_write,
- goldfish_fb_write
-};
-
-void goldfish_fb_init(DisplayState *ds, int id)
-{
- struct goldfish_fb_state *s;
-
- s = (struct goldfish_fb_state *)qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish_fb";
- s->dev.id = id;
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
-
- s->qfbuff = qframebuffer_fifo_get();
- qframebuffer_set_producer( s->qfbuff, s,
- goldfish_fb_update_display,
- goldfish_fb_invalidate_display,
- goldfish_fb_detach_display );
-
- goldfish_device_add(&s->dev, goldfish_fb_readfn, goldfish_fb_writefn, s);
-
- register_savevm( "goldfish_fb", 0, GOLDFISH_FB_SAVE_VERSION,
- goldfish_fb_save, goldfish_fb_load, s);
-}
-
diff --git a/hw/goldfish_interrupt.c b/hw/goldfish_interrupt.c
deleted file mode 100644
index 2cba649..0000000
--- a/hw/goldfish_interrupt.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "arm_pic.h"
-#include "goldfish_device.h"
-#include "irq.h"
-
-enum {
- INTERRUPT_STATUS = 0x00, // number of pending interrupts
- INTERRUPT_NUMBER = 0x04,
- INTERRUPT_DISABLE_ALL = 0x08,
- INTERRUPT_DISABLE = 0x0c,
- INTERRUPT_ENABLE = 0x10
-};
-
-struct goldfish_int_state {
- struct goldfish_device dev;
- uint32_t level;
- uint32_t pending_count;
- uint32_t irq_enabled;
- uint32_t fiq_enabled;
- qemu_irq parent_irq;
- qemu_irq parent_fiq;
-};
-
-#define GOLDFISH_INT_SAVE_VERSION 1
-
-#define QFIELD_STRUCT struct goldfish_int_state
-QFIELD_BEGIN(goldfish_int_fields)
- QFIELD_INT32(level),
- QFIELD_INT32(pending_count),
- QFIELD_INT32(irq_enabled),
- QFIELD_INT32(fiq_enabled),
-QFIELD_END
-
-static void goldfish_int_save(QEMUFile* f, void* opaque)
-{
- struct goldfish_int_state* s = opaque;
-
- qemu_put_struct(f, goldfish_int_fields, s);
-}
-
-static int goldfish_int_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct goldfish_int_state* s = opaque;
-
- if (version_id != GOLDFISH_INT_SAVE_VERSION)
- return -1;
-
- return qemu_get_struct(f, goldfish_int_fields, s);
-}
-
-static void goldfish_int_update(struct goldfish_int_state *s)
-{
- uint32_t flags;
-
- flags = (s->level & s->irq_enabled);
- qemu_set_irq(s->parent_irq, flags != 0);
-
- flags = (s->level & s->fiq_enabled);
- qemu_set_irq(s->parent_fiq, flags != 0);
-}
-
-static void goldfish_int_set_irq(void *opaque, int irq, int level)
-{
- struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;
- uint32_t mask = (1U << irq);
-
- if(level) {
- if(!(s->level & mask)) {
- if(s->irq_enabled & mask)
- s->pending_count++;
- s->level |= mask;
- }
- }
- else {
- if(s->level & mask) {
- if(s->irq_enabled & mask)
- s->pending_count--;
- s->level &= ~mask;
- }
- }
- goldfish_int_update(s);
-}
-
-static uint32_t goldfish_int_read(void *opaque, target_phys_addr_t offset)
-{
- struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;
- offset -= s->dev.base;
-
- switch (offset) {
- case INTERRUPT_STATUS: /* IRQ_STATUS */
- return s->pending_count;
- case INTERRUPT_NUMBER: {
- int i;
- uint32_t pending = s->level & s->irq_enabled;
- for(i = 0; i < 32; i++) {
- if(pending & (1U << i))
- return i;
- }
- return 0;
- }
- default:
- cpu_abort (cpu_single_env, "goldfish_int_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_int_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;
- uint32_t mask = (1U << value);
- offset -= s->dev.base;
-
- switch (offset) {
- case INTERRUPT_DISABLE_ALL:
- s->pending_count = 0;
- s->level = 0;
- break;
-
- case INTERRUPT_DISABLE:
- if(s->irq_enabled & mask) {
- if(s->level & mask)
- s->pending_count--;
- s->irq_enabled &= ~mask;
- }
- break;
- case INTERRUPT_ENABLE:
- if(!(s->irq_enabled & mask)) {
- s->irq_enabled |= mask;
- if(s->level & mask)
- s->pending_count++;
- }
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_int_write: Bad offset %x\n", offset);
- return;
- }
- goldfish_int_update(s);
-}
-
-static CPUReadMemoryFunc *goldfish_int_readfn[] = {
- goldfish_int_read,
- goldfish_int_read,
- goldfish_int_read
-};
-
-static CPUWriteMemoryFunc *goldfish_int_writefn[] = {
- goldfish_int_write,
- goldfish_int_write,
- goldfish_int_write
-};
-
-qemu_irq* goldfish_interrupt_init(uint32_t base, qemu_irq parent_irq, qemu_irq parent_fiq)
-{
- int ret;
- struct goldfish_int_state *s;
- qemu_irq* qi;
-
- s = qemu_mallocz(sizeof(*s));
- qi = qemu_allocate_irqs(goldfish_int_set_irq, s, 32);
- s->dev.name = "goldfish_interrupt_controller";
- s->dev.id = -1;
- s->dev.base = base;
- s->dev.size = 0x1000;
- s->parent_irq = parent_irq;
- s->parent_fiq = parent_fiq;
-
- ret = goldfish_device_add(&s->dev, goldfish_int_readfn, goldfish_int_writefn, s);
- if(ret) {
- qemu_free(s);
- return NULL;
- }
-
- register_savevm( "goldfish_int", 0, GOLDFISH_INT_SAVE_VERSION,
- goldfish_int_save, goldfish_int_load, s);
-
- return qi;
-}
-
diff --git a/hw/goldfish_memlog.c b/hw/goldfish_memlog.c
deleted file mode 100644
index 98fcffc..0000000
--- a/hw/goldfish_memlog.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "qemu_file.h"
-#include "goldfish_device.h"
-#include "audio/audio.h"
-
-extern void dprint(const char* fmt, ...);
-
-int fd = -1;
-
-static uint32_t memlog_read(void *opaque, target_phys_addr_t offset)
-{
- struct goldfish_device *dev = opaque;
- offset -= dev->base;
-
- return 0;
-}
-
-unsigned info[8];
-
-static void memlog_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- char buf[128];
- struct goldfish_device *dev = opaque;
- offset -= dev->base;
-
- info[offset / 4] = val;
-
- if (offset == 0) {
- /* write PID and VADDR to logfile */
- sprintf(buf,"%08x %08x\n", info[0], info[1]);
- write(fd, buf, strlen(buf));
- }
-}
-
-
-static CPUReadMemoryFunc *memlog_readfn[] = {
- memlog_read,
- memlog_read,
- memlog_read
-};
-
-static CPUWriteMemoryFunc *memlog_writefn[] = {
- memlog_write,
- memlog_write,
- memlog_write
-};
-
-struct goldfish_device memlog_dev;
-
-void goldfish_memlog_init(uint32_t base)
-{
- struct goldfish_device *dev = &memlog_dev;
-
- dev->name = "goldfish_memlog";
- dev->id = 0;
- dev->base = base;
- dev->size = 0x1000;
- dev->irq_count = 0;
-
- fd = open("mem.log", /* O_CREAT | */ O_TRUNC | O_WRONLY, 0644);
-
- goldfish_device_add(dev, memlog_readfn, memlog_writefn, dev);
-}
-
diff --git a/hw/goldfish_mmc.c b/hw/goldfish_mmc.c
deleted file mode 100644
index 272f403..0000000
--- a/hw/goldfish_mmc.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_device.h"
-#include "mmc.h"
-#include "sd.h"
-#include "block.h"
-
-enum {
- /* status register */
- MMC_INT_STATUS = 0x00,
- /* set this to enable IRQ */
- MMC_INT_ENABLE = 0x04,
- /* set this to specify buffer address */
- MMC_SET_BUFFER = 0x08,
-
- /* MMC command number */
- MMC_CMD = 0x0C,
-
- /* MMC argument */
- MMC_ARG = 0x10,
-
- /* MMC response (or R2 bits 0 - 31) */
- MMC_RESP_0 = 0x14,
-
- /* MMC R2 response bits 32 - 63 */
- MMC_RESP_1 = 0x18,
-
- /* MMC R2 response bits 64 - 95 */
- MMC_RESP_2 = 0x1C,
-
- /* MMC R2 response bits 96 - 127 */
- MMC_RESP_3 = 0x20,
-
- MMC_BLOCK_LENGTH = 0x24,
- MMC_BLOCK_COUNT = 0x28,
-
- /* MMC state flags */
- MMC_STATE = 0x2C,
-
- /* MMC_INT_STATUS bits */
-
- MMC_STAT_END_OF_CMD = 1U << 0,
- MMC_STAT_END_OF_DATA = 1U << 1,
- MMC_STAT_STATE_CHANGE = 1U << 2,
-
- /* MMC_STATE bits */
- MMC_STATE_INSERTED = 1U << 0,
- MMC_STATE_READ_ONLY = 1U << 1,
-};
-
-
-struct goldfish_mmc_state {
- struct goldfish_device dev;
- BlockDriverState *bs;
- // pointer to our buffer
- uint8_t* buffer;
- // offsets for read and write operations
- uint32_t read_offset, write_offset;
- // buffer status flags
- uint32_t int_status;
- // irq enable mask for int_status
- uint32_t int_enable;
-
- // MMC command argument
- uint32_t arg;
- uint32_t resp[4];
-
- uint32_t block_length;
- uint32_t block_count;
- int is_SDHC;
-};
-
-#define GOLDFISH_MMC_SAVE_VERSION 1
-#define QFIELD_STRUCT struct goldfish_mmc_state
-QFIELD_BEGIN(goldfish_mmc_fields)
- QFIELD_INT32(read_offset),
- QFIELD_INT32(write_offset),
- QFIELD_INT32(int_status),
- QFIELD_INT32(int_enable),
- QFIELD_INT32(arg),
- QFIELD_INT32(resp[0]),
- QFIELD_INT32(resp[1]),
- QFIELD_INT32(resp[2]),
- QFIELD_INT32(resp[3]),
- QFIELD_INT32(block_length),
- QFIELD_INT32(block_count),
- QFIELD_INT32(is_SDHC),
-QFIELD_END
-
-static void goldfish_mmc_save(QEMUFile* f, void* opaque)
-{
- struct goldfish_mmc_state* s = opaque;
-
- qemu_put_be32(f, s->buffer - phys_ram_base);
- qemu_put_struct(f, goldfish_mmc_fields, s);
-}
-
-static int goldfish_mmc_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct goldfish_mmc_state* s = opaque;
-
- if (version_id != GOLDFISH_MMC_SAVE_VERSION)
- return -1;
-
- s->buffer = qemu_get_be32(f) + phys_ram_base;
- return qemu_get_struct(f, goldfish_mmc_fields, s);
-}
-
-struct mmc_opcode {
- const char* name;
- int cmd;
-} mmc_opcodes[] = {
- { "MMC_GO_IDLE_STATE", 0 },
- { "MMC_SEND_OP_COND", 1 },
- { "MMC_ALL_SEND_CID", 2 },
- { "MMC_SET_RELATIVE_ADDR", 3 },
- { "MMC_SET_DSR", 4 },
- { "MMC_SWITCH", 6 },
- { "MMC_SELECT_CARD", 7 },
- { "MMC_SEND_EXT_CSD", 8 },
- { "MMC_SEND_CSD", 9 },
- { "MMC_SEND_CID", 10 },
- { "MMC_READ_DAT_UNTIL_STOP", 11 },
- { "MMC_STOP_TRANSMISSION", 12 },
- { "MMC_SEND_STATUS", 13 },
- { "MMC_GO_INACTIVE_STATE", 15 },
- { "MMC_SET_BLOCKLEN", 16 },
- { "MMC_READ_SINGLE_BLOCK", 17 },
- { "MMC_READ_MULTIPLE_BLOCK", 18 },
- { "MMC_WRITE_DAT_UNTIL_STOP", 20 },
- { "MMC_SET_BLOCK_COUNT", 23 },
- { "MMC_WRITE_BLOCK", 24 },
- { "MMC_WRITE_MULTIPLE_BLOCK", 25 },
- { "MMC_PROGRAM_CID", 26 },
- { "MMC_PROGRAM_CSD", 27 },
- { "MMC_SET_WRITE_PROT", 28 },
- { "MMC_CLR_WRITE_PROT", 29 },
- { "MMC_SEND_WRITE_PROT", 30 },
- { "MMC_ERASE_GROUP_START", 35 },
- { "MMC_ERASE_GROUP_END", 36 },
- { "MMC_ERASE", 38 },
- { "MMC_FAST_IO", 39 },
- { "MMC_GO_IRQ_STATE", 40 },
- { "MMC_LOCK_UNLOCK", 42 },
- { "MMC_APP_CMD", 55 },
- { "MMC_GEN_CMD", 56 },
- { "SD_APP_OP_COND", 41 },
- { "SD_APP_SEND_SCR", 51 },
- { "UNKNOWN", -1 }
-};
-
-#if 0
-static const char* get_command_name(int command)
-{
- struct mmc_opcode* opcode = mmc_opcodes;
-
- while (opcode->cmd != command && opcode->cmd != -1) opcode++;
- return opcode->name;
-}
-#endif
-
-static void goldfish_mmc_do_command(struct goldfish_mmc_state *s, uint32_t cmd, uint32_t arg)
-{
- int result;
- int new_status = MMC_STAT_END_OF_CMD;
- int opcode = cmd & 63;
-
-// fprintf(stderr, "goldfish_mmc_do_command opcode: %s (0x%04X), arg: %d\n", get_command_name(opcode), cmd, arg);
-
- s->resp[0] = 0;
- s->resp[1] = 0;
- s->resp[2] = 0;
- s->resp[3] = 0;
-
-#define SET_R1_CURRENT_STATE(s) ((s << 9) & 0x00001E00) /* sx, b (4 bits) */
-
- switch (opcode) {
- case MMC_SEND_CSD: {
- int64_t sector_count = 0;
- uint64_t capacity;
- uint8_t exponent;
- uint32_t m;
-
- bdrv_get_geometry(s->bs, (uint64_t*)&sector_count);
- capacity = sector_count * 512;
- if (capacity > 2147483648U) {
- // if storages is > 2 gig, then emulate SDHC card
- s->is_SDHC = 1;
-
- // CSD bits borrowed from a real SDHC card, with capacity bits zeroed out
- s->resp[3] = 0x400E0032;
- s->resp[2] = 0x5B590000;
- s->resp[1] = 0x00007F80;
- s->resp[0] = 0x0A4040DF;
-
- // stuff in the real capacity
- // m = UNSTUFF_BITS(resp, 48, 22);
- m = (uint32_t)(capacity / (512*1024)) - 1;
- // m must fit into 22 bits
- if (m & 0xFFC00000) {
- fprintf(stderr, "SD card too big (%lld bytes). Maximum SDHC card size is 128 gigabytes.\n", capacity);
- abort();
- }
-
- // low 16 bits go in high end of resp[1]
- s->resp[1] |= ((m & 0x0000FFFF) << 16);
- // high 6 bits go in low end of resp[2]
- s->resp[2] |= (m >> 16);
- } else {
- // emulate standard SD card
- s->is_SDHC = 0;
-
- // CSD bits borrowed from a real SD card, with capacity bits zeroed out
- s->resp[3] = 0x00260032;
- s->resp[2] = 0x5F5A8000;
- s->resp[1] = 0x3EF84FFF;
- s->resp[0] = 0x928040CB;
-
- // stuff in the real capacity
- // e = UNSTUFF_BITS(resp, 47, 3);
- // m = UNSTUFF_BITS(resp, 62, 12);
- // csd->capacity = (1 + m) << (e + 2);
- // need to reverse the formula and calculate e and m
- exponent = 0;
- capacity = sector_count * 512;
- if (capacity > 2147483648U) {
- fprintf(stderr, "SD card too big (%lld bytes). Maximum SD card size is 2 gigabytes.\n", capacity);
- abort();
- }
- capacity >>= 10; // convert to Kbytes
- while (capacity > 4096) {
- // (capacity - 1) must fit into 12 bits
- exponent++;
- capacity >>= 1;
- }
- capacity -= 1;
- exponent -= 2;
- if (exponent > 7)
- cpu_abort(cpu_single_env, "exponent %d too big\n", exponent);
-
- s->resp[2] |= (((uint32_t)capacity >> 2) & 0x3FF); // high 10 bits to bottom of resp[2]
- s->resp[1] |= (((uint32_t)capacity & 3) << 30); // low 2 bits to top of resp[1]
- s->resp[1] |= (exponent << (47 - 32));
- }
- break;
- }
-
- case MMC_SEND_EXT_CSD:
- s->resp[0] = arg;
- break;
-
- case MMC_APP_CMD:
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA | R1_APP_CMD; //2336
- break;
-
- case SD_APP_OP_COND:
- s->resp[0] = 0x80FF8000;
- break;
-
- case SD_APP_SEND_SCR:
- {
- uint32_t* scr = (uint32_t*)s->buffer;
- scr[0] = 0x00002502;
- scr[1] = 0x00000000;
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA | R1_APP_CMD; //2336
- new_status |= MMC_STAT_END_OF_DATA;
- break;
- }
- case MMC_SET_RELATIVE_ADDR:
- s->resp[0] = -518519520;
- break;
-
- case MMC_ALL_SEND_CID:
- s->resp[3] = 55788627;
- s->resp[2] = 1429221959;
- s->resp[1] = -2147479692;
- s->resp[0] = -436179883;
- break;
-
- case MMC_SELECT_CARD:
- s->resp[0] = SET_R1_CURRENT_STATE(3) | R1_READY_FOR_DATA; // 1792
- break;
-
- case MMC_SWITCH:
- if (arg == 0x00FFFFF1 || arg == 0x80FFFFF1) {
- uint8_t* switchbuf = s->buffer;
- memset(switchbuf, 0, 64);
- switchbuf[13] = 2;
- new_status |= MMC_STAT_END_OF_DATA;
- }
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA | R1_APP_CMD; //2336
- break;
-
- case MMC_SET_BLOCKLEN:
- s->block_length = arg;
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA; // 2304
- break;
-
- case MMC_READ_SINGLE_BLOCK:
- s->block_count = 1;
- // fall through
- case MMC_READ_MULTIPLE_BLOCK: {
- if (s->is_SDHC) {
- // arg is block offset
- } else {
- // arg is byte offset
- if (arg & 511) fprintf(stderr, "offset %d is not multiple of 512 when reading\n", arg);
- arg /= s->block_length;
- }
- result = bdrv_read(s->bs, arg, s->buffer, s->block_count);
- new_status |= MMC_STAT_END_OF_DATA;
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA; // 2304
- break;
- }
-
- case MMC_WRITE_BLOCK:
- s->block_count = 1;
- // fall through
- case MMC_WRITE_MULTIPLE_BLOCK: {
- if (s->is_SDHC) {
- // arg is block offset
- } else {
- // arg is byte offset
- if (arg & 511) fprintf(stderr, "offset %d is not multiple of 512 when writing\n", arg);
- arg /= s->block_length;
- }
- // arg is byte offset
- result = bdrv_write(s->bs, arg, s->buffer, s->block_count);
-// bdrv_flush(s->bs);
- new_status |= MMC_STAT_END_OF_DATA;
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA; // 2304
- break;
- }
-
- case MMC_STOP_TRANSMISSION:
- s->resp[0] = SET_R1_CURRENT_STATE(5) | R1_READY_FOR_DATA; // 2816
- break;
-
- case MMC_SEND_STATUS:
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA; // 2304
- break;
- }
-
- s->int_status |= new_status;
-
- if ((s->int_status & s->int_enable)) {
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- }
-}
-
-static uint32_t goldfish_mmc_read(void *opaque, target_phys_addr_t offset)
-{
- uint32_t ret;
- struct goldfish_mmc_state *s = opaque;
-
- offset -= s->dev.base;
- switch(offset) {
- case MMC_INT_STATUS:
- // return current buffer status flags
- return s->int_status & s->int_enable;
- case MMC_RESP_0:
- return s->resp[0];
- case MMC_RESP_1:
- return s->resp[1];
- case MMC_RESP_2:
- return s->resp[2];
- case MMC_RESP_3:
- return s->resp[3];
- case MMC_STATE: {
- ret = MMC_STATE_INSERTED;
- if (bdrv_is_read_only(s->bs)) {
- ret |= MMC_STATE_READ_ONLY;
- }
- return ret;
- }
- default:
- cpu_abort(cpu_single_env, "goldfish_mmc_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_mmc_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- struct goldfish_mmc_state *s = opaque;
- int status, old_status;
-
- offset -= s->dev.base;
-
- switch(offset) {
-
- case MMC_INT_STATUS:
- status = s->int_status;
- old_status = status;
- status &= ~val;
- s->int_status = status;
- if(status != old_status) {
- goldfish_device_set_irq(&s->dev, 0, status);
- }
- break;
-
- case MMC_INT_ENABLE:
- /* enable buffer interrupts */
- s->int_enable = val;
- s->int_status = 0;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
- case MMC_SET_BUFFER:
- /* save pointer to buffer 1 */
- s->buffer = phys_ram_base + val;
- break;
- case MMC_CMD:
- goldfish_mmc_do_command(s, val, s->arg);
- break;
- case MMC_ARG:
- s->arg = val;
- break;
- case MMC_BLOCK_LENGTH:
- s->block_length = val + 1;
- break;
- case MMC_BLOCK_COUNT:
- s->block_count = val + 1;
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_mmc_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_mmc_readfn[] = {
- goldfish_mmc_read,
- goldfish_mmc_read,
- goldfish_mmc_read
-};
-
-static CPUWriteMemoryFunc *goldfish_mmc_writefn[] = {
- goldfish_mmc_write,
- goldfish_mmc_write,
- goldfish_mmc_write
-};
-
-void goldfish_mmc_init(uint32_t base, int id, BlockDriverState* bs)
-{
- struct goldfish_mmc_state *s;
-
- s = (struct goldfish_mmc_state *)qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish_mmc";
- s->dev.id = id;
- s->dev.base = base;
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
- s->bs = bs;
-
- goldfish_device_add(&s->dev, goldfish_mmc_readfn, goldfish_mmc_writefn, s);
-
- register_savevm( "goldfish_mmc", 0, GOLDFISH_MMC_SAVE_VERSION,
- goldfish_mmc_save, goldfish_mmc_load, s);
-}
-
diff --git a/hw/goldfish_nand.c b/hw/goldfish_nand.c
deleted file mode 100644
index 61b075e..0000000
--- a/hw/goldfish_nand.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_nand_reg.h"
-#include "goldfish_nand.h"
-#include "android/utils/tempfile.h"
-#include "qemu_debug.h"
-#include "android/android.h"
-
-#define DEBUG 1
-#if DEBUG
-# define D(...) VERBOSE_PRINT(nand,__VA_ARGS__)
-# define D_ACTIVE VERBOSE_CHECK(nand)
-# define T(...) VERBOSE_PRINT(nand_limits,__VA_ARGS__)
-# define T_ACTIVE VERBOSE_CHECK(nand_limits)
-#else
-# define D(...) ((void)0)
-# define D_ACTIVE 0
-# define T(...) ((void)0)
-# define T_ACTIVE 0
-#endif
-
-/* lseek uses 64-bit offsets on Darwin. */
-/* prefer lseek64 on Linux */
-#ifdef __APPLE__
-# define llseek lseek
-#elif defined(__linux__)
-# define llseek lseek64
-#endif
-
-#define XLOG xlog
-
-static void
-xlog( const char* format, ... )
-{
- va_list args;
- va_start(args, format);
- fprintf(stderr, "NAND: ");
- vfprintf(stderr, format, args);
- va_end(args);
-}
-
-typedef struct {
- char* devname;
- size_t devname_len;
- char* data;
- int fd;
- uint32_t flags;
- uint32_t page_size;
- uint32_t extra_size;
- uint32_t erase_size;
- uint64_t size;
-} nand_dev;
-
-nand_threshold android_nand_write_threshold;
-nand_threshold android_nand_read_threshold;
-
-#ifdef CONFIG_NAND_THRESHOLD
-
-/* update a threshold, return 1 if limit is hit, 0 otherwise */
-static void
-nand_threshold_update( nand_threshold* t, uint32_t len )
-{
- if (t->counter < t->limit) {
- uint64_t avail = t->limit - t->counter;
- if (avail > len)
- avail = len;
-
- if (t->counter == 0) {
- T("%s: starting threshold counting to %lld",
- __FUNCTION__, t->limit);
- }
- t->counter += avail;
- if (t->counter >= t->limit) {
- /* threshold reach, send a signal to an external process */
- T( "%s: sending signal %d to pid %d !",
- __FUNCTION__, t->signal, t->pid );
-
- kill( t->pid, t->signal );
- }
- }
- return;
-}
-
-#define NAND_UPDATE_READ_THRESHOLD(len) \
- nand_threshold_update( &android_nand_read_threshold, (uint32_t)(len) )
-
-#define NAND_UPDATE_WRITE_THRESHOLD(len) \
- nand_threshold_update( &android_nand_write_threshold, (uint32_t)(len) )
-
-#else /* !NAND_THRESHOLD */
-
-#define NAND_UPDATE_READ_THRESHOLD(len) \
- do {} while (0)
-
-#define NAND_UPDATE_WRITE_THRESHOLD(len) \
- do {} while (0)
-
-#endif /* !NAND_THRESHOLD */
-
-static nand_dev *nand_devs = NULL;
-static uint32_t nand_dev_count = 0;
-
-typedef struct {
- uint32_t base;
-
- // register state
- uint32_t dev;
- uint32_t addr_low;
- uint32_t addr_high;
- uint32_t transfer_size;
- uint32_t data;
- uint32_t result;
-} nand_dev_state;
-
-/* update this everytime you change the nand_dev_state structure */
-#define NAND_DEV_STATE_SAVE_VERSION 1
-
-#define QFIELD_STRUCT nand_dev_state
-QFIELD_BEGIN(nand_dev_state_fields)
- QFIELD_INT32(dev),
- QFIELD_INT32(addr_low),
- QFIELD_INT32(addr_high),
- QFIELD_INT32(transfer_size),
- QFIELD_INT32(data),
- QFIELD_INT32(result),
-QFIELD_END
-
-static void nand_dev_state_save(QEMUFile* f, void* opaque)
-{
- nand_dev_state* s = opaque;
-
- qemu_put_struct(f, nand_dev_state_fields, s);
-}
-
-static int nand_dev_state_load(QEMUFile* f, void* opaque, int version_id)
-{
- nand_dev_state* s = opaque;
-
- if (version_id != NAND_DEV_STATE_SAVE_VERSION)
- return -1;
-
- return qemu_get_struct(f, nand_dev_state_fields, s);
-}
-
-
-static int do_read(int fd, void* buf, size_t size)
-{
- int ret;
- do {
- ret = read(fd, buf, size);
- } while (ret < 0 && errno == EINTR);
-
- return ret;
-}
-
-static int do_write(int fd, const void* buf, size_t size)
-{
- int ret;
- do {
- ret = write(fd, buf, size);
- } while (ret < 0 && errno == EINTR);
-
- return ret;
-}
-
-static uint32_t nand_dev_read_file(nand_dev *dev, uint32_t data, uint64_t addr, uint32_t total_len)
-{
- uint32_t len = total_len;
- size_t read_len = dev->erase_size;
- int eof = 0;
-
- NAND_UPDATE_READ_THRESHOLD(total_len);
-
- lseek(dev->fd, addr, SEEK_SET);
- while(len > 0) {
- if(read_len < dev->erase_size) {
- memset(dev->data, 0xff, dev->erase_size);
- read_len = dev->erase_size;
- eof = 1;
- }
- if(len < read_len)
- read_len = len;
- if(!eof) {
- read_len = do_read(dev->fd, dev->data, read_len);
- }
- pmemcpy(data, dev->data, read_len);
- data += read_len;
- len -= read_len;
- }
- return total_len;
-}
-
-static uint32_t nand_dev_write_file(nand_dev *dev, uint32_t data, uint64_t addr, uint32_t total_len)
-{
- uint32_t len = total_len;
- size_t write_len = dev->erase_size;
- int ret;
-
- NAND_UPDATE_WRITE_THRESHOLD(total_len);
-
- lseek(dev->fd, addr, SEEK_SET);
- while(len > 0) {
- if(len < write_len)
- write_len = len;
- vmemcpy(data, dev->data, write_len);
- ret = do_write(dev->fd, dev->data, write_len);
- if(ret < write_len) {
- XLOG("nand_dev_write_file, write failed: %s\n", strerror(errno));
- break;
- }
- data += write_len;
- len -= write_len;
- }
- return total_len - len;
-}
-
-static uint32_t nand_dev_erase_file(nand_dev *dev, uint64_t addr, uint32_t total_len)
-{
- uint32_t len = total_len;
- size_t write_len = dev->erase_size;
- int ret;
-
- lseek(dev->fd, addr, SEEK_SET);
- memset(dev->data, 0xff, dev->erase_size);
- while(len > 0) {
- if(len < write_len)
- write_len = len;
- ret = do_write(dev->fd, dev->data, write_len);
- if(ret < write_len) {
- XLOG( "nand_dev_write_file, write failed: %s\n", strerror(errno));
- break;
- }
- len -= write_len;
- }
- return total_len - len;
-}
-
-/* this is a huge hack required to make the PowerPC emulator binary usable
- * on Mac OS X. If you define this function as 'static', the emulated kernel
- * will panic when attempting to mount the /data partition.
- *
- * worse, if you do *not* define the function as static on Linux-x86, the
- * emulated kernel will also panic !?
- *
- * I still wonder if this is a compiler bug, or due to some nasty thing the
- * emulator does with CPU registers during execution of the translated code.
- */
-#if !(defined __APPLE__ && defined __powerpc__)
-static
-#endif
-uint32_t nand_dev_do_cmd(nand_dev_state *s, uint32_t cmd)
-{
- uint32_t size;
- uint64_t addr;
- nand_dev *dev;
-
- addr = s->addr_low | ((uint64_t)s->addr_high << 32);
- size = s->transfer_size;
- if(s->dev >= nand_dev_count)
- return 0;
- dev = nand_devs + s->dev;
-
- switch(cmd) {
- case NAND_CMD_GET_DEV_NAME:
- if(size > dev->devname_len)
- size = dev->devname_len;
- pmemcpy(s->data, dev->devname, size);
- return size;
- case NAND_CMD_READ:
- if(addr >= dev->size)
- return 0;
- if(size + addr > dev->size)
- size = dev->size - addr;
- if(dev->fd >= 0)
- return nand_dev_read_file(dev, s->data, addr, size);
- pmemcpy(s->data, &dev->data[addr], size);
- return size;
- case NAND_CMD_WRITE:
- if(dev->flags & NAND_DEV_FLAG_READ_ONLY)
- return 0;
- if(addr >= dev->size)
- return 0;
- if(size + addr > dev->size)
- size = dev->size - addr;
- if(dev->fd >= 0)
- return nand_dev_write_file(dev, s->data, addr, size);
- vmemcpy(s->data, &dev->data[addr], size);
- return size;
- case NAND_CMD_ERASE:
- if(dev->flags & NAND_DEV_FLAG_READ_ONLY)
- return 0;
- if(addr >= dev->size)
- return 0;
- if(size + addr > dev->size)
- size = dev->size - addr;
- if(dev->fd >= 0)
- return nand_dev_erase_file(dev, addr, size);
- memset(&dev->data[addr], 0xff, size);
- return size;
- case NAND_CMD_BLOCK_BAD_GET: // no bad block support
- return 0;
- case NAND_CMD_BLOCK_BAD_SET:
- if(dev->flags & NAND_DEV_FLAG_READ_ONLY)
- return 0;
- return 0;
- default:
- cpu_abort(cpu_single_env, "nand_dev_do_cmd: Bad command %x\n", cmd);
- return 0;
- }
-}
-
-/* I/O write */
-static void nand_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- nand_dev_state *s = (nand_dev_state *)opaque;
-
- offset -= s->base;
- switch (offset) {
- case NAND_DEV:
- s->dev = value;
- if(s->dev >= nand_dev_count) {
- cpu_abort(cpu_single_env, "nand_dev_write: Bad dev %x\n", value);
- }
- break;
- case NAND_ADDR_HIGH:
- s->addr_high = value;
- break;
- case NAND_ADDR_LOW:
- s->addr_low = value;
- break;
- case NAND_TRANSFER_SIZE:
- s->transfer_size = value;
- break;
- case NAND_DATA:
- s->data = value;
- break;
- case NAND_COMMAND:
- s->result = nand_dev_do_cmd(s, value);
- break;
- default:
- cpu_abort(cpu_single_env, "nand_dev_write: Bad offset %x\n", offset);
- break;
- }
-}
-
-/* I/O read */
-static uint32_t nand_dev_read(void *opaque, target_phys_addr_t offset)
-{
- nand_dev_state *s = (nand_dev_state *)opaque;
- nand_dev *dev;
-
- offset -= s->base;
- switch (offset) {
- case NAND_VERSION:
- return NAND_VERSION_CURRENT;
- case NAND_NUM_DEV:
- return nand_dev_count;
- case NAND_RESULT:
- return s->result;
- }
-
- if(s->dev >= nand_dev_count)
- return 0;
-
- dev = nand_devs + s->dev;
-
- switch (offset) {
- case NAND_DEV_FLAGS:
- return dev->flags;
-
- case NAND_DEV_NAME_LEN:
- return dev->devname_len;
-
- case NAND_DEV_PAGE_SIZE:
- return dev->page_size;
-
- case NAND_DEV_EXTRA_SIZE:
- return dev->extra_size;
-
- case NAND_DEV_ERASE_SIZE:
- return dev->erase_size;
-
- case NAND_DEV_SIZE_LOW:
- return (uint32_t)dev->size;
-
- case NAND_DEV_SIZE_HIGH:
- return (uint32_t)(dev->size >> 32);
-
- default:
- cpu_abort(cpu_single_env, "nand_dev_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static CPUReadMemoryFunc *nand_dev_readfn[] = {
- nand_dev_read,
- nand_dev_read,
- nand_dev_read
-};
-
-static CPUWriteMemoryFunc *nand_dev_writefn[] = {
- nand_dev_write,
- nand_dev_write,
- nand_dev_write
-};
-
-/* initialize the QFB device */
-void nand_dev_init(uint32_t base)
-{
- int iomemtype;
- static int instance_id = 0;
- nand_dev_state *s;
-
- s = (nand_dev_state *)qemu_mallocz(sizeof(nand_dev_state));
- iomemtype = cpu_register_io_memory(0, nand_dev_readfn, nand_dev_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->base = base;
-
- register_savevm( "nand_dev", instance_id++, NAND_DEV_STATE_SAVE_VERSION,
- nand_dev_state_save, nand_dev_state_load, s);
-}
-
-static int arg_match(const char *a, const char *b, size_t b_len)
-{
- while(*a && b_len--) {
- if(*a++ != *b++)
- return 0;
- }
- return b_len == 0;
-}
-
-void nand_add_dev(const char *arg)
-{
- uint64_t dev_size = 0;
- const char *next_arg;
- const char *value;
- size_t arg_len, value_len;
- nand_dev *new_devs, *dev;
- char *devname = NULL;
- size_t devname_len = 0;
- char *initfilename = NULL;
- char *rwfilename = NULL;
- int initfd = -1;
- int rwfd = -1;
- int read_only = 0;
- int pad;
- ssize_t read_size;
- uint32_t page_size = 2048;
- uint32_t extra_size = 64;
- uint32_t erase_pages = 64;
-
- while(arg) {
- next_arg = strchr(arg, ',');
- value = strchr(arg, '=');
- if(next_arg != NULL) {
- arg_len = next_arg - arg;
- next_arg++;
- if(value >= next_arg)
- value = NULL;
- }
- else
- arg_len = strlen(arg);
- if(value != NULL) {
- size_t new_arg_len = value - arg;
- value_len = arg_len - new_arg_len - 1;
- arg_len = new_arg_len;
- value++;
- }
- else
- value_len = 0;
-
- if(devname == NULL) {
- if(value != NULL)
- goto bad_arg_and_value;
- devname_len = arg_len;
- devname = malloc(arg_len);
- if(devname == NULL)
- goto out_of_memory;
- memcpy(devname, arg, arg_len);
- }
- else if(value == NULL) {
- if(arg_match("readonly", arg, arg_len)) {
- read_only = 1;
- }
- else {
- XLOG("bad arg: %.*s\n", arg_len, arg);
- exit(1);
- }
- }
- else {
- if(arg_match("size", arg, arg_len)) {
- char *ep;
- dev_size = strtoull(value, &ep, 0);
- if(ep != value + value_len)
- goto bad_arg_and_value;
- }
- else if(arg_match("pagesize", arg, arg_len)) {
- char *ep;
- page_size = strtoul(value, &ep, 0);
- if(ep != value + value_len)
- goto bad_arg_and_value;
- }
- else if(arg_match("extrasize", arg, arg_len)) {
- char *ep;
- extra_size = strtoul(value, &ep, 0);
- if(ep != value + value_len)
- goto bad_arg_and_value;
- }
- else if(arg_match("erasepages", arg, arg_len)) {
- char *ep;
- erase_pages = strtoul(value, &ep, 0);
- if(ep != value + value_len)
- goto bad_arg_and_value;
- }
- else if(arg_match("initfile", arg, arg_len)) {
- initfilename = malloc(value_len + 1);
- if(initfilename == NULL)
- goto out_of_memory;
- memcpy(initfilename, value, value_len);
- initfilename[value_len] = '\0';
- }
- else if(arg_match("file", arg, arg_len)) {
- rwfilename = malloc(value_len + 1);
- if(rwfilename == NULL)
- goto out_of_memory;
- memcpy(rwfilename, value, value_len);
- rwfilename[value_len] = '\0';
- }
- else {
- goto bad_arg_and_value;
- }
- }
-
- arg = next_arg;
- }
-
- if (rwfilename == NULL) {
- /* we create a temporary file to store everything */
- TempFile* tmp = tempfile_create();
-
- if (tmp == NULL) {
- XLOG("could not create temp file for %.*s NAND disk image: %s",
- devname_len, devname, strerror(errno));
- exit(1);
- }
- rwfilename = (char*) tempfile_path(tmp);
- if (VERBOSE_CHECK(init))
- dprint( "mapping '%.*s' NAND image to %s", devname_len, devname, rwfilename);
- }
-
- if(rwfilename) {
- rwfd = open(rwfilename, O_BINARY | (read_only ? O_RDONLY : O_RDWR));
- if(rwfd < 0 && read_only) {
- XLOG("could not open file %s, %s\n", rwfilename, strerror(errno));
- exit(1);
- }
- /* this could be a writable temporary file. use atexit_close_fd to ensure
- * that it is properly cleaned up at exit on Win32
- */
- if (!read_only)
- atexit_close_fd(rwfd);
- }
-
- if(initfilename) {
- initfd = open(initfilename, O_BINARY | O_RDONLY);
- if(initfd < 0) {
- XLOG("could not open file %s, %s\n", initfilename, strerror(errno));
- exit(1);
- }
- if(dev_size == 0) {
- dev_size = lseek(initfd, 0, SEEK_END);
- lseek(initfd, 0, SEEK_SET);
- }
- }
-
- new_devs = realloc(nand_devs, sizeof(nand_devs[0]) * (nand_dev_count + 1));
- if(new_devs == NULL)
- goto out_of_memory;
- nand_devs = new_devs;
- dev = &new_devs[nand_dev_count];
-
- dev->page_size = page_size;
- dev->extra_size = extra_size;
- dev->erase_size = erase_pages * (page_size + extra_size);
- pad = dev_size % dev->erase_size;
- if (pad != 0) {
- dev_size += (dev->erase_size - pad);
- XLOG("rounding devsize up to a full eraseunit, now %llx\n", dev_size);
- }
- dev->devname = devname;
- dev->devname_len = devname_len;
- dev->size = dev_size;
- dev->data = malloc(dev->erase_size);
- if(dev->data == NULL)
- goto out_of_memory;
- dev->flags = read_only ? NAND_DEV_FLAG_READ_ONLY : 0;
-
- if (initfd >= 0) {
- do {
- read_size = do_read(initfd, dev->data, dev->erase_size);
- if(read_size < 0) {
- XLOG("could not read file %s, %s\n", initfilename, strerror(errno));
- exit(1);
- }
- if(do_write(rwfd, dev->data, read_size) != read_size) {
- XLOG("could not write file %s, %s\n", initfilename, strerror(errno));
- exit(1);
- }
- } while(read_size == dev->erase_size);
- close(initfd);
- }
- dev->fd = rwfd;
-
- nand_dev_count++;
-
- return;
-
-out_of_memory:
- XLOG("out of memory\n");
- exit(1);
-
-bad_arg_and_value:
- XLOG("bad arg: %.*s=%.*s\n", arg_len, arg, value_len, value);
- exit(1);
-}
-
diff --git a/hw/goldfish_nand.h b/hw/goldfish_nand.h
deleted file mode 100644
index dcc59d8..0000000
--- a/hw/goldfish_nand.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef NAND_DEVICE_H
-#define NAND_DEVICE_H
-
-void nand_dev_init(uint32_t base);
-void nand_add_dev(const char *arg);
-
-typedef struct {
- uint64_t limit;
- uint64_t counter;
- int pid;
- int signal;
-} nand_threshold;
-
-extern nand_threshold android_nand_read_threshold;
-extern nand_threshold android_nand_write_threshold;
-
-#endif
diff --git a/hw/goldfish_nand_reg.h b/hw/goldfish_nand_reg.h
deleted file mode 100644
index ea91461..0000000
--- a/hw/goldfish_nand_reg.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef NAND_DEVICE_REG_H
-#define NAND_DEVICE_REG_H
-
-enum nand_cmd {
- NAND_CMD_GET_DEV_NAME, // Write device name for NAND_DEV to NAND_DATA (vaddr)
- NAND_CMD_READ,
- NAND_CMD_WRITE,
- NAND_CMD_ERASE,
- NAND_CMD_BLOCK_BAD_GET, // NAND_RESULT is 1 if block is bad, 0 if it is not
- NAND_CMD_BLOCK_BAD_SET
-};
-
-enum nand_dev_flags {
- NAND_DEV_FLAG_READ_ONLY = 0x00000001
-};
-
-#define NAND_VERSION_CURRENT (1)
-
-enum nand_reg {
- // Global
- NAND_VERSION = 0x000,
- NAND_NUM_DEV = 0x004,
- NAND_DEV = 0x008,
-
- // Dev info
- NAND_DEV_FLAGS = 0x010,
- NAND_DEV_NAME_LEN = 0x014,
- NAND_DEV_PAGE_SIZE = 0x018,
- NAND_DEV_EXTRA_SIZE = 0x01c,
- NAND_DEV_ERASE_SIZE = 0x020,
- NAND_DEV_SIZE_LOW = 0x028,
- NAND_DEV_SIZE_HIGH = 0x02c,
-
- // Command
- NAND_RESULT = 0x040,
- NAND_COMMAND = 0x044,
- NAND_DATA = 0x048,
- NAND_TRANSFER_SIZE = 0x04c,
- NAND_ADDR_LOW = 0x050,
- NAND_ADDR_HIGH = 0x054,
-};
-
-#endif
diff --git a/hw/goldfish_switch.c b/hw/goldfish_switch.c
deleted file mode 100644
index 8a12d66..0000000
--- a/hw/goldfish_switch.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_device.h"
-
-enum {
- SW_NAME_LEN = 0x00,
- SW_NAME_PTR = 0x04,
- SW_FLAGS = 0x08,
- SW_STATE = 0x0c,
- SW_INT_STATUS = 0x10,
- SW_INT_ENABLE = 0x14,
-
- SW_FLAGS_OUTPUT = 1U << 0
-};
-
-
-struct switch_state {
- struct goldfish_device dev;
- char *name;
- uint32_t state;
- uint32_t state_changed : 1;
- uint32_t int_enable : 1;
- uint32_t (*writefn)(void *opaque, uint32_t state);
- void *writeopaque;
-};
-
-#define GOLDFISH_SWITCH_SAVE_VERSION 1
-
-static void goldfish_switch_save(QEMUFile* f, void* opaque)
-{
- struct switch_state* s = opaque;
-
- qemu_put_be32(f, s->state);
- qemu_put_byte(f, s->state_changed);
- qemu_put_byte(f, s->int_enable);
-}
-
-static int goldfish_switch_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct switch_state* s = opaque;
-
- if (version_id != GOLDFISH_SWITCH_SAVE_VERSION)
- return -1;
-
- s->state = qemu_get_be32(f);
- s->state_changed = qemu_get_byte(f);
- s->int_enable = qemu_get_byte(f);
-
- return 0;
-}
-
-static uint32_t goldfish_switch_read(void *opaque, target_phys_addr_t offset)
-{
- struct switch_state *s = (struct switch_state *)opaque;
- offset -= s->dev.base;
-
- //printf("goldfish_switch_read %x %x\n", offset, size);
-
- switch (offset) {
- case SW_NAME_LEN:
- return strlen(s->name);
- case SW_FLAGS:
- return s->writefn ? SW_FLAGS_OUTPUT : 0;
- case SW_STATE:
- return s->state;
- case SW_INT_STATUS:
- if(s->state_changed && s->int_enable) {
- s->state_changed = 0;
- goldfish_device_set_irq(&s->dev, 0, 0);
- return 1;
- }
- return 0;
- default:
- cpu_abort (cpu_single_env, "goldfish_switch_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_switch_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct switch_state *s = (struct switch_state *)opaque;
- offset -= s->dev.base;
-
- //printf("goldfish_switch_read %x %x %x\n", offset, value, size);
-
- switch(offset) {
- case SW_NAME_PTR:
- pmemcpy(value, s->name, strlen(s->name));
- break;
-
- case SW_STATE:
- if(s->writefn) {
- uint32_t new_state;
- new_state = s->writefn(s->writeopaque, value);
- if(new_state != s->state) {
- goldfish_switch_set_state(s, new_state);
- }
- }
- else
- cpu_abort (cpu_single_env, "goldfish_switch_write: write to SW_STATE on input\n");
- break;
-
- case SW_INT_ENABLE:
- value &= 1;
- if(s->state_changed && s->int_enable != value)
- goldfish_device_set_irq(&s->dev, 0, value);
- s->int_enable = value;
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_switch_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_switch_readfn[] = {
- goldfish_switch_read,
- goldfish_switch_read,
- goldfish_switch_read
-};
-
-static CPUWriteMemoryFunc *goldfish_switch_writefn[] = {
- goldfish_switch_write,
- goldfish_switch_write,
- goldfish_switch_write
-};
-
-void goldfish_switch_set_state(void *opaque, uint32_t state)
-{
- struct switch_state *s = opaque;
- s->state_changed = 1;
- s->state = state;
- if(s->int_enable)
- goldfish_device_set_irq(&s->dev, 0, 1);
-}
-
-void *goldfish_switch_add(char *name, uint32_t (*writefn)(void *opaque, uint32_t state), void *writeopaque, int id)
-{
- int ret;
- struct switch_state *s;
-
- s = qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish-switch";
- s->dev.id = id;
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
- s->name = name;
- s->writefn = writefn;
- s->writeopaque = writeopaque;
-
-
- ret = goldfish_device_add(&s->dev, goldfish_switch_readfn, goldfish_switch_writefn, s);
- if(ret) {
- qemu_free(s);
- return NULL;
- }
-
- register_savevm( "goldfish_switch", 0, GOLDFISH_SWITCH_SAVE_VERSION,
- goldfish_switch_save, goldfish_switch_load, s);
-
- return s;
-}
-
diff --git a/hw/goldfish_timer.c b/hw/goldfish_timer.c
deleted file mode 100644
index 73f1455..0000000
--- a/hw/goldfish_timer.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu-timer.h"
-#include "cpu.h"
-#include "arm_pic.h"
-#include "goldfish_device.h"
-
-enum {
- TIMER_TIME_LOW = 0x00, // get low bits of current time and update TIMER_TIME_HIGH
- TIMER_TIME_HIGH = 0x04, // get high bits of time at last TIMER_TIME_LOW read
- TIMER_ALARM_LOW = 0x08, // set low bits of alarm and activate it
- TIMER_ALARM_HIGH = 0x0c, // set high bits of next alarm
- TIMER_CLEAR_INTERRUPT = 0x10,
- TIMER_CLEAR_ALARM = 0x14
-};
-
-struct timer_state {
- struct goldfish_device dev;
- uint32_t alarm_low;
- int32_t alarm_high;
- int64_t now;
- int armed;
- QEMUTimer *timer;
-};
-
-#define GOLDFISH_TIMER_SAVE_VERSION 1
-
-static void goldfish_timer_save(QEMUFile* f, void* opaque)
-{
- struct timer_state* s = opaque;
-
- qemu_put_be64(f, s->now); /* in case the kernel is in the middle of a timer read */
- qemu_put_byte(f, s->armed);
- if (s->armed) {
- int64_t now = qemu_get_clock(vm_clock);
- int64_t alarm = muldiv64(s->alarm_low | (int64_t)s->alarm_high << 32, ticks_per_sec, 1000000000);
- qemu_put_be64(f, alarm-now);
- }
-}
-
-static int goldfish_timer_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct timer_state* s = opaque;
-
- if (version_id != GOLDFISH_TIMER_SAVE_VERSION)
- return -1;
-
- s->now = qemu_get_be64(f);
- s->armed = qemu_get_byte(f);
- if (s->armed) {
- int64_t now = qemu_get_clock(vm_clock);
- int64_t diff = qemu_get_be64(f);
- int64_t alarm = now + diff;
-
- if (alarm <= now) {
- goldfish_device_set_irq(&s->dev, 0, 1);
- s->armed = 0;
- } else {
- qemu_mod_timer(s->timer, alarm);
- }
- }
- return 0;
-}
-
-static uint32_t goldfish_timer_read(void *opaque, target_phys_addr_t offset)
-{
- struct timer_state *s = (struct timer_state *)opaque;
- offset -= s->dev.base;
- switch(offset) {
- case TIMER_TIME_LOW:
- s->now = muldiv64(qemu_get_clock(vm_clock), 1000000000, ticks_per_sec);
- return s->now;
- case TIMER_TIME_HIGH:
- return s->now >> 32;
- default:
- cpu_abort (cpu_single_env, "goldfish_timer_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_timer_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct timer_state *s = (struct timer_state *)opaque;
- int64_t alarm, now;
- offset -= s->dev.base;
- switch(offset) {
- case TIMER_ALARM_LOW:
- s->alarm_low = value;
- alarm = muldiv64(s->alarm_low | (int64_t)s->alarm_high << 32, ticks_per_sec, 1000000000);
- now = qemu_get_clock(vm_clock);
- if (alarm <= now) {
- goldfish_device_set_irq(&s->dev, 0, 1);
- } else {
- qemu_mod_timer(s->timer, alarm);
- s->armed = 1;
- }
- break;
- case TIMER_ALARM_HIGH:
- s->alarm_high = value;
- //printf("alarm_high %d\n", s->alarm_high);
- break;
- case TIMER_CLEAR_ALARM:
- qemu_del_timer(s->timer);
- s->armed = 0;
- /* fall through */
- case TIMER_CLEAR_INTERRUPT:
- goldfish_device_set_irq(&s->dev, 0, 0);
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_timer_write: Bad offset %x\n", offset);
- }
-}
-
-static void goldfish_timer_tick(void *opaque)
-{
- struct timer_state *s = (struct timer_state *)opaque;
-
- s->armed = 0;
- goldfish_device_set_irq(&s->dev, 0, 1);
-}
-
-struct rtc_state {
- struct goldfish_device dev;
- uint32_t alarm_low;
- int32_t alarm_high;
- int64_t now;
-};
-
-/* we save the RTC for the case where the kernel is in the middle of a rtc_read
- * (i.e. it has read the low 32-bit of s->now, but not the high 32-bits yet */
-#define GOLDFISH_RTC_SAVE_VERSION 1
-
-static void goldfish_rtc_save(QEMUFile* f, void* opaque)
-{
- struct rtc_state* s = opaque;
-
- qemu_put_be64(f, s->now);
-}
-
-static int goldfish_rtc_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct rtc_state* s = opaque;
-
- if (version_id != GOLDFISH_RTC_SAVE_VERSION)
- return -1;
-
- /* this is an old value that is not correct. but that's ok anyway */
- s->now = qemu_get_be64(f);
- return 0;
-}
-
-static uint32_t goldfish_rtc_read(void *opaque, target_phys_addr_t offset)
-{
- struct rtc_state *s = (struct rtc_state *)opaque;
- offset -= s->dev.base;
- switch(offset) {
- case 0x0:
- s->now = (int64_t)time(NULL) * 1000000000;
- return s->now;
- case 0x4:
- return s->now >> 32;
- default:
- cpu_abort (cpu_single_env, "goldfish_rtc_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_rtc_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct rtc_state *s = (struct rtc_state *)opaque;
- int64_t alarm;
- offset -= s->dev.base;
- switch(offset) {
- case 0x8:
- s->alarm_low = value;
- alarm = s->alarm_low | (int64_t)s->alarm_high << 32;
- //printf("next alarm at %lld, tps %lld\n", alarm, ticks_per_sec);
- //qemu_mod_timer(s->timer, alarm);
- break;
- case 0xc:
- s->alarm_high = value;
- //printf("alarm_high %d\n", s->alarm_high);
- break;
- case 0x10:
- goldfish_device_set_irq(&s->dev, 0, 0);
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_rtc_write: Bad offset %x\n", offset);
- }
-}
-
-static struct timer_state timer_state = {
- .dev = {
- .name = "goldfish_timer",
- .id = -1,
- .size = 0x1000,
- .irq_count = 1,
- }
-};
-
-static struct timer_state rtc_state = {
- .dev = {
- .name = "goldfish_rtc",
- .id = -1,
- .size = 0x1000,
- .irq_count = 1,
- }
-};
-
-static CPUReadMemoryFunc *goldfish_timer_readfn[] = {
- goldfish_timer_read,
- goldfish_timer_read,
- goldfish_timer_read
-};
-
-static CPUWriteMemoryFunc *goldfish_timer_writefn[] = {
- goldfish_timer_write,
- goldfish_timer_write,
- goldfish_timer_write
-};
-
-static CPUReadMemoryFunc *goldfish_rtc_readfn[] = {
- goldfish_rtc_read,
- goldfish_rtc_read,
- goldfish_rtc_read
-};
-
-static CPUWriteMemoryFunc *goldfish_rtc_writefn[] = {
- goldfish_rtc_write,
- goldfish_rtc_write,
- goldfish_rtc_write
-};
-
-void goldfish_timer_and_rtc_init(uint32_t timerbase, int timerirq)
-{
- timer_state.dev.base = timerbase;
- timer_state.dev.irq = timerirq;
- timer_state.timer = qemu_new_timer(vm_clock, goldfish_timer_tick, &timer_state);
- goldfish_device_add(&timer_state.dev, goldfish_timer_readfn, goldfish_timer_writefn, &timer_state);
- register_savevm( "goldfish_timer", 0, GOLDFISH_TIMER_SAVE_VERSION,
- goldfish_timer_save, goldfish_timer_load, &timer_state);
-
- goldfish_device_add(&rtc_state.dev, goldfish_rtc_readfn, goldfish_rtc_writefn, &rtc_state);
- register_savevm( "goldfish_rtc", 0, GOLDFISH_RTC_SAVE_VERSION,
- goldfish_rtc_save, goldfish_rtc_load, &rtc_state);
-}
-
diff --git a/hw/goldfish_trace.c b/hw/goldfish_trace.c
deleted file mode 100644
index ad0eba5..0000000
--- a/hw/goldfish_trace.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-/*
- * Virtual hardware for bridging the FUSE kernel module
- * in the emulated OS and outside file system
- */
-#include "qemu_file.h"
-#include "goldfish_trace.h"
-
-//#define DEBUG 1
-
-extern void cpu_loop_exit(void);
-
-extern int tracing;
-
-/* for execve */
-static char path[CLIENT_PAGE_SIZE];
-static char arg[CLIENT_PAGE_SIZE];
-static unsigned long vstart; // VM start
-static unsigned long vend; // VM end
-static unsigned long eoff; // offset in EXE file
-static unsigned cmdlen; // cmdline length
-static unsigned pid; // PID (really thread id)
-static unsigned tgid; // thread group id (really process id)
-static unsigned long dsaddr; // dynamic symbol address
-static unsigned long unmap_start; // start address to unmap
-
-/* for context switch */
-//static unsigned long cs_pid; // context switch PID
-
-/* I/O write */
-static void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- trace_dev_state *s = (trace_dev_state *)opaque;
-
- offset -= s->base;
- switch (offset >> 2) {
- case TRACE_DEV_REG_SWITCH: // context switch, switch to pid
- trace_switch(value);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, context switch %u\n", value);
-#endif
- break;
- case TRACE_DEV_REG_TGID: // save the tgid for the following fork/clone
- tgid = value;
-#ifdef DEBUG
- printf("QEMU.trace: kernel, tgid %u\n", value);
-#endif
- break;
- case TRACE_DEV_REG_FORK: // fork, fork new pid
- trace_fork(tgid, value);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, fork %u\n", value);
-#endif
- break;
- case TRACE_DEV_REG_CLONE: // fork, clone new pid (i.e. thread)
- trace_clone(tgid, value);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, clone %u\n", value);
-#endif
- break;
- case TRACE_DEV_REG_EXECVE_VMSTART: // execve, vstart
- vstart = value;
- break;
- case TRACE_DEV_REG_EXECVE_VMEND: // execve, vend
- vend = value;
- break;
- case TRACE_DEV_REG_EXECVE_OFFSET: // execve, offset in EXE
- eoff = value;
- break;
- case TRACE_DEV_REG_EXECVE_EXEPATH: // init exec, path of EXE
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
- trace_init_exec(vstart, vend, eoff, path);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, path);
-#endif
- path[0] = 0;
- break;
- case TRACE_DEV_REG_CMDLINE_LEN: // execve, process cmdline length
- cmdlen = value;
- break;
- case TRACE_DEV_REG_CMDLINE: // execve, process cmdline
- vmemcpy(value, arg, cmdlen);
- trace_execve(arg, cmdlen);
-#ifdef DEBUG
- {
- int i;
- for (i = 0; i < cmdlen; i ++)
- if (i != cmdlen - 1 && arg[i] == 0)
- arg[i] = ' ';
- printf("QEMU.trace: kernel, execve %s[%d]\n", arg, cmdlen);
- }
-#endif
- arg[0] = 0;
- break;
- case TRACE_DEV_REG_EXIT: // exit, exit current process with exit code
- trace_exit(value);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, exit %x\n", value);
-#endif
- break;
- case TRACE_DEV_REG_NAME: // record thread name
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
-
- // Remove the trailing newline if it exists
- int len = strlen(path);
- if (path[len - 1] == '\n') {
- path[len - 1] = 0;
- }
- trace_name(path);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, name %s\n", path);
-#endif
- break;
- case TRACE_DEV_REG_MMAP_EXEPATH: // mmap, path of EXE, the others are same as execve
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
- trace_mmap(vstart, vend, eoff, path);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, path);
-#endif
- path[0] = 0;
- break;
- case TRACE_DEV_REG_INIT_PID: // init, name the pid that starts before device registered
- pid = value;
- break;
- case TRACE_DEV_REG_INIT_NAME: // init, the comm of the init pid
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
- trace_init_name(tgid, pid, path);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, init name %u [%s]\n", pid, path);
-#endif
- path[0] = 0;
- break;
-
- case TRACE_DEV_REG_DYN_SYM_ADDR: // dynamic symbol address
- dsaddr = value;
- break;
- case TRACE_DEV_REG_DYN_SYM: // add dynamic symbol
- vstrcpy(value, arg, CLIENT_PAGE_SIZE);
- trace_dynamic_symbol_add(dsaddr, arg);
-#ifdef DEBUG
- printf("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, arg);
-#endif
- arg[0] = 0;
- break;
- case TRACE_DEV_REG_REMOVE_ADDR: // remove dynamic symbol addr
- trace_dynamic_symbol_remove(value);
-#ifdef DEBUG
- printf("QEMU.trace: dynamic symbol remove %lx\n", dsaddr);
-#endif
- arg[0] = 0;
- break;
-
- case TRACE_DEV_REG_PRINT_STR: // print string
- vstrcpy(value, arg, CLIENT_PAGE_SIZE);
- printf("%s", arg);
- arg[0] = 0;
- break;
- case TRACE_DEV_REG_PRINT_NUM_DEC: // print number in decimal
- printf("%d", value);
- break;
- case TRACE_DEV_REG_PRINT_NUM_HEX: // print number in hexical
- printf("%x", value);
- break;
-
- case TRACE_DEV_REG_STOP_EMU: // stop the VM execution
- // To ensure that the number of instructions executed in this
- // block is correct, we pretend that there was an exception.
- trace_exception(0);
-
- cpu_single_env->exception_index = EXCP_HLT;
- cpu_single_env->halted = 1;
- qemu_system_shutdown_request();
- cpu_loop_exit();
- break;
-
- case TRACE_DEV_REG_ENABLE: // tracing enable: 0 = stop, 1 = start
- if (value == 1)
- start_tracing();
- else if (value == 0) {
- stop_tracing();
-
- // To ensure that the number of instructions executed in this
- // block is correct, we pretend that there was an exception.
- trace_exception(0);
- }
- break;
-
- case TRACE_DEV_REG_UNMAP_START:
- unmap_start = value;
- break;
- case TRACE_DEV_REG_UNMAP_END:
- trace_munmap(unmap_start, value);
- break;
-
- default:
- cpu_abort(cpu_single_env, "trace_dev_write: Bad offset %x\n", offset);
- break;
- }
-}
-
-/* I/O read */
-static uint32_t trace_dev_read(void *opaque, target_phys_addr_t offset)
-{
- trace_dev_state *s = (trace_dev_state *)opaque;
-
- offset -= s->base;
- switch (offset >> 2) {
- case TRACE_DEV_REG_ENABLE: // tracing enable
- return tracing;
- default:
- cpu_abort(cpu_single_env, "trace_dev_read: Bad offset %x\n", offset);
- return 0;
- }
- return 0;
-}
-
-static CPUReadMemoryFunc *trace_dev_readfn[] = {
- trace_dev_read,
- trace_dev_read,
- trace_dev_read
-};
-
-static CPUWriteMemoryFunc *trace_dev_writefn[] = {
- trace_dev_write,
- trace_dev_write,
- trace_dev_write
-};
-
-/* initialize the trace device */
-void trace_dev_init(uint32_t base)
-{
- int iomemtype;
- trace_dev_state *s;
-
- s = (trace_dev_state *)qemu_mallocz(sizeof(trace_dev_state));
- iomemtype = cpu_register_io_memory(0, trace_dev_readfn, trace_dev_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->base = base;
-
- path[0] = arg[0] = '\0';
-}
diff --git a/hw/goldfish_trace.h b/hw/goldfish_trace.h
deleted file mode 100644
index 44190ee..0000000
--- a/hw/goldfish_trace.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _TRACE_DEV_H_
-#define _TRACE_DEV_H_
-
-#define CLIENT_PAGE_SIZE 4096
-
-/* trace device registers */
-#define TRACE_DEV_REG_SWITCH 0
-#define TRACE_DEV_REG_FORK 1
-#define TRACE_DEV_REG_EXECVE_PID 2
-#define TRACE_DEV_REG_EXECVE_VMSTART 3
-#define TRACE_DEV_REG_EXECVE_VMEND 4
-#define TRACE_DEV_REG_EXECVE_OFFSET 5
-#define TRACE_DEV_REG_EXECVE_EXEPATH 6
-#define TRACE_DEV_REG_EXIT 7
-#define TRACE_DEV_REG_CMDLINE 8
-#define TRACE_DEV_REG_CMDLINE_LEN 9
-#define TRACE_DEV_REG_MMAP_EXEPATH 10
-#define TRACE_DEV_REG_INIT_PID 11
-#define TRACE_DEV_REG_INIT_NAME 12
-#define TRACE_DEV_REG_CLONE 13
-#define TRACE_DEV_REG_UNMAP_START 14
-#define TRACE_DEV_REG_UNMAP_END 15
-#define TRACE_DEV_REG_NAME 16
-#define TRACE_DEV_REG_TGID 17
-#define TRACE_DEV_REG_DYN_SYM 50
-#define TRACE_DEV_REG_DYN_SYM_ADDR 51
-#define TRACE_DEV_REG_REMOVE_ADDR 52
-#define TRACE_DEV_REG_PRINT_STR 60
-#define TRACE_DEV_REG_PRINT_NUM_DEC 61
-#define TRACE_DEV_REG_PRINT_NUM_HEX 62
-#define TRACE_DEV_REG_STOP_EMU 90
-#define TRACE_DEV_REG_ENABLE 100
-
-/* the virtual trace device state */
-typedef struct {
- uint32_t base;
-} trace_dev_state;
-
-/*
- * interfaces for copy from virtual space
- * from target-arm/op_helper.c
- */
-extern target_phys_addr_t v2p(target_ulong ptr, int is_user);
-extern void vmemcpy(target_ulong ptr, char *buf, int size);
-extern void pmemcpy(target_ulong ptr, const char* buf, int size);
-extern void vstrcpy(target_ulong ptr, char *buf, int max);
-
-/*
- * interfaces to trace module to signal kernel events
- */
-extern void trace_switch(int pid);
-extern void trace_fork(int tgid, int pid);
-extern void trace_clone(int tgid, int pid);
-extern void trace_execve(const char *arg, int len);
-extern void trace_exit(int exitcode);
-extern void trace_mmap(unsigned long vstart, unsigned long vend,
- unsigned long offset, const char *path);
-extern void trace_munmap(unsigned long vstart, unsigned long vend);
-extern void trace_dynamic_symbol_add(unsigned long vaddr, const char *name);
-extern void trace_dynamic_symbol_remove(unsigned long vaddr);
-extern void trace_init_name(int tgid, int pid, const char *name);
-extern void trace_init_exec(unsigned long start, unsigned long end,
- unsigned long offset, const char *exe);
-extern void start_tracing(void);
-extern void stop_tracing(void);
-extern void trace_exception(uint32 target_pc);
-
-#endif
diff --git a/hw/goldfish_tty.c b/hw/goldfish_tty.c
deleted file mode 100644
index aa62d75..0000000
--- a/hw/goldfish_tty.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "qemu-char.h"
-#include "goldfish_device.h"
-
-enum {
- TTY_PUT_CHAR = 0x00,
- TTY_BYTES_READY = 0x04,
- TTY_CMD = 0x08,
-
- TTY_DATA_PTR = 0x10,
- TTY_DATA_LEN = 0x14,
-
- TTY_CMD_INT_DISABLE = 0,
- TTY_CMD_INT_ENABLE = 1,
- TTY_CMD_WRITE_BUFFER = 2,
- TTY_CMD_READ_BUFFER = 3,
-};
-
-struct tty_state {
- struct goldfish_device dev;
- CharDriverState *cs;
- uint32_t ptr;
- uint32_t ptr_len;
- uint32_t ready;
- uint8_t data[128];
- uint32_t data_count;
-};
-
-#define GOLDFISH_TTY_SAVE_VERSION 1
-
-static void goldfish_tty_save(QEMUFile* f, void* opaque)
-{
- struct tty_state* s = opaque;
-
- qemu_put_be32( f, s->ptr );
- qemu_put_be32( f, s->ptr_len );
- qemu_put_byte( f, s->ready );
- qemu_put_byte( f, s->data_count );
- qemu_put_buffer( f, s->data, s->data_count );
-}
-
-static int goldfish_tty_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct tty_state* s = opaque;
-
- if (version_id != GOLDFISH_TTY_SAVE_VERSION)
- return -1;
-
- s->ptr = qemu_get_be32(f);
- s->ptr_len = qemu_get_be32(f);
- s->ready = qemu_get_byte(f);
- s->data_count = qemu_get_byte(f);
- qemu_get_buffer(f, s->data, s->data_count);
-
- return 0;
-}
-
-static uint32_t goldfish_tty_read(void *opaque, target_phys_addr_t offset)
-{
- struct tty_state *s = (struct tty_state *)opaque;
- offset -= s->dev.base;
-
- //printf("goldfish_tty_read %x %x\n", offset, size);
-
- switch (offset) {
- case TTY_BYTES_READY:
- return s->data_count;
- default:
- cpu_abort (cpu_single_env, "goldfish_tty_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_tty_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct tty_state *s = (struct tty_state *)opaque;
- offset -= s->dev.base;
-
- //printf("goldfish_tty_read %x %x %x\n", offset, value, size);
-
- switch(offset) {
- case TTY_PUT_CHAR: {
- uint8_t ch = value;
- if(s->cs)
- qemu_chr_write(s->cs, &ch, 1);
- } break;
-
- case TTY_CMD:
- switch(value) {
- case TTY_CMD_INT_DISABLE:
- if(s->ready) {
- if(s->data_count > 0)
- goldfish_device_set_irq(&s->dev, 0, 0);
- s->ready = 0;
- }
- break;
-
- case TTY_CMD_INT_ENABLE:
- if(!s->ready) {
- if(s->data_count > 0)
- goldfish_device_set_irq(&s->dev, 0, 1);
- s->ready = 1;
- }
- break;
-
- case TTY_CMD_WRITE_BUFFER:
- if(s->cs) {
- int len;
- target_ulong buf;
-
- buf = s->ptr;
- len = s->ptr_len;
-
- while(len) {
- int page_remain = TARGET_PAGE_SIZE - (buf & ~TARGET_PAGE_MASK);
- int to_write = len;
- uint8_t *phys = (uint8_t *)v2p(buf, 0);
- if(to_write > page_remain)
- to_write = page_remain;
- qemu_chr_write(s->cs, phys, to_write);
- buf += to_write;
- len -= to_write;
- }
- //printf("goldfish_tty_write: got %d bytes from %x\n", s->ptr_len, s->ptr);
- }
- break;
-
- case TTY_CMD_READ_BUFFER:
- if(s->ptr_len > s->data_count)
- cpu_abort (cpu_single_env, "goldfish_tty_write: reading more data than available %d %d\n", s->ptr_len, s->data_count);
- pmemcpy(s->ptr, s->data, s->ptr_len);
- //printf("goldfish_tty_write: read %d bytes to %x\n", s->ptr_len, s->ptr);
- if(s->data_count > s->ptr_len)
- memmove(s->data, s->data + s->ptr_len, s->data_count - s->ptr_len);
- s->data_count -= s->ptr_len;
- if(s->data_count == 0 && s->ready)
- goldfish_device_set_irq(&s->dev, 0, 0);
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_tty_write: Bad command %x\n", value);
- };
- break;
-
- case TTY_DATA_PTR:
- s->ptr = value;
- break;
-
- case TTY_DATA_LEN:
- s->ptr_len = value;
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_tty_write: Bad offset %x\n", offset);
- }
-}
-
-static int tty_can_receive(void *opaque)
-{
- struct tty_state *s = opaque;
-
- return (sizeof(s->data) - s->data_count);
-}
-
-static void tty_receive(void *opaque, const uint8_t *buf, int size)
-{
- struct tty_state *s = opaque;
-
- memcpy(s->data + s->data_count, buf, size);
- s->data_count += size;
- if(s->data_count > 0 && s->ready)
- goldfish_device_set_irq(&s->dev, 0, 1);
-}
-
-static CPUReadMemoryFunc *goldfish_tty_readfn[] = {
- goldfish_tty_read,
- goldfish_tty_read,
- goldfish_tty_read
-};
-
-static CPUWriteMemoryFunc *goldfish_tty_writefn[] = {
- goldfish_tty_write,
- goldfish_tty_write,
- goldfish_tty_write
-};
-
-int goldfish_tty_add(CharDriverState *cs, int id, uint32_t base, int irq)
-{
- int ret;
- struct tty_state *s;
- static int instance_id = 0;
-
- s = qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish_tty";
- s->dev.id = id;
- s->dev.base = base;
- s->dev.size = 0x1000;
- s->dev.irq = irq;
- s->dev.irq_count = 1;
- s->cs = cs;
-
- if(cs) {
- qemu_chr_add_handlers(cs, tty_can_receive, tty_receive, NULL, s);
- }
-
- ret = goldfish_device_add(&s->dev, goldfish_tty_readfn, goldfish_tty_writefn, s);
- if(ret) {
- qemu_free(s);
- } else {
- register_savevm( "goldfish_tty", instance_id++, GOLDFISH_TTY_SAVE_VERSION,
- goldfish_tty_save, goldfish_tty_load, s);
- }
- return ret;
-}
-
diff --git a/hw/hw.h b/hw/hw.h
deleted file mode 100644
index 06e24cb..0000000
--- a/hw/hw.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Declarations for use by hardware emulation. */
-#ifndef QEMU_HW_H
-#define QEMU_HW_H
-
-#include "qemu-common.h"
-#include "irq.h"
-#include "cpu.h"
-
-/* VM Load/Save */
-
-QEMUFile *qemu_fopen(const char *filename, const char *mode);
-void qemu_fflush(QEMUFile *f);
-void qemu_fclose(QEMUFile *f);
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
-void qemu_put_byte(QEMUFile *f, int v);
-void qemu_put_be16(QEMUFile *f, unsigned int v);
-void qemu_put_be32(QEMUFile *f, unsigned int v);
-void qemu_put_be64(QEMUFile *f, uint64_t v);
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
-int qemu_get_byte(QEMUFile *f);
-unsigned int qemu_get_be16(QEMUFile *f);
-unsigned int qemu_get_be32(QEMUFile *f);
-uint64_t qemu_get_be64(QEMUFile *f);
-
-static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
-{
- qemu_put_be64(f, *pv);
-}
-
-static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
-{
- qemu_put_be32(f, *pv);
-}
-
-static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
-{
- qemu_put_be16(f, *pv);
-}
-
-static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
-{
- qemu_put_byte(f, *pv);
-}
-
-static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
-{
- *pv = qemu_get_be64(f);
-}
-
-static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
-{
- *pv = qemu_get_be32(f);
-}
-
-static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
-{
- *pv = qemu_get_be16(f);
-}
-
-static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
-{
- *pv = qemu_get_byte(f);
-}
-
-#ifdef NEED_CPU_H
-#if TARGET_LONG_BITS == 64
-#define qemu_put_betl qemu_put_be64
-#define qemu_get_betl qemu_get_be64
-#define qemu_put_betls qemu_put_be64s
-#define qemu_get_betls qemu_get_be64s
-#else
-#define qemu_put_betl qemu_put_be32
-#define qemu_get_betl qemu_get_be32
-#define qemu_put_betls qemu_put_be32s
-#define qemu_get_betls qemu_get_be32s
-#endif
-#endif
-
-int64_t qemu_ftell(QEMUFile *f);
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence);
-
-typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
-
-int register_savevm(const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque);
-
-typedef void QEMUResetHandler(void *opaque);
-
-void qemu_register_reset(QEMUResetHandler *func, void *opaque);
-
-/* handler to set the boot_device for a specific type of QEMUMachine */
-/* return 0 if success */
-typedef int QEMUBootSetHandler(const char *boot_device);
-extern QEMUBootSetHandler *qemu_boot_set_handler;
-void qemu_register_boot_set(QEMUBootSetHandler *func);
-
-/* These should really be in isa.h, but are here to make pc.h happy. */
-typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
-typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
-
-
-/* ANDROID: copy memory from the QEMU buffer to simulated virtual space */
-extern void pmemcpy(target_ulong ptr, const char *buf, int size);
-
-#endif
diff --git a/hw/irq.c b/hw/irq.c
deleted file mode 100644
index eca707d..0000000
--- a/hw/irq.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * QEMU IRQ/GPIO common code.
- *
- * Copyright (c) 2007 CodeSourcery.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "irq.h"
-
-struct IRQState {
- qemu_irq_handler handler;
- void *opaque;
- int n;
-};
-
-void qemu_set_irq(qemu_irq irq, int level)
-{
- if (!irq)
- return;
-
- irq->handler(irq->opaque, irq->n, level);
-}
-
-qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
-{
- qemu_irq *s;
- struct IRQState *p;
- int i;
-
- s = (qemu_irq *)qemu_mallocz(sizeof(qemu_irq) * n);
- p = (struct IRQState *)qemu_mallocz(sizeof(struct IRQState) * n);
- for (i = 0; i < n; i++) {
- p->handler = handler;
- p->opaque = opaque;
- p->n = i;
- s[i] = p;
- p++;
- }
- return s;
-}
-
-static void qemu_notirq(void *opaque, int line, int level)
-{
- struct IRQState *irq = opaque;
-
- irq->handler(irq->opaque, irq->n, !level);
-}
-
-qemu_irq qemu_irq_invert(qemu_irq irq)
-{
- /* The default state for IRQs is low, so raise the output now. */
- qemu_irq_raise(irq);
- return qemu_allocate_irqs(qemu_notirq, irq, 1)[0];
-}
diff --git a/hw/irq.h b/hw/irq.h
deleted file mode 100644
index 0880ad2..0000000
--- a/hw/irq.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef QEMU_IRQ_H
-#define QEMU_IRQ_H
-
-/* Generic IRQ/GPIO pin infrastructure. */
-
-/* FIXME: Rmove one of these. */
-typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
-typedef void SetIRQFunc(void *opaque, int irq_num, int level);
-
-void qemu_set_irq(qemu_irq irq, int level);
-
-static inline void qemu_irq_raise(qemu_irq irq)
-{
- qemu_set_irq(irq, 1);
-}
-
-static inline void qemu_irq_lower(qemu_irq irq)
-{
- qemu_set_irq(irq, 0);
-}
-
-static inline void qemu_irq_pulse(qemu_irq irq)
-{
- qemu_set_irq(irq, 1);
- qemu_set_irq(irq, 0);
-}
-
-/* Returns an array of N IRQs. */
-qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
-
-/* Returns a new IRQ with opposite polarity. */
-qemu_irq qemu_irq_invert(qemu_irq irq);
-
-#endif
diff --git a/hw/isa.h b/hw/isa.h
deleted file mode 100644
index 222e4f3..0000000
--- a/hw/isa.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef HW_ISA_H
-#define HW_ISA_H
-/* ISA bus */
-
-extern target_phys_addr_t isa_mem_base;
-
-int register_ioport_read(int start, int length, int size,
- IOPortReadFunc *func, void *opaque);
-int register_ioport_write(int start, int length, int size,
- IOPortWriteFunc *func, void *opaque);
-void isa_unassign_ioport(int start, int length);
-
-void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
-
-/* dma.c */
-int DMA_get_channel_mode (int nchan);
-int DMA_read_memory (int nchan, void *buf, int pos, int size);
-int DMA_write_memory (int nchan, void *buf, int pos, int size);
-void DMA_hold_DREQ (int nchan);
-void DMA_release_DREQ (int nchan);
-void DMA_schedule(int nchan);
-void DMA_run (void);
-void DMA_init (int high_page_enable);
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque);
-#endif
diff --git a/hw/mmc.h b/hw/mmc.h
deleted file mode 100644
index 3ae3ea9..0000000
--- a/hw/mmc.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Header for MultiMediaCard (MMC)
- *
- * Copyright 2002 Hewlett-Packard Company
- *
- * Use consistent with the GNU GPL is permitted,
- * provided that this copyright notice is
- * preserved in its entirety in all copies and derived works.
- *
- * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
- * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
- * FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- * Many thanks to Alessandro Rubini and Jonathan Corbet!
- *
- * Based strongly on code by:
- *
- * Author: Yong-iL Joh <tolkien@mizi.com>
- * Date : $Date: 2002/06/18 12:37:30 $
- *
- * Author: Andrew Christian
- * 15 May 2002
- */
-
-#ifndef MMC_MMC_H
-#define MMC_MMC_H
-
-/* Standard MMC commands (4.1) type argument response */
- /* class 1 */
-#define MMC_GO_IDLE_STATE 0 /* bc */
-#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
-#define MMC_ALL_SEND_CID 2 /* bcr R2 */
-#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
-#define MMC_SET_DSR 4 /* bc [31:16] RCA */
-#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
-#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
-#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
-#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
-#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
-#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
-#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
-#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
-#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
-
- /* class 2 */
-#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
-#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
-#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
-
- /* class 3 */
-#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
-
- /* class 4 */
-#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
-#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
-#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
-#define MMC_PROGRAM_CID 26 /* adtc R1 */
-#define MMC_PROGRAM_CSD 27 /* adtc R1 */
-
- /* class 6 */
-#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
-#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
-#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
-
- /* class 5 */
-#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
-#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
-#define MMC_ERASE 38 /* ac R1b */
-
- /* class 9 */
-#define MMC_FAST_IO 39 /* ac <Complex> R4 */
-#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
-
- /* class 7 */
-#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
-
- /* class 8 */
-#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
-#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
-
-/*
- * MMC_SWITCH argument format:
- *
- * [31:26] Always 0
- * [25:24] Access Mode
- * [23:16] Location of target Byte in EXT_CSD
- * [15:08] Value Byte
- * [07:03] Always 0
- * [02:00] Command Set
- */
-
-/*
- MMC status in R1
- Type
- e : error bit
- s : status bit
- r : detected and set for the actual command response
- x : detected and set during command execution. the host must poll
- the card by sending status command in order to read these bits.
- Clear condition
- a : according to the card state
- b : always related to the previous command. Reception of
- a valid command will clear it (with a delay of one command)
- c : clear by read
- */
-
-#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
-#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
-#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
-#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
-#define R1_ERASE_PARAM (1 << 27) /* ex, c */
-#define R1_WP_VIOLATION (1 << 26) /* erx, c */
-#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
-#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
-#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
-#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
-#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
-#define R1_CC_ERROR (1 << 20) /* erx, c */
-#define R1_ERROR (1 << 19) /* erx, c */
-#define R1_UNDERRUN (1 << 18) /* ex, c */
-#define R1_OVERRUN (1 << 17) /* ex, c */
-#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
-#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
-#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
-#define R1_ERASE_RESET (1 << 13) /* sr, c */
-#define R1_STATUS(x) (x & 0xFFFFE000)
-#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
-#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
-#define R1_APP_CMD (1 << 5) /* sr, c */
-
-
-/*
- * OCR bits are mostly in host.h
- */
-#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
-
-/*
- * Card Command Classes (CCC)
- */
-#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
- /* (CMD0,1,2,3,4,7,9,10,12,13,15) */
-#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
- /* (CMD11) */
-#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
- /* (CMD16,17,18) */
-#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
- /* (CMD20) */
-#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
- /* (CMD16,24,25,26,27) */
-#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
- /* (CMD32,33,34,35,36,37,38,39) */
-#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
- /* (CMD28,29,30) */
-#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
- /* (CMD16,CMD42) */
-#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
- /* (CMD55,56,57,ACMD*) */
-#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
- /* (CMD5,39,40,52,53) */
-#define CCC_SWITCH (1<<10) /* (10) High speed switch */
- /* (CMD6,34,35,36,37,50) */
- /* (11) Reserved */
- /* (CMD?) */
-
-/*
- * CSD field definitions
- */
-
-#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
-#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
-#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
-#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
-
-#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
-#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
-#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
-#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
-#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
-
-/*
- * EXT_CSD fields
- */
-
-#define EXT_CSD_BUS_WIDTH 183 /* R/W */
-#define EXT_CSD_HS_TIMING 185 /* R/W */
-#define EXT_CSD_CARD_TYPE 196 /* RO */
-#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
-
-/*
- * EXT_CSD field definitions
- */
-
-#define EXT_CSD_CMD_SET_NORMAL (1<<0)
-#define EXT_CSD_CMD_SET_SECURE (1<<1)
-#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
-
-#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
-#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
-
-#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
-#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
-#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
-
-/*
- * MMC_SWITCH access modes
- */
-
-#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
-#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
-#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
-#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
-
-#endif /* MMC_MMC_PROTOCOL_H */
-
diff --git a/hw/pc.h b/hw/pc.h
deleted file mode 100644
index 2862849..0000000
--- a/hw/pc.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef HW_PC_H
-#define HW_PC_H
-/* PC-style peripherals (also used by other machines). */
-
-/* serial.c */
-
-SerialState *serial_init(int base, qemu_irq irq, int baudbase,
- CharDriverState *chr);
-SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
- qemu_irq irq, int baudbase,
- CharDriverState *chr, int ioregister);
-uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr);
-void serial_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t value);
-uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr);
-void serial_mm_writew (void *opaque, target_phys_addr_t addr, uint32_t value);
-uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr);
-void serial_mm_writel (void *opaque, target_phys_addr_t addr, uint32_t value);
-
-/* parallel.c */
-
-typedef struct ParallelState ParallelState;
-ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr);
-ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr);
-
-/* i8259.c */
-
-typedef struct PicState2 PicState2;
-extern PicState2 *isa_pic;
-void pic_set_irq(int irq, int level);
-void pic_set_irq_new(void *opaque, int irq, int level);
-qemu_irq *i8259_init(qemu_irq parent_irq);
-void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
- void *alt_irq_opaque);
-int pic_read_irq(PicState2 *s);
-void pic_update_irq(PicState2 *s);
-uint32_t pic_intack_read(PicState2 *s);
-void pic_info(void);
-void irq_info(void);
-
-/* APIC */
-typedef struct IOAPICState IOAPICState;
-
-int apic_init(CPUState *env);
-int apic_accept_pic_intr(CPUState *env);
-void apic_deliver_pic_intr(CPUState *env, int level);
-int apic_get_interrupt(CPUState *env);
-IOAPICState *ioapic_init(void);
-void ioapic_set_irq(void *opaque, int vector, int level);
-
-/* i8254.c */
-
-#define PIT_FREQ 1193182
-
-typedef struct PITState PITState;
-
-PITState *pit_init(int base, qemu_irq irq);
-void pit_set_gate(PITState *pit, int channel, int val);
-int pit_get_gate(PITState *pit, int channel);
-int pit_get_initial_count(PITState *pit, int channel);
-int pit_get_mode(PITState *pit, int channel);
-int pit_get_out(PITState *pit, int channel, int64_t current_time);
-
-/* vmport.c */
-void vmport_init(void);
-void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque);
-
-/* vmmouse.c */
-void *vmmouse_init(void *m);
-
-/* pckbd.c */
-
-void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
-void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
- target_phys_addr_t base, int it_shift);
-
-/* mc146818rtc.c */
-
-typedef struct RTCState RTCState;
-
-RTCState *rtc_init(int base, qemu_irq irq);
-RTCState *rtc_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq);
-void rtc_set_memory(RTCState *s, int addr, int val);
-void rtc_set_date(RTCState *s, const struct tm *tm);
-
-/* pc.c */
-extern int fd_bootchk;
-
-void ioport_set_a20(int enable);
-int ioport_get_a20(void);
-
-/* acpi.c */
-extern int acpi_enabled;
-i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
- qemu_irq sci_irq);
-void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
-void acpi_bios_init(void);
-
-/* pcspk.c */
-void pcspk_init(PITState *);
-int pcspk_audio_init(AudioState *, qemu_irq *pic);
-
-/* piix_pci.c */
-PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic);
-void i440fx_set_smm(PCIDevice *d, int val);
-int piix3_init(PCIBus *bus, int devfn);
-void i440fx_init_memory_mappings(PCIDevice *d);
-
-int piix4_init(PCIBus *bus, int devfn);
-
-/* vga.c */
-
-#ifndef TARGET_SPARC
-#define VGA_RAM_SIZE (8192 * 1024)
-#else
-#define VGA_RAM_SIZE (9 * 1024 * 1024)
-#endif
-
-int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size,
- unsigned long vga_bios_offset, int vga_bios_size);
-int isa_vga_mm_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size,
- target_phys_addr_t vram_base, target_phys_addr_t ctrl_base,
- int it_shift);
-
-/* cirrus_vga.c */
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-
-/* ide.c */
-void isa_ide_init(int iobase, int iobase2, qemu_irq irq,
- BlockDriverState *hd0, BlockDriverState *hd1);
-void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
- int secondary_ide_enabled);
-void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
- qemu_irq *pic);
-void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
- qemu_irq *pic);
-
-/* ne2000.c */
-
-void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd);
-
-#endif
diff --git a/hw/pci.c b/hw/pci.c
deleted file mode 100644
index 5f7004a..0000000
--- a/hw/pci.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * QEMU PCI bus manager
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw.h"
-#include "pci.h"
-#include "console.h"
-#include "net.h"
-
-//#define DEBUG_PCI
-
-struct PCIBus {
- int bus_num;
- int devfn_min;
- pci_set_irq_fn set_irq;
- pci_map_irq_fn map_irq;
- uint32_t config_reg; /* XXX: suppress */
- /* low level pic */
- SetIRQFunc *low_set_irq;
- qemu_irq *irq_opaque;
- PCIDevice *devices[256];
- PCIDevice *parent_dev;
- PCIBus *next;
- /* The bus IRQ state is the logical OR of the connected devices.
- Keep a count of the number of devices with raised IRQs. */
- int nirq;
- int irq_count[];
-};
-
-static void pci_update_mappings(PCIDevice *d);
-static void pci_set_irq(void *opaque, int irq_num, int level);
-
-target_phys_addr_t pci_mem_base;
-static int pci_irq_index;
-static PCIBus *first_bus;
-
-static void pcibus_save(QEMUFile *f, void *opaque)
-{
- PCIBus *bus = (PCIBus *)opaque;
- int i;
-
- qemu_put_be32(f, bus->nirq);
- for (i = 0; i < bus->nirq; i++)
- qemu_put_be32(f, bus->irq_count[i]);
-}
-
-static int pcibus_load(QEMUFile *f, void *opaque, int version_id)
-{
- PCIBus *bus = (PCIBus *)opaque;
- int i, nirq;
-
- if (version_id != 1)
- return -EINVAL;
-
- nirq = qemu_get_be32(f);
- if (bus->nirq != nirq) {
- fprintf(stderr, "pcibus_load: nirq mismatch: src=%d dst=%d\n",
- nirq, bus->nirq);
- return -EINVAL;
- }
-
- for (i = 0; i < nirq; i++)
- bus->irq_count[i] = qemu_get_be32(f);
-
- return 0;
-}
-
-PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- qemu_irq *pic, int devfn_min, int nirq)
-{
- PCIBus *bus;
- static int nbus = 0;
-
- bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
- bus->set_irq = set_irq;
- bus->map_irq = map_irq;
- bus->irq_opaque = pic;
- bus->devfn_min = devfn_min;
- bus->nirq = nirq;
- first_bus = bus;
- register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
- return bus;
-}
-
-static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
-{
- PCIBus *bus;
- bus = qemu_mallocz(sizeof(PCIBus));
- bus->map_irq = map_irq;
- bus->parent_dev = dev;
- bus->next = dev->bus->next;
- dev->bus->next = bus;
- return bus;
-}
-
-int pci_bus_num(PCIBus *s)
-{
- return s->bus_num;
-}
-
-void pci_device_save(PCIDevice *s, QEMUFile *f)
-{
- int i;
-
- qemu_put_be32(f, 2); /* PCI device version */
- qemu_put_buffer(f, s->config, 256);
- for (i = 0; i < 4; i++)
- qemu_put_be32(f, s->irq_state[i]);
-}
-
-int pci_device_load(PCIDevice *s, QEMUFile *f)
-{
- uint32_t version_id;
- int i;
-
- version_id = qemu_get_be32(f);
- if (version_id > 2)
- return -EINVAL;
- qemu_get_buffer(f, s->config, 256);
- pci_update_mappings(s);
-
- if (version_id >= 2)
- for (i = 0; i < 4; i ++)
- s->irq_state[i] = qemu_get_be32(f);
-
- return 0;
-}
-
-/* -1 for devfn means auto assign */
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write)
-{
- PCIDevice *pci_dev;
-
- if (pci_irq_index >= PCI_DEVICES_MAX)
- return NULL;
-
- if (devfn < 0) {
- for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
- if (!bus->devices[devfn])
- goto found;
- }
- return NULL;
- found: ;
- }
- pci_dev = qemu_mallocz(instance_size);
- if (!pci_dev)
- return NULL;
- pci_dev->bus = bus;
- pci_dev->devfn = devfn;
- pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
- memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
-
- if (!config_read)
- config_read = pci_default_read_config;
- if (!config_write)
- config_write = pci_default_write_config;
- pci_dev->config_read = config_read;
- pci_dev->config_write = config_write;
- pci_dev->irq_index = pci_irq_index++;
- bus->devices[devfn] = pci_dev;
- pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
- return pci_dev;
-}
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func)
-{
- PCIIORegion *r;
- uint32_t addr;
-
- if ((unsigned int)region_num >= PCI_NUM_REGIONS)
- return;
- r = &pci_dev->io_regions[region_num];
- r->addr = -1;
- r->size = size;
- r->type = type;
- r->map_func = map_func;
- if (region_num == PCI_ROM_SLOT) {
- addr = 0x30;
- } else {
- addr = 0x10 + region_num * 4;
- }
- *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
-}
-
-static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
-{
- return addr + pci_mem_base;
-}
-
-static void pci_update_mappings(PCIDevice *d)
-{
- PCIIORegion *r;
- int cmd, i;
- uint32_t last_addr, new_addr, config_ofs;
-
- cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
- for(i = 0; i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (i == PCI_ROM_SLOT) {
- config_ofs = 0x30;
- } else {
- config_ofs = 0x10 + i * 4;
- }
- if (r->size != 0) {
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- if (cmd & PCI_COMMAND_IO) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we have only 64K ioports on PC */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr >= 0x10000) {
- new_addr = -1;
- }
- } else {
- new_addr = -1;
- }
- } else {
- if (cmd & PCI_COMMAND_MEMORY) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
- /* the ROM slot has a specific enable bit */
- if (i == PCI_ROM_SLOT && !(new_addr & 1))
- goto no_mem_map;
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we do not support wrapping */
- /* XXX: as we cannot support really dynamic
- mappings, we handle specific values as invalid
- mappings. */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr == -1) {
- new_addr = -1;
- }
- } else {
- no_mem_map:
- new_addr = -1;
- }
- }
- /* now do the real mapping */
- if (new_addr != r->addr) {
- if (r->addr != -1) {
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- int class;
- /* NOTE: specific hack for IDE in PC case:
- only one byte must be mapped. */
- class = d->config[0x0a] | (d->config[0x0b] << 8);
- if (class == 0x0101 && r->size == 4) {
- isa_unassign_ioport(r->addr + 2, 1);
- } else {
- isa_unassign_ioport(r->addr, r->size);
- }
- } else {
- cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
- r->size,
- IO_MEM_UNASSIGNED);
- }
- }
- r->addr = new_addr;
- if (r->addr != -1) {
- r->map_func(d, i, r->addr, r->size, r->type);
- }
- }
- }
- }
-}
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len)
-{
- uint32_t val;
-
- switch(len) {
- default:
- case 4:
- if (address <= 0xfc) {
- val = le32_to_cpu(*(uint32_t *)(d->config + address));
- break;
- }
- /* fall through */
- case 2:
- if (address <= 0xfe) {
- val = le16_to_cpu(*(uint16_t *)(d->config + address));
- break;
- }
- /* fall through */
- case 1:
- val = d->config[address];
- break;
- }
- return val;
-}
-
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- int can_write, i;
- uint32_t end, addr;
-
- if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
- (address >= 0x30 && address < 0x34))) {
- PCIIORegion *r;
- int reg;
-
- if ( address >= 0x30 ) {
- reg = PCI_ROM_SLOT;
- }else{
- reg = (address - 0x10) >> 2;
- }
- r = &d->io_regions[reg];
- if (r->size == 0)
- goto default_config;
- /* compute the stored value */
- if (reg == PCI_ROM_SLOT) {
- /* keep ROM enable bit */
- val &= (~(r->size - 1)) | 1;
- } else {
- val &= ~(r->size - 1);
- val |= r->type;
- }
- *(uint32_t *)(d->config + address) = cpu_to_le32(val);
- pci_update_mappings(d);
- return;
- }
- default_config:
- /* not efficient, but simple */
- addr = address;
- for(i = 0; i < len; i++) {
- /* default read/write accesses */
- switch(d->config[0x0e]) {
- case 0x00:
- case 0x80:
- switch(addr) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0e:
- case 0x10 ... 0x27: /* base */
- case 0x30 ... 0x33: /* rom */
- case 0x3d:
- can_write = 0;
- break;
- default:
- can_write = 1;
- break;
- }
- break;
- default:
- case 0x01:
- switch(addr) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0e:
- case 0x38 ... 0x3b: /* rom */
- case 0x3d:
- can_write = 0;
- break;
- default:
- can_write = 1;
- break;
- }
- break;
- }
- if (can_write) {
- d->config[addr] = val;
- }
- if (++addr > 0xff)
- break;
- val >>= 8;
- }
-
- end = address + len;
- if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
- /* if the command register is modified, we must modify the mappings */
- pci_update_mappings(d);
- }
-}
-
-void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
-{
- PCIBus *s = opaque;
- PCIDevice *pci_dev;
- int config_addr, bus_num;
-
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_write: addr=%08x val=%08x len=%d\n",
- addr, val, len);
-#endif
- bus_num = (addr >> 16) & 0xff;
- while (s && s->bus_num != bus_num)
- s = s->next;
- if (!s)
- return;
- pci_dev = s->devices[(addr >> 8) & 0xff];
- if (!pci_dev)
- return;
- config_addr = addr & 0xff;
-#if defined(DEBUG_PCI)
- printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
- pci_dev->config_write(pci_dev, config_addr, val, len);
-}
-
-uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
-{
- PCIBus *s = opaque;
- PCIDevice *pci_dev;
- int config_addr, bus_num;
- uint32_t val;
-
- bus_num = (addr >> 16) & 0xff;
- while (s && s->bus_num != bus_num)
- s= s->next;
- if (!s)
- goto fail;
- pci_dev = s->devices[(addr >> 8) & 0xff];
- if (!pci_dev) {
- fail:
- switch(len) {
- case 1:
- val = 0xff;
- break;
- case 2:
- val = 0xffff;
- break;
- default:
- case 4:
- val = 0xffffffff;
- break;
- }
- goto the_end;
- }
- config_addr = addr & 0xff;
- val = pci_dev->config_read(pci_dev, config_addr, len);
-#if defined(DEBUG_PCI)
- printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
- the_end:
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_read: addr=%08x val=%08x len=%d\n",
- addr, val, len);
-#endif
- return val;
-}
-
-/***********************************************************/
-/* generic PCI irq support */
-
-/* 0 <= irq_num <= 3. level must be 0 or 1 */
-static void pci_set_irq(void *opaque, int irq_num, int level)
-{
- PCIDevice *pci_dev = (PCIDevice *)opaque;
- PCIBus *bus;
- int change;
-
- change = level - pci_dev->irq_state[irq_num];
- if (!change)
- return;
-
- pci_dev->irq_state[irq_num] = level;
- for (;;) {
- bus = pci_dev->bus;
- irq_num = bus->map_irq(pci_dev, irq_num);
- if (bus->set_irq)
- break;
- pci_dev = bus->parent_dev;
- }
- bus->irq_count[irq_num] += change;
- bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
-}
-
-/***********************************************************/
-/* monitor info on PCI */
-
-typedef struct {
- uint16_t class;
- const char *desc;
-} pci_class_desc;
-
-static pci_class_desc pci_class_descriptions[] =
-{
- { 0x0100, "SCSI controller"},
- { 0x0101, "IDE controller"},
- { 0x0102, "Floppy controller"},
- { 0x0103, "IPI controller"},
- { 0x0104, "RAID controller"},
- { 0x0106, "SATA controller"},
- { 0x0107, "SAS controller"},
- { 0x0180, "Storage controller"},
- { 0x0200, "Ethernet controller"},
- { 0x0201, "Token Ring controller"},
- { 0x0202, "FDDI controller"},
- { 0x0203, "ATM controller"},
- { 0x0280, "Network controller"},
- { 0x0300, "VGA controller"},
- { 0x0301, "XGA controller"},
- { 0x0302, "3D controller"},
- { 0x0380, "Display controller"},
- { 0x0400, "Video controller"},
- { 0x0401, "Audio controller"},
- { 0x0402, "Phone"},
- { 0x0480, "Multimedia controller"},
- { 0x0500, "RAM controller"},
- { 0x0501, "Flash controller"},
- { 0x0580, "Memory controller"},
- { 0x0600, "Host bridge"},
- { 0x0601, "ISA bridge"},
- { 0x0602, "EISA bridge"},
- { 0x0603, "MC bridge"},
- { 0x0604, "PCI bridge"},
- { 0x0605, "PCMCIA bridge"},
- { 0x0606, "NUBUS bridge"},
- { 0x0607, "CARDBUS bridge"},
- { 0x0608, "RACEWAY bridge"},
- { 0x0680, "Bridge"},
- { 0x0c03, "USB controller"},
- { 0, NULL}
-};
-
-static void pci_info_device(PCIDevice *d)
-{
- int i, class;
- PCIIORegion *r;
- pci_class_desc *desc;
-
- term_printf(" Bus %2d, device %3d, function %d:\n",
- d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
- class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
- term_printf(" ");
- desc = pci_class_descriptions;
- while (desc->desc && class != desc->class)
- desc++;
- if (desc->desc) {
- term_printf("%s", desc->desc);
- } else {
- term_printf("Class %04x", class);
- }
- term_printf(": PCI device %04x:%04x\n",
- le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
- le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
-
- if (d->config[PCI_INTERRUPT_PIN] != 0) {
- term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
- }
- if (class == 0x0604) {
- term_printf(" BUS %d.\n", d->config[0x19]);
- }
- for(i = 0;i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (r->size != 0) {
- term_printf(" BAR%d: ", i);
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- term_printf("I/O at 0x%04x [0x%04x].\n",
- r->addr, r->addr + r->size - 1);
- } else {
- term_printf("32 bit memory at 0x%08x [0x%08x].\n",
- r->addr, r->addr + r->size - 1);
- }
- }
- }
- if (class == 0x0604 && d->config[0x19] != 0) {
- pci_for_each_device(d->config[0x19], pci_info_device);
- }
-}
-
-void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
-{
- PCIBus *bus = first_bus;
- PCIDevice *d;
- int devfn;
-
- while (bus && bus->bus_num != bus_num)
- bus = bus->next;
- if (bus) {
- for(devfn = 0; devfn < 256; devfn++) {
- d = bus->devices[devfn];
- if (d)
- fn(d);
- }
- }
-}
-
-void pci_info(void)
-{
- pci_for_each_device(0, pci_info_device);
-}
-
-/* Initialize a PCI NIC. */
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)
-{
-#if 0
- if (strcmp(nd->model, "ne2k_pci") == 0) {
- pci_ne2000_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "i82551") == 0) {
- pci_i82551_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "i82557b") == 0) {
- pci_i82557b_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "i82559er") == 0) {
- pci_i82559er_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "rtl8139") == 0) {
- pci_rtl8139_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "e1000") == 0) {
- pci_e1000_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "pcnet") == 0) {
- pci_pcnet_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "?") == 0) {
- fprintf(stderr, "qemu: Supported PCI NICs: i82551 i82557b i82559er"
- " ne2k_pci pcnet rtl8139 e1000\n");
- exit (1);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
- exit (1);
- }
-#endif
-}
-
-typedef struct {
- PCIDevice dev;
- PCIBus *bus;
-} PCIBridge;
-
-static void pci_bridge_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- PCIBridge *s = (PCIBridge *)d;
-
- if (address == 0x19 || (address == 0x18 && len > 1)) {
- if (address == 0x19)
- s->bus->bus_num = val & 0xff;
- else
- s->bus->bus_num = (val >> 8) & 0xff;
-#if defined(DEBUG_PCI)
- printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num);
-#endif
- }
- pci_default_write_config(d, address, val, len);
-}
-
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
- pci_map_irq_fn map_irq, const char *name)
-{
- PCIBridge *s;
- s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
- devfn, NULL, pci_bridge_write_config);
- s->dev.config[0x00] = id >> 16;
- s->dev.config[0x01] = id >> 24;
- s->dev.config[0x02] = id; // device_id
- s->dev.config[0x03] = id >> 8;
- s->dev.config[0x04] = 0x06; // command = bus master, pci mem
- s->dev.config[0x05] = 0x00;
- s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
- s->dev.config[0x07] = 0x00; // status = fast devsel
- s->dev.config[0x08] = 0x00; // revision
- s->dev.config[0x09] = 0x00; // programming i/f
- s->dev.config[0x0A] = 0x04; // class_sub = PCI to PCI bridge
- s->dev.config[0x0B] = 0x06; // class_base = PCI_bridge
- s->dev.config[0x0D] = 0x10; // latency_timer
- s->dev.config[0x0E] = 0x81; // header_type
- s->dev.config[0x1E] = 0xa0; // secondary status
-
- s->bus = pci_register_secondary_bus(&s->dev, map_irq);
- return s->bus;
-}
diff --git a/hw/pci.h b/hw/pci.h
deleted file mode 100644
index e870987..0000000
--- a/hw/pci.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef QEMU_PCI_H
-#define QEMU_PCI_H
-
-/* PCI includes legacy ISA access. */
-#include "isa.h"
-
-/* PCI bus */
-
-extern target_phys_addr_t pci_mem_base;
-
-typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
- uint32_t address, uint32_t data, int len);
-typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
- uint32_t address, int len);
-typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type);
-
-#define PCI_ADDRESS_SPACE_MEM 0x00
-#define PCI_ADDRESS_SPACE_IO 0x01
-#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
-
-typedef struct PCIIORegion {
- uint32_t addr; /* current PCI mapping address. -1 means not mapped */
- uint32_t size;
- uint8_t type;
- PCIMapIORegionFunc *map_func;
-} PCIIORegion;
-
-#define PCI_ROM_SLOT 6
-#define PCI_NUM_REGIONS 7
-
-#define PCI_DEVICES_MAX 64
-
-#define PCI_VENDOR_ID 0x00 /* 16 bits */
-#define PCI_DEVICE_ID 0x02 /* 16 bits */
-#define PCI_COMMAND 0x04 /* 16 bits */
-#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
-#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
-#define PCI_CLASS_DEVICE 0x0a /* Device class */
-#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
-#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
-#define PCI_MIN_GNT 0x3e /* 8 bits */
-#define PCI_MAX_LAT 0x3f /* 8 bits */
-
-struct PCIDevice {
- /* PCI config space */
- uint8_t config[256];
-
- /* the following fields are read only */
- PCIBus *bus;
- int devfn;
- char name[64];
- PCIIORegion io_regions[PCI_NUM_REGIONS];
-
- /* do not access the following fields */
- PCIConfigReadFunc *config_read;
- PCIConfigWriteFunc *config_write;
- /* ??? This is a PC-specific hack, and should be removed. */
- int irq_index;
-
- /* IRQ objects for the INTA-INTD pins. */
- qemu_irq *irq;
-
- /* Current IRQ levels. Used internally by the generic PCI code. */
- int irq_state[4];
-};
-
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write);
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func);
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len);
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len);
-void pci_device_save(PCIDevice *s, QEMUFile *f);
-int pci_device_load(PCIDevice *s, QEMUFile *f);
-
-typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level);
-typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
-PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- qemu_irq *pic, int devfn_min, int nirq);
-
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
-uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
-int pci_bus_num(PCIBus *s);
-void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
-
-void pci_info(void);
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
- pci_map_irq_fn map_irq, const char *name);
-
-/* lsi53c895a.c */
-#define LSI_MAX_DEVS 7
-void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
-void *lsi_scsi_init(PCIBus *bus, int devfn);
-
-/* vmware_vga.c */
-void pci_vmsvga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-
-/* usb-uhci.c */
-void usb_uhci_piix3_init(PCIBus *bus, int devfn);
-void usb_uhci_piix4_init(PCIBus *bus, int devfn);
-
-/* usb-ohci.c */
-void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn);
-
-/* eepro100.c */
-
-void pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* ne2000.c */
-
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* rtl8139.c */
-
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* e1000.c */
-void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* pcnet.c */
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* prep_pci.c */
-PCIBus *pci_prep_init(qemu_irq *pic);
-
-/* apb_pci.c */
-PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base,
- qemu_irq *pic);
-
-#endif
diff --git a/hw/pci_host.h b/hw/pci_host.h
deleted file mode 100644
index 49a0c59..0000000
--- a/hw/pci_host.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * QEMU Common PCI Host bridge configuration data space access routines.
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Worker routines for a PCI host controller that uses an {address,data}
- register pair to access PCI configuration space. */
-
-typedef struct {
- uint32_t config_reg;
- PCIBus *bus;
-} PCIHostState;
-
-static void pci_host_data_writeb(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg | (addr & 3), val, 1);
-}
-
-static void pci_host_data_writew(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg | (addr & 3), val, 2);
-}
-
-static void pci_host_data_writel(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg, val, 4);
-}
-
-static uint32_t pci_host_data_readb(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- if (!(s->config_reg & (1 << 31)))
- return 0xff;
- return pci_data_read(s->bus, s->config_reg | (addr & 3), 1);
-}
-
-static uint32_t pci_host_data_readw(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- uint32_t val;
- if (!(s->config_reg & (1 << 31)))
- return 0xffff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- return val;
-}
-
-static uint32_t pci_host_data_readl(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- uint32_t val;
- if (!(s->config_reg & (1 << 31)))
- return 0xffffffff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
diff --git a/hw/pcmcia.h b/hw/pcmcia.h
deleted file mode 100644
index bfa23ba..0000000
--- a/hw/pcmcia.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* PCMCIA/Cardbus */
-
-struct pcmcia_socket_s {
- qemu_irq irq;
- int attached;
- const char *slot_string;
- const char *card_string;
-};
-
-void pcmcia_socket_register(struct pcmcia_socket_s *socket);
-void pcmcia_socket_unregister(struct pcmcia_socket_s *socket);
-void pcmcia_info(void);
-
-struct pcmcia_card_s {
- void *state;
- struct pcmcia_socket_s *slot;
- int (*attach)(void *state);
- int (*detach)(void *state);
- const uint8_t *cis;
- int cis_len;
-
- /* Only valid if attached */
- uint8_t (*attr_read)(void *state, uint32_t address);
- void (*attr_write)(void *state, uint32_t address, uint8_t value);
- uint16_t (*common_read)(void *state, uint32_t address);
- void (*common_write)(void *state, uint32_t address, uint16_t value);
- uint16_t (*io_read)(void *state, uint32_t address);
- void (*io_write)(void *state, uint32_t address, uint16_t value);
-};
-
-#define CISTPL_DEVICE 0x01 /* 5V Device Information Tuple */
-#define CISTPL_NO_LINK 0x14 /* No Link Tuple */
-#define CISTPL_VERS_1 0x15 /* Level 1 Version Tuple */
-#define CISTPL_JEDEC_C 0x18 /* JEDEC ID Tuple */
-#define CISTPL_JEDEC_A 0x19 /* JEDEC ID Tuple */
-#define CISTPL_CONFIG 0x1a /* Configuration Tuple */
-#define CISTPL_CFTABLE_ENTRY 0x1b /* 16-bit PCCard Configuration */
-#define CISTPL_DEVICE_OC 0x1c /* Additional Device Information */
-#define CISTPL_DEVICE_OA 0x1d /* Additional Device Information */
-#define CISTPL_DEVICE_GEO 0x1e /* Additional Device Information */
-#define CISTPL_DEVICE_GEO_A 0x1f /* Additional Device Information */
-#define CISTPL_MANFID 0x20 /* Manufacture ID Tuple */
-#define CISTPL_FUNCID 0x21 /* Function ID Tuple */
-#define CISTPL_FUNCE 0x22 /* Function Extension Tuple */
-#define CISTPL_END 0xff /* Tuple End */
-#define CISTPL_ENDMARK 0xff
-
-/* dscm1xxxx.c */
-struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv);
-
diff --git a/hw/power_supply.h b/hw/power_supply.h
deleted file mode 100644
index b85edc7..0000000
--- a/hw/power_supply.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Universal power supply monitor class
- *
- * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
- * Copyright © 2004 Szabolcs Gyurko
- * Copyright © 2003 Ian Molton <spyro@f2s.com>
- *
- * Modified: 2004, Oct Szabolcs Gyurko
- *
- * You may use this code as per GPL version 2
- */
-
-#ifndef __LINUX_POWER_SUPPLY_H__
-#define __LINUX_POWER_SUPPLY_H__
-
-/*
- * All voltages, currents, charges, energies, time and temperatures in uV,
- * µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise
- * stated. It's driver's job to convert its raw values to units in which
- * this class operates.
- */
-
-/*
- * For systems where the charger determines the maximum battery capacity
- * the min and max fields should be used to present these values to user
- * space. Unused/unknown fields will not appear in sysfs.
- */
-
-enum {
- POWER_SUPPLY_STATUS_UNKNOWN = 0,
- POWER_SUPPLY_STATUS_CHARGING,
- POWER_SUPPLY_STATUS_DISCHARGING,
- POWER_SUPPLY_STATUS_NOT_CHARGING,
- POWER_SUPPLY_STATUS_FULL,
-};
-
-enum {
- POWER_SUPPLY_HEALTH_UNKNOWN = 0,
- POWER_SUPPLY_HEALTH_GOOD,
- POWER_SUPPLY_HEALTH_OVERHEAT,
- POWER_SUPPLY_HEALTH_DEAD,
- POWER_SUPPLY_HEALTH_OVERVOLTAGE,
- POWER_SUPPLY_HEALTH_UNSPEC_FAILURE,
-};
-
-enum {
- POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0,
- POWER_SUPPLY_TECHNOLOGY_NiMH,
- POWER_SUPPLY_TECHNOLOGY_LION,
- POWER_SUPPLY_TECHNOLOGY_LIPO,
- POWER_SUPPLY_TECHNOLOGY_LiFe,
- POWER_SUPPLY_TECHNOLOGY_NiCd,
-};
-
-enum {
- POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN = 0,
- POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL,
- POWER_SUPPLY_CAPACITY_LEVEL_LOW,
- POWER_SUPPLY_CAPACITY_LEVEL_NORMAL,
- POWER_SUPPLY_CAPACITY_LEVEL_HIGH,
- POWER_SUPPLY_CAPACITY_LEVEL_FULL,
-};
-
-enum power_supply_property {
- /* Properties of type `int' */
- POWER_SUPPLY_PROP_STATUS = 0,
- POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_VOLTAGE_AVG,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_CURRENT_AVG,
- POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
- POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
- POWER_SUPPLY_PROP_CHARGE_FULL,
- POWER_SUPPLY_PROP_CHARGE_EMPTY,
- POWER_SUPPLY_PROP_CHARGE_NOW,
- POWER_SUPPLY_PROP_CHARGE_AVG,
- POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
- POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
- POWER_SUPPLY_PROP_ENERGY_FULL,
- POWER_SUPPLY_PROP_ENERGY_EMPTY,
- POWER_SUPPLY_PROP_ENERGY_NOW,
- POWER_SUPPLY_PROP_ENERGY_AVG,
- POWER_SUPPLY_PROP_CAPACITY, /* in percents! */
- POWER_SUPPLY_PROP_CAPACITY_LEVEL,
- POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_TEMP_AMBIENT,
- POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
- POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
- POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
- POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
- /* Properties of type `const char *' */
- POWER_SUPPLY_PROP_MODEL_NAME,
- POWER_SUPPLY_PROP_MANUFACTURER,
-};
-
-enum power_supply_type {
- POWER_SUPPLY_TYPE_BATTERY = 0,
- POWER_SUPPLY_TYPE_UPS,
- POWER_SUPPLY_TYPE_MAINS,
- POWER_SUPPLY_TYPE_USB,
-};
-
-#endif /* __LINUX_POWER_SUPPLY_H__ */
diff --git a/hw/pxa.h b/hw/pxa.h
deleted file mode 100644
index 16a68d9..0000000
--- a/hw/pxa.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Intel XScale PXA255/270 processor support.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licenced under the GNU GPL v2.
- */
-#ifndef PXA_H
-# define PXA_H "pxa.h"
-
-/* Interrupt numbers */
-# define PXA2XX_PIC_SSP3 0
-# define PXA2XX_PIC_USBH2 2
-# define PXA2XX_PIC_USBH1 3
-# define PXA2XX_PIC_KEYPAD 4
-# define PXA2XX_PIC_PWRI2C 6
-# define PXA25X_PIC_HWUART 7
-# define PXA27X_PIC_OST_4_11 7
-# define PXA2XX_PIC_GPIO_0 8
-# define PXA2XX_PIC_GPIO_1 9
-# define PXA2XX_PIC_GPIO_X 10
-# define PXA2XX_PIC_I2S 13
-# define PXA26X_PIC_ASSP 15
-# define PXA25X_PIC_NSSP 16
-# define PXA27X_PIC_SSP2 16
-# define PXA2XX_PIC_LCD 17
-# define PXA2XX_PIC_I2C 18
-# define PXA2XX_PIC_ICP 19
-# define PXA2XX_PIC_STUART 20
-# define PXA2XX_PIC_BTUART 21
-# define PXA2XX_PIC_FFUART 22
-# define PXA2XX_PIC_MMC 23
-# define PXA2XX_PIC_SSP 24
-# define PXA2XX_PIC_DMA 25
-# define PXA2XX_PIC_OST_0 26
-# define PXA2XX_PIC_RTC1HZ 30
-# define PXA2XX_PIC_RTCALARM 31
-
-/* DMA requests */
-# define PXA2XX_RX_RQ_I2S 2
-# define PXA2XX_TX_RQ_I2S 3
-# define PXA2XX_RX_RQ_BTUART 4
-# define PXA2XX_TX_RQ_BTUART 5
-# define PXA2XX_RX_RQ_FFUART 6
-# define PXA2XX_TX_RQ_FFUART 7
-# define PXA2XX_RX_RQ_SSP1 13
-# define PXA2XX_TX_RQ_SSP1 14
-# define PXA2XX_RX_RQ_SSP2 15
-# define PXA2XX_TX_RQ_SSP2 16
-# define PXA2XX_RX_RQ_ICP 17
-# define PXA2XX_TX_RQ_ICP 18
-# define PXA2XX_RX_RQ_STUART 19
-# define PXA2XX_TX_RQ_STUART 20
-# define PXA2XX_RX_RQ_MMCI 21
-# define PXA2XX_TX_RQ_MMCI 22
-# define PXA2XX_USB_RQ(x) ((x) + 24)
-# define PXA2XX_RX_RQ_SSP3 66
-# define PXA2XX_TX_RQ_SSP3 67
-
-# define PXA2XX_SDRAM_BASE 0xa0000000
-# define PXA2XX_INTERNAL_BASE 0x5c000000
-# define PXA2XX_INTERNAL_SIZE 0x40000
-
-/* pxa2xx_pic.c */
-qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env);
-
-/* pxa2xx_timer.c */
-void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs);
-void pxa27x_timer_init(target_phys_addr_t base, qemu_irq *irqs, qemu_irq irq4);
-
-/* pxa2xx_gpio.c */
-struct pxa2xx_gpio_info_s;
-struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base,
- CPUState *env, qemu_irq *pic, int lines);
-qemu_irq *pxa2xx_gpio_in_get(struct pxa2xx_gpio_info_s *s);
-void pxa2xx_gpio_out_set(struct pxa2xx_gpio_info_s *s,
- int line, qemu_irq handler);
-void pxa2xx_gpio_read_notifier(struct pxa2xx_gpio_info_s *s, qemu_irq handler);
-
-/* pxa2xx_dma.c */
-struct pxa2xx_dma_state_s;
-struct pxa2xx_dma_state_s *pxa255_dma_init(target_phys_addr_t base,
- qemu_irq irq);
-struct pxa2xx_dma_state_s *pxa27x_dma_init(target_phys_addr_t base,
- qemu_irq irq);
-void pxa2xx_dma_request(struct pxa2xx_dma_state_s *s, int req_num, int on);
-
-/* pxa2xx_lcd.c */
-struct pxa2xx_lcdc_s;
-struct pxa2xx_lcdc_s *pxa2xx_lcdc_init(target_phys_addr_t base,
- qemu_irq irq, DisplayState *ds);
-void pxa2xx_lcd_vsync_notifier(struct pxa2xx_lcdc_s *s, qemu_irq handler);
-void pxa2xx_lcdc_oritentation(void *opaque, int angle);
-
-/* pxa2xx_mmci.c */
-struct pxa2xx_mmci_s;
-struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base,
- BlockDriverState *bd, qemu_irq irq, void *dma);
-void pxa2xx_mmci_handlers(struct pxa2xx_mmci_s *s, qemu_irq readonly,
- qemu_irq coverswitch);
-
-/* pxa2xx_pcmcia.c */
-struct pxa2xx_pcmcia_s;
-struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base);
-int pxa2xx_pcmcia_attach(void *opaque, struct pcmcia_card_s *card);
-int pxa2xx_pcmcia_dettach(void *opaque);
-void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
-
-/* pxa2xx_keypad.c */
-struct keymap {
- int column;
- int row;
-};
-struct pxa2xx_keypad_s;
-struct pxa2xx_keypad_s *pxa27x_keypad_init(target_phys_addr_t base,
- qemu_irq irq);
-void pxa27x_register_keypad(struct pxa2xx_keypad_s *kp, struct keymap *map,
- int size);
-
-/* pxa2xx.c */
-struct pxa2xx_ssp_s;
-void pxa2xx_ssp_attach(struct pxa2xx_ssp_s *port,
- uint32_t (*readfn)(void *opaque),
- void (*writefn)(void *opaque, uint32_t value), void *opaque);
-
-struct pxa2xx_i2c_s;
-struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
- qemu_irq irq, uint32_t page_size);
-i2c_bus *pxa2xx_i2c_bus(struct pxa2xx_i2c_s *s);
-
-struct pxa2xx_i2s_s;
-struct pxa2xx_fir_s;
-
-struct pxa2xx_state_s {
- CPUState *env;
- qemu_irq *pic;
- qemu_irq reset;
- struct pxa2xx_dma_state_s *dma;
- struct pxa2xx_gpio_info_s *gpio;
- struct pxa2xx_lcdc_s *lcd;
- struct pxa2xx_ssp_s **ssp;
- struct pxa2xx_i2c_s *i2c[2];
- struct pxa2xx_mmci_s *mmc;
- struct pxa2xx_pcmcia_s *pcmcia[2];
- struct pxa2xx_i2s_s *i2s;
- struct pxa2xx_fir_s *fir;
- struct pxa2xx_keypad_s *kp;
-
- /* Power management */
- target_phys_addr_t pm_base;
- uint32_t pm_regs[0x40];
-
- /* Clock management */
- target_phys_addr_t cm_base;
- uint32_t cm_regs[4];
- uint32_t clkcfg;
-
- /* Memory management */
- target_phys_addr_t mm_base;
- uint32_t mm_regs[0x1a];
-
- /* Performance monitoring */
- uint32_t pmnc;
-
- /* Real-Time clock */
- target_phys_addr_t rtc_base;
- uint32_t rttr;
- uint32_t rtsr;
- uint32_t rtar;
- uint32_t rdar1;
- uint32_t rdar2;
- uint32_t ryar1;
- uint32_t ryar2;
- uint32_t swar1;
- uint32_t swar2;
- uint32_t piar;
- uint32_t last_rcnr;
- uint32_t last_rdcr;
- uint32_t last_rycr;
- uint32_t last_swcr;
- uint32_t last_rtcpicr;
- int64_t last_hz;
- int64_t last_sw;
- int64_t last_pi;
- QEMUTimer *rtc_hz;
- QEMUTimer *rtc_rdal1;
- QEMUTimer *rtc_rdal2;
- QEMUTimer *rtc_swal1;
- QEMUTimer *rtc_swal2;
- QEMUTimer *rtc_pi;
-};
-
-struct pxa2xx_i2s_s {
- target_phys_addr_t base;
- qemu_irq irq;
- struct pxa2xx_dma_state_s *dma;
- void (*data_req)(void *, int, int);
-
- uint32_t control[2];
- uint32_t status;
- uint32_t mask;
- uint32_t clk;
-
- int enable;
- int rx_len;
- int tx_len;
- void (*codec_out)(void *, uint32_t);
- uint32_t (*codec_in)(void *);
- void *opaque;
-
- int fifo_len;
- uint32_t fifo[16];
-};
-
-# define PA_FMT "0x%08lx"
-# define REG_FMT "0x" TARGET_FMT_plx
-
-struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, DisplayState *ds,
- const char *revision);
-struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, DisplayState *ds);
-
-/* usb-ohci.c */
-void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
- qemu_irq irq);
-
-#endif /* PXA_H */
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
deleted file mode 100644
index 16b3215..0000000
--- a/hw/scsi-disk.c
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * SCSI Device emulation
- *
- * Copyright (c) 2006 CodeSourcery.
- * Based on code by Fabrice Bellard
- *
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- *
- * Note that this file only handles the SCSI architecture model and device
- * commands. Emulation of interface/link layer protocols is handled by
- * the host adapter emulator.
- */
-
-//#define DEBUG_SCSI
-
-#ifdef DEBUG_SCSI
-#define DPRINTF(fmt, args...) \
-do { printf("scsi-disk: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-#define BADF(fmt, args...) \
-do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
-
-#include "qemu-common.h"
-#include "block.h"
-#include "scsi-disk.h"
-
-#define SENSE_NO_SENSE 0
-#define SENSE_NOT_READY 2
-#define SENSE_HARDWARE_ERROR 4
-#define SENSE_ILLEGAL_REQUEST 5
-
-#define SCSI_DMA_BUF_SIZE 65536
-
-typedef struct SCSIRequest {
- SCSIDeviceState *dev;
- uint32_t tag;
- /* ??? We should probably keep track of whether the data trasfer is
- a read or a write. Currently we rely on the host getting it right. */
- /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
- int sector;
- int sector_count;
- /* The amounnt of data in the buffer. */
- int buf_len;
- uint8_t *dma_buf;
- BlockDriverAIOCB *aiocb;
- struct SCSIRequest *next;
-} SCSIRequest;
-
-struct SCSIDeviceState
-{
- BlockDriverState *bdrv;
- SCSIRequest *requests;
- /* The qemu block layer uses a fixed 512 byte sector size.
- This is the number of 512 byte blocks in a single scsi sector. */
- int cluster_size;
- int sense;
- int tcq;
- /* Completion functions may be called from either scsi_{read,write}_data
- or from the AIO completion routines. */
- scsi_completionfn completion;
- void *opaque;
-};
-
-/* Global pool of SCSIRequest structures. */
-static SCSIRequest *free_requests = NULL;
-
-static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
-{
- SCSIRequest *r;
-
- if (free_requests) {
- r = free_requests;
- free_requests = r->next;
- } else {
- r = qemu_malloc(sizeof(SCSIRequest));
- r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
- }
- r->dev = s;
- r->tag = tag;
- r->sector_count = 0;
- r->buf_len = 0;
- r->aiocb = NULL;
-
- r->next = s->requests;
- s->requests = r;
- return r;
-}
-
-static void scsi_remove_request(SCSIRequest *r)
-{
- SCSIRequest *last;
- SCSIDeviceState *s = r->dev;
-
- if (s->requests == r) {
- s->requests = r->next;
- } else {
- last = s->requests;
- while (last && last->next != r)
- last = last->next;
- if (last) {
- last->next = r->next;
- } else {
- BADF("Orphaned request\n");
- }
- }
- r->next = free_requests;
- free_requests = r;
-}
-
-static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
-{
- SCSIRequest *r;
-
- r = s->requests;
- while (r && r->tag != tag)
- r = r->next;
-
- return r;
-}
-
-/* Helper function for command completion. */
-static void scsi_command_complete(SCSIRequest *r, int sense)
-{
- SCSIDeviceState *s = r->dev;
- uint32_t tag;
- DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
- s->sense = sense;
- tag = r->tag;
- scsi_remove_request(r);
- s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
-}
-
-/* Cancel a pending data transfer. */
-static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
-{
- SCSIDeviceState *s = d->state;
- SCSIRequest *r;
- DPRINTF("Cancel tag=0x%x\n", tag);
- r = scsi_find_request(s, tag);
- if (r) {
- if (r->aiocb)
- bdrv_aio_cancel(r->aiocb);
- r->aiocb = NULL;
- scsi_remove_request(r);
- }
-}
-
-static void scsi_read_complete(void * opaque, int ret)
-{
- SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIDeviceState *s = r->dev;
-
- if (ret) {
- DPRINTF("IO error\n");
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return;
- }
- DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
-
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
-}
-
-/* Read more data from scsi device into buffer. */
-static void scsi_read_data(SCSIDevice *d, uint32_t tag)
-{
- SCSIDeviceState *s = d->state;
- SCSIRequest *r;
- uint32_t n;
-
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad read tag 0x%x\n", tag);
- /* ??? This is the wrong error. */
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return;
- }
- if (r->sector_count == (uint32_t)-1) {
- DPRINTF("Read buf_len=%d\n", r->buf_len);
- r->sector_count = 0;
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
- return;
- }
- DPRINTF("Read sector_count=%d\n", r->sector_count);
- if (r->sector_count == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- return;
- }
-
- n = r->sector_count;
- if (n > SCSI_DMA_BUF_SIZE / 512)
- n = SCSI_DMA_BUF_SIZE / 512;
-
- r->buf_len = n * 512;
- r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
- scsi_read_complete, r);
- if (r->aiocb == NULL)
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- r->sector += n;
- r->sector_count -= n;
-}
-
-static void scsi_write_complete(void * opaque, int ret)
-{
- SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIDeviceState *s = r->dev;
- uint32_t len;
-
- if (ret) {
- fprintf(stderr, "scsi-disc: IO write error\n");
- exit(1);
- }
-
- r->aiocb = NULL;
- if (r->sector_count == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- } else {
- len = r->sector_count * 512;
- if (len > SCSI_DMA_BUF_SIZE) {
- len = SCSI_DMA_BUF_SIZE;
- }
- r->buf_len = len;
- DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
- }
-}
-
-/* Write data to a scsi device. Returns nonzero on failure.
- The transfer may complete asynchronously. */
-static int scsi_write_data(SCSIDevice *d, uint32_t tag)
-{
- SCSIDeviceState *s = d->state;
- SCSIRequest *r;
- uint32_t n;
-
- DPRINTF("Write data tag=0x%x\n", tag);
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad write tag 0x%x\n", tag);
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return 1;
- }
- if (r->aiocb)
- BADF("Data transfer already in progress\n");
- n = r->buf_len / 512;
- if (n) {
- r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
- scsi_write_complete, r);
- if (r->aiocb == NULL)
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- r->sector += n;
- r->sector_count -= n;
- } else {
- /* Invoke completion routine to fetch data from host. */
- scsi_write_complete(r, 0);
- }
-
- return 0;
-}
-
-/* Return a pointer to the data buffer. */
-static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
-{
- SCSIDeviceState *s = d->state;
- SCSIRequest *r;
-
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad buffer tag 0x%x\n", tag);
- return NULL;
- }
- return r->dma_buf;
-}
-
-/* Execute a scsi command. Returns the length of the data expected by the
- command. This will be Positive for data transfers from the device
- (eg. disk reads), negative for transfers to the device (eg. disk writes),
- and zero if the command does not transfer any data. */
-
-static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
- uint8_t *buf, int lun)
-{
- SCSIDeviceState *s = d->state;
- uint64_t nb_sectors;
- uint32_t lba;
- uint32_t len;
- int cmdlen;
- int is_write;
- uint8_t command;
- uint8_t *outbuf;
- SCSIRequest *r;
-
- command = buf[0];
- r = scsi_find_request(s, tag);
- if (r) {
- BADF("Tag 0x%x already in use\n", tag);
- scsi_cancel_io(d, tag);
- }
- /* ??? Tags are not unique for different luns. We only implement a
- single lun, so this should not matter. */
- r = scsi_new_request(s, tag);
- outbuf = r->dma_buf;
- is_write = 0;
- DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
- switch (command >> 5) {
- case 0:
- lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
- len = buf[4];
- cmdlen = 6;
- break;
- case 1:
- case 2:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[8] | (buf[7] << 8);
- cmdlen = 10;
- break;
- case 4:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
- cmdlen = 16;
- break;
- case 5:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
- cmdlen = 12;
- break;
- default:
- BADF("Unsupported command length, command %x\n", command);
- goto fail;
- }
-#ifdef DEBUG_SCSI
- {
- int i;
- for (i = 1; i < cmdlen; i++) {
- printf(" 0x%02x", buf[i]);
- }
- printf("\n");
- }
-#endif
- if (lun || buf[1] >> 5) {
- /* Only LUN 0 supported. */
- DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
- goto fail;
- }
- switch (command) {
- case 0x0:
- DPRINTF("Test Unit Ready\n");
- break;
- case 0x03:
- DPRINTF("Request Sense (len %d)\n", len);
- if (len < 4)
- goto fail;
- memset(outbuf, 0, 4);
- outbuf[0] = 0xf0;
- outbuf[1] = 0;
- outbuf[2] = s->sense;
- r->buf_len = 4;
- break;
- case 0x12:
- DPRINTF("Inquiry (len %d)\n", len);
- if (buf[1] & 0x2) {
- /* Command support data - optional, not implemented */
- BADF("optional INQUIRY command support request not implemented\n");
- goto fail;
- }
- else if (buf[1] & 0x1) {
- /* Vital product data */
- uint8_t page_code = buf[2];
- if (len < 4) {
- BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
- "less than 4\n", page_code, len);
- goto fail;
- }
-
- switch (page_code) {
- case 0x00:
- {
- /* Supported page codes, mandatory */
- DPRINTF("Inquiry EVPD[Supported pages] "
- "buffer size %d\n", len);
-
- r->buf_len = 0;
-
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[r->buf_len++] = 5;
- } else {
- outbuf[r->buf_len++] = 0;
- }
-
- outbuf[r->buf_len++] = 0x00; // this page
- outbuf[r->buf_len++] = 0x00;
- outbuf[r->buf_len++] = 3; // number of pages
- outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)
- outbuf[r->buf_len++] = 0x80; // unit serial number
- outbuf[r->buf_len++] = 0x83; // device identification
- }
- break;
- case 0x80:
- {
- /* Device serial number, optional */
- if (len < 4) {
- BADF("Error: EVPD[Serial number] Inquiry buffer "
- "size %d too small, %d needed\n", len, 4);
- goto fail;
- }
-
- DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
-
- r->buf_len = 0;
-
- /* Supported page codes */
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[r->buf_len++] = 5;
- } else {
- outbuf[r->buf_len++] = 0;
- }
-
- outbuf[r->buf_len++] = 0x80; // this page
- outbuf[r->buf_len++] = 0x00;
- outbuf[r->buf_len++] = 0x01; // 1 byte data follow
-
- outbuf[r->buf_len++] = '0'; // 1 byte data follow
- }
-
- break;
- case 0x83:
- {
- /* Device identification page, mandatory */
- int max_len = 255 - 8;
- int id_len = strlen(bdrv_get_device_name(s->bdrv));
- if (id_len > max_len)
- id_len = max_len;
-
- DPRINTF("Inquiry EVPD[Device identification] "
- "buffer size %d\n", len);
- r->buf_len = 0;
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[r->buf_len++] = 5;
- } else {
- outbuf[r->buf_len++] = 0;
- }
-
- outbuf[r->buf_len++] = 0x83; // this page
- outbuf[r->buf_len++] = 0x00;
- outbuf[r->buf_len++] = 3 + id_len;
-
- outbuf[r->buf_len++] = 0x2; // ASCII
- outbuf[r->buf_len++] = 0; // not officially assigned
- outbuf[r->buf_len++] = 0; // reserved
- outbuf[r->buf_len++] = id_len; // length of data following
-
- memcpy(&outbuf[r->buf_len],
- bdrv_get_device_name(s->bdrv), id_len);
- r->buf_len += id_len;
- }
- break;
- default:
- BADF("Error: unsupported Inquiry (EVPD[%02X]) "
- "buffer size %d\n", page_code, len);
- goto fail;
- }
- /* done with EVPD */
- break;
- }
- else {
- /* Standard INQUIRY data */
- if (buf[2] != 0) {
- BADF("Error: Inquiry (STANDARD) page or code "
- "is non-zero [%02X]\n", buf[2]);
- goto fail;
- }
-
- /* PAGE CODE == 0 */
- if (len < 5) {
- BADF("Error: Inquiry (STANDARD) buffer size %d "
- "is less than 5\n", len);
- goto fail;
- }
-
- if (len < 36) {
- BADF("Error: Inquiry (STANDARD) buffer size %d "
- "is less than 36 (TODO: only 5 required)\n", len);
- }
- }
- memset(outbuf, 0, 36);
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[0] = 5;
- outbuf[1] = 0x80;
- memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
- } else {
- outbuf[0] = 0;
- memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
- }
- memcpy(&outbuf[8], "QEMU ", 8);
- memcpy(&outbuf[32], QEMU_VERSION, 4);
- /* Identify device as SCSI-3 rev 1.
- Some later commands are also implemented. */
- outbuf[2] = 3;
- outbuf[3] = 2; /* Format 2 */
- outbuf[4] = 31;
- /* Sync data transfer and TCQ. */
- outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
- r->buf_len = 36;
- break;
- case 0x16:
- DPRINTF("Reserve(6)\n");
- if (buf[1] & 1)
- goto fail;
- break;
- case 0x17:
- DPRINTF("Release(6)\n");
- if (buf[1] & 1)
- goto fail;
- break;
- case 0x1a:
- case 0x5a:
- {
- uint8_t *p;
- int page;
-
- page = buf[2] & 0x3f;
- DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
- p = outbuf;
- memset(p, 0, 4);
- outbuf[1] = 0; /* Default media type. */
- outbuf[3] = 0; /* Block descriptor length. */
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[2] = 0x80; /* Readonly. */
- }
- p += 4;
- if (page == 4) {
- int cylinders, heads, secs;
-
- /* Rigid disk device geometry page. */
- p[0] = 4;
- p[1] = 0x16;
- /* if a geometry hint is available, use it */
- bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
- p[2] = (cylinders >> 16) & 0xff;
- p[3] = (cylinders >> 8) & 0xff;
- p[4] = cylinders & 0xff;
- p[5] = heads & 0xff;
- /* Write precomp start cylinder, disabled */
- p[6] = (cylinders >> 16) & 0xff;
- p[7] = (cylinders >> 8) & 0xff;
- p[8] = cylinders & 0xff;
- /* Reduced current start cylinder, disabled */
- p[9] = (cylinders >> 16) & 0xff;
- p[10] = (cylinders >> 8) & 0xff;
- p[11] = cylinders & 0xff;
- /* Device step rate [ns], 200ns */
- p[12] = 0;
- p[13] = 200;
- /* Landing zone cylinder */
- p[14] = 0xff;
- p[15] = 0xff;
- p[16] = 0xff;
- /* Medium rotation rate [rpm], 5400 rpm */
- p[20] = (5400 >> 8) & 0xff;
- p[21] = 5400 & 0xff;
- p += 0x16;
- } else if (page == 5) {
- int cylinders, heads, secs;
-
- /* Flexible disk device geometry page. */
- p[0] = 5;
- p[1] = 0x1e;
- /* Transfer rate [kbit/s], 5Mbit/s */
- p[2] = 5000 >> 8;
- p[3] = 5000 & 0xff;
- /* if a geometry hint is available, use it */
- bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
- p[4] = heads & 0xff;
- p[5] = secs & 0xff;
- p[6] = s->cluster_size * 2;
- p[8] = (cylinders >> 8) & 0xff;
- p[9] = cylinders & 0xff;
- /* Write precomp start cylinder, disabled */
- p[10] = (cylinders >> 8) & 0xff;
- p[11] = cylinders & 0xff;
- /* Reduced current start cylinder, disabled */
- p[12] = (cylinders >> 8) & 0xff;
- p[13] = cylinders & 0xff;
- /* Device step rate [100us], 100us */
- p[14] = 0;
- p[15] = 1;
- /* Device step pulse width [us], 1us */
- p[16] = 1;
- /* Device head settle delay [100us], 100us */
- p[17] = 0;
- p[18] = 1;
- /* Motor on delay [0.1s], 0.1s */
- p[19] = 1;
- /* Motor off delay [0.1s], 0.1s */
- p[20] = 1;
- /* Medium rotation rate [rpm], 5400 rpm */
- p[28] = (5400 >> 8) & 0xff;
- p[29] = 5400 & 0xff;
- p += 0x1e;
- } else if ((page == 8 || page == 0x3f)) {
- /* Caching page. */
- memset(p,0,20);
- p[0] = 8;
- p[1] = 0x12;
- p[2] = 4; /* WCE */
- p += 20;
- }
- if ((page == 0x3f || page == 0x2a)
- && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
- /* CD Capabilities and Mechanical Status page. */
- p[0] = 0x2a;
- p[1] = 0x14;
- p[2] = 3; // CD-R & CD-RW read
- p[3] = 0; // Writing not supported
- p[4] = 0x7f; /* Audio, composite, digital out,
- mode 2 form 1&2, multi session */
- p[5] = 0xff; /* CD DA, DA accurate, RW supported,
- RW corrected, C2 errors, ISRC,
- UPC, Bar code */
- p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
- /* Locking supported, jumper present, eject, tray */
- p[7] = 0; /* no volume & mute control, no
- changer */
- p[8] = (50 * 176) >> 8; // 50x read speed
- p[9] = (50 * 176) & 0xff;
- p[10] = 0 >> 8; // No volume
- p[11] = 0 & 0xff;
- p[12] = 2048 >> 8; // 2M buffer
- p[13] = 2048 & 0xff;
- p[14] = (16 * 176) >> 8; // 16x read speed current
- p[15] = (16 * 176) & 0xff;
- p[18] = (16 * 176) >> 8; // 16x write speed
- p[19] = (16 * 176) & 0xff;
- p[20] = (16 * 176) >> 8; // 16x write speed current
- p[21] = (16 * 176) & 0xff;
- p += 22;
- }
- r->buf_len = p - outbuf;
- outbuf[0] = r->buf_len - 4;
- if (r->buf_len > len)
- r->buf_len = len;
- }
- break;
- case 0x1b:
- DPRINTF("Start Stop Unit\n");
- break;
- case 0x1e:
- DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
- bdrv_set_locked(s->bdrv, buf[4] & 1);
- break;
- case 0x25:
- DPRINTF("Read Capacity\n");
- /* The normal LEN field for this command is zero. */
- memset(outbuf, 0, 8);
- bdrv_get_geometry(s->bdrv, &nb_sectors);
- /* Returned value is the address of the last sector. */
- if (nb_sectors) {
- nb_sectors--;
- outbuf[0] = (nb_sectors >> 24) & 0xff;
- outbuf[1] = (nb_sectors >> 16) & 0xff;
- outbuf[2] = (nb_sectors >> 8) & 0xff;
- outbuf[3] = nb_sectors & 0xff;
- outbuf[4] = 0;
- outbuf[5] = 0;
- outbuf[6] = s->cluster_size * 2;
- outbuf[7] = 0;
- r->buf_len = 8;
- } else {
- scsi_command_complete(r, SENSE_NOT_READY);
- return 0;
- }
- break;
- case 0x08:
- case 0x28:
- DPRINTF("Read (sector %d, count %d)\n", lba, len);
- r->sector = lba * s->cluster_size;
- r->sector_count = len * s->cluster_size;
- break;
- case 0x0a:
- case 0x2a:
- DPRINTF("Write (sector %d, count %d)\n", lba, len);
- r->sector = lba * s->cluster_size;
- r->sector_count = len * s->cluster_size;
- is_write = 1;
- break;
- case 0x35:
- DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
- bdrv_flush(s->bdrv);
- break;
- case 0x43:
- {
- int start_track, format, msf, toclen;
-
- msf = buf[1] & 2;
- format = buf[2] & 0xf;
- start_track = buf[6];
- bdrv_get_geometry(s->bdrv, &nb_sectors);
- DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
- switch(format) {
- case 0:
- toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
- break;
- case 1:
- /* multi session : only a single session defined */
- toclen = 12;
- memset(outbuf, 0, 12);
- outbuf[1] = 0x0a;
- outbuf[2] = 0x01;
- outbuf[3] = 0x01;
- break;
- case 2:
- toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
- break;
- default:
- goto error_cmd;
- }
- if (toclen > 0) {
- if (len > toclen)
- len = toclen;
- r->buf_len = len;
- break;
- }
- error_cmd:
- DPRINTF("Read TOC error\n");
- goto fail;
- }
- case 0x46:
- DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
- memset(outbuf, 0, 8);
- /* ??? This should probably return much more information. For now
- just return the basic header indicating the CD-ROM profile. */
- outbuf[7] = 8; // CD-ROM
- r->buf_len = 8;
- break;
- case 0x56:
- DPRINTF("Reserve(10)\n");
- if (buf[1] & 3)
- goto fail;
- break;
- case 0x57:
- DPRINTF("Release(10)\n");
- if (buf[1] & 3)
- goto fail;
- break;
- case 0xa0:
- DPRINTF("Report LUNs (len %d)\n", len);
- if (len < 16)
- goto fail;
- memset(outbuf, 0, 16);
- outbuf[3] = 8;
- r->buf_len = 16;
- break;
- default:
- DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
- fail:
- scsi_command_complete(r, SENSE_ILLEGAL_REQUEST);
- return 0;
- }
- if (r->sector_count == 0 && r->buf_len == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- }
- len = r->sector_count * 512 + r->buf_len;
- if (is_write) {
- return -len;
- } else {
- if (!r->sector_count)
- r->sector_count = -1;
- return len;
- }
-}
-
-static void scsi_destroy(SCSIDevice *d)
-{
- qemu_free(d->state);
- qemu_free(d);
-}
-
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
- scsi_completionfn completion, void *opaque)
-{
- SCSIDevice *d;
- SCSIDeviceState *s;
-
- s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
- s->bdrv = bdrv;
- s->tcq = tcq;
- s->completion = completion;
- s->opaque = opaque;
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- s->cluster_size = 4;
- } else {
- s->cluster_size = 1;
- }
-
- d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
- d->state = s;
- d->destroy = scsi_destroy;
- d->send_command = scsi_send_command;
- d->read_data = scsi_read_data;
- d->write_data = scsi_write_data;
- d->cancel_io = scsi_cancel_io;
- d->get_buf = scsi_get_buf;
-
- return d;
-}
diff --git a/hw/scsi-disk.h b/hw/scsi-disk.h
deleted file mode 100644
index f42212b..0000000
--- a/hw/scsi-disk.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef SCSI_DISK_H
-#define SCSI_DISK_H
-
-/* scsi-disk.c */
-enum scsi_reason {
- SCSI_REASON_DONE, /* Command complete. */
- SCSI_REASON_DATA /* Transfer complete, more data required. */
-};
-
-typedef struct SCSIDeviceState SCSIDeviceState;
-typedef struct SCSIDevice SCSIDevice;
-typedef void (*scsi_completionfn)(void *opaque, int reason, uint32_t tag,
- uint32_t arg);
-
-struct SCSIDevice
-{
- SCSIDeviceState *state;
- void (*destroy)(SCSIDevice *s);
- int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf,
- int lun);
- void (*read_data)(SCSIDevice *s, uint32_t tag);
- int (*write_data)(SCSIDevice *s, uint32_t tag);
- void (*cancel_io)(SCSIDevice *s, uint32_t tag);
- uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag);
-};
-
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
- scsi_completionfn completion, void *opaque);
-SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
- scsi_completionfn completion, void *opaque);
-
-/* cdrom.c */
-int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
-int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
-
-#endif
diff --git a/hw/sd.h b/hw/sd.h
deleted file mode 100644
index f310062..0000000
--- a/hw/sd.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * include/linux/mmc/sd.h
- *
- * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#ifndef MMC_SD_H
-#define MMC_SD_H
-
-/* SD commands type argument response */
- /* class 0 */
-/* This is basically the same command as for MMC with some quirks. */
-#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
-#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
-
- /* class 10 */
-#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
-
- /* Application commands */
-#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
-#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
-#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
-#define SD_APP_SEND_SCR 51 /* adtc R1 */
-
-/*
- * SD_SWITCH argument format:
- *
- * [31] Check (0) or switch (1)
- * [30:24] Reserved (0)
- * [23:20] Function group 6
- * [19:16] Function group 5
- * [15:12] Function group 4
- * [11:8] Function group 3
- * [7:4] Function group 2
- * [3:0] Function group 1
- */
-
-/*
- * SD_SEND_IF_COND argument format:
- *
- * [31:12] Reserved (0)
- * [11:8] Host Voltage Supply Flags
- * [7:0] Check Pattern (0xAA)
- */
-
-/*
- * SCR field definitions
- */
-
-#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
-#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
-#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */
-
-/*
- * SD bus widths
- */
-#define SD_BUS_WIDTH_1 0
-#define SD_BUS_WIDTH_4 2
-
-/*
- * SD_SWITCH mode
- */
-#define SD_SWITCH_CHECK 0
-#define SD_SWITCH_SET 1
-
-/*
- * SD_SWITCH function groups
- */
-#define SD_SWITCH_GRP_ACCESS 0
-
-/*
- * SD_SWITCH access modes
- */
-#define SD_SWITCH_ACCESS_DEF 0
-#define SD_SWITCH_ACCESS_HS 1
-
-#endif
-
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
deleted file mode 100644
index 410051d..0000000
--- a/hw/smc91c111.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
- * SMSC 91C111 Ethernet interface emulation
- *
- * Copyright (c) 2005 CodeSourcery, LLC.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL
- */
-
-#include "hw.h"
-#include "net.h"
-#include "devices.h"
-/* For crc32 */
-#include <zlib.h>
-
-/* Number of 2k memory pages available. */
-#define NUM_PACKETS 4
-
-typedef struct {
- uint32_t base;
- VLANClientState *vc;
- uint16_t tcr;
- uint16_t rcr;
- uint16_t cr;
- uint16_t ctr;
- uint16_t gpr;
- uint16_t ptr;
- uint16_t ercv;
- qemu_irq irq;
- int bank;
- int packet_num;
- int tx_alloc;
- /* Bitmask of allocated packets. */
- int allocated;
- int tx_fifo_len;
- int tx_fifo[NUM_PACKETS];
- int rx_fifo_len;
- int rx_fifo[NUM_PACKETS];
- int tx_fifo_done_len;
- int tx_fifo_done[NUM_PACKETS];
- /* Packet buffer memory. */
- uint8_t data[NUM_PACKETS][2048];
- uint8_t int_level;
- uint8_t int_mask;
- uint8_t macaddr[6];
-} smc91c111_state;
-
-#define RCR_SOFT_RST 0x8000
-#define RCR_STRIP_CRC 0x0200
-#define RCR_RXEN 0x0100
-
-#define TCR_EPH_LOOP 0x2000
-#define TCR_NOCRC 0x0100
-#define TCR_PAD_EN 0x0080
-#define TCR_FORCOL 0x0004
-#define TCR_LOOP 0x0002
-#define TCR_TXEN 0x0001
-
-#define INT_MD 0x80
-#define INT_ERCV 0x40
-#define INT_EPH 0x20
-#define INT_RX_OVRN 0x10
-#define INT_ALLOC 0x08
-#define INT_TX_EMPTY 0x04
-#define INT_TX 0x02
-#define INT_RCV 0x01
-
-#define CTR_AUTO_RELEASE 0x0800
-#define CTR_RELOAD 0x0002
-#define CTR_STORE 0x0001
-
-#define RS_ALGNERR 0x8000
-#define RS_BRODCAST 0x4000
-#define RS_BADCRC 0x2000
-#define RS_ODDFRAME 0x1000
-#define RS_TOOLONG 0x0800
-#define RS_TOOSHORT 0x0400
-#define RS_MULTICAST 0x0001
-
-/* Update interrupt status. */
-static void smc91c111_update(smc91c111_state *s)
-{
- int level;
-
- if (s->tx_fifo_len == 0)
- s->int_level |= INT_TX_EMPTY;
- if (s->tx_fifo_done_len != 0)
- s->int_level |= INT_TX;
- level = (s->int_level & s->int_mask) != 0;
- qemu_set_irq(s->irq, level);
-}
-
-/* Try to allocate a packet. Returns 0x80 on failure. */
-static int smc91c111_allocate_packet(smc91c111_state *s)
-{
- int i;
- if (s->allocated == (1 << NUM_PACKETS) - 1) {
- return 0x80;
- }
-
- for (i = 0; i < NUM_PACKETS; i++) {
- if ((s->allocated & (1 << i)) == 0)
- break;
- }
- s->allocated |= 1 << i;
- return i;
-}
-
-
-/* Process a pending TX allocate. */
-static void smc91c111_tx_alloc(smc91c111_state *s)
-{
- s->tx_alloc = smc91c111_allocate_packet(s);
- if (s->tx_alloc == 0x80)
- return;
- s->int_level |= INT_ALLOC;
- smc91c111_update(s);
-}
-
-/* Remove and item from the RX FIFO. */
-static void smc91c111_pop_rx_fifo(smc91c111_state *s)
-{
- int i;
-
- s->rx_fifo_len--;
- if (s->rx_fifo_len) {
- for (i = 0; i < s->rx_fifo_len; i++)
- s->rx_fifo[i] = s->rx_fifo[i + 1];
- s->int_level |= INT_RCV;
- } else {
- s->int_level &= ~INT_RCV;
- }
- smc91c111_update(s);
-}
-
-/* Remove an item from the TX completion FIFO. */
-static void smc91c111_pop_tx_fifo_done(smc91c111_state *s)
-{
- int i;
-
- if (s->tx_fifo_done_len == 0)
- return;
- s->tx_fifo_done_len--;
- for (i = 0; i < s->tx_fifo_done_len; i++)
- s->tx_fifo_done[i] = s->tx_fifo_done[i + 1];
-}
-
-/* Release the memory allocated to a packet. */
-static void smc91c111_release_packet(smc91c111_state *s, int packet)
-{
- s->allocated &= ~(1 << packet);
- if (s->tx_alloc == 0x80)
- smc91c111_tx_alloc(s);
-}
-
-/* Flush the TX FIFO. */
-static void smc91c111_do_tx(smc91c111_state *s)
-{
- int i;
- int len;
- int control;
- int add_crc;
- int packetnum;
- uint8_t *p;
-
- if ((s->tcr & TCR_TXEN) == 0)
- return;
- if (s->tx_fifo_len == 0)
- return;
- for (i = 0; i < s->tx_fifo_len; i++) {
- packetnum = s->tx_fifo[i];
- p = &s->data[packetnum][0];
- /* Set status word. */
- *(p++) = 0x01;
- *(p++) = 0x40;
- len = *(p++);
- len |= ((int)*(p++)) << 8;
- len -= 6;
- control = p[len + 1];
- if (control & 0x20)
- len++;
- /* ??? This overwrites the data following the buffer.
- Don't know what real hardware does. */
- if (len < 64 && (s->tcr & TCR_PAD_EN)) {
- memset(p + len, 0, 64 - len);
- len = 64;
- }
-#if 0
- /* The card is supposed to append the CRC to the frame. However
- none of the other network traffic has the CRC appended.
- Suspect this is low level ethernet detail we don't need to worry
- about. */
- add_crc = (control & 0x10) || (s->tcr & TCR_NOCRC) == 0;
- if (add_crc) {
- uint32_t crc;
-
- crc = crc32(~0, p, len);
- memcpy(p + len, &crc, 4);
- len += 4;
- }
-#else
- add_crc = 0;
-#endif
- if (s->ctr & CTR_AUTO_RELEASE)
- /* Race? */
- smc91c111_release_packet(s, packetnum);
- else if (s->tx_fifo_done_len < NUM_PACKETS)
- s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
- qemu_send_packet(s->vc, p, len);
- }
- s->tx_fifo_len = 0;
- smc91c111_update(s);
-}
-
-/* Add a packet to the TX FIFO. */
-static void smc91c111_queue_tx(smc91c111_state *s, int packet)
-{
- if (s->tx_fifo_len == NUM_PACKETS)
- return;
- s->tx_fifo[s->tx_fifo_len++] = packet;
- smc91c111_do_tx(s);
-}
-
-static void smc91c111_reset(smc91c111_state *s)
-{
- s->bank = 0;
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- s->rx_fifo_len = 0;
- s->allocated = 0;
- s->packet_num = 0;
- s->tx_alloc = 0;
- s->tcr = 0;
- s->rcr = 0;
- s->cr = 0xa0b1;
- s->ctr = 0x1210;
- s->ptr = 0;
- s->ercv = 0x1f;
- s->int_level = INT_TX_EMPTY;
- s->int_mask = 0;
- smc91c111_update(s);
-}
-
-#define SET_LOW(name, val) s->name = (s->name & 0xff00) | val
-#define SET_HIGH(name, val) s->name = (s->name & 0xff) | (val << 8)
-
-static void smc91c111_writeb(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- offset -= s->base;
- if (offset == 14) {
- s->bank = value;
- return;
- }
- if (offset == 15)
- return;
- switch (s->bank) {
- case 0:
- switch (offset) {
- case 0: /* TCR */
- SET_LOW(tcr, value);
- return;
- case 1:
- SET_HIGH(tcr, value);
- return;
- case 4: /* RCR */
- SET_LOW(rcr, value);
- return;
- case 5:
- SET_HIGH(rcr, value);
- if (s->rcr & RCR_SOFT_RST)
- smc91c111_reset(s);
- return;
- case 10: case 11: /* RPCR */
- /* Ignored */
- return;
- }
- break;
-
- case 1:
- switch (offset) {
- case 0: /* CONFIG */
- SET_LOW(cr, value);
- return;
- case 1:
- SET_HIGH(cr,value);
- return;
- case 2: case 3: /* BASE */
- case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
- /* Not implemented. */
- return;
- case 10: /* Genral Purpose */
- SET_LOW(gpr, value);
- return;
- case 11:
- SET_HIGH(gpr, value);
- return;
- case 12: /* Control */
- if (value & 1)
- fprintf(stderr, "smc91c111:EEPROM store not implemented\n");
- if (value & 2)
- fprintf(stderr, "smc91c111:EEPROM reload not implemented\n");
- value &= ~3;
- SET_LOW(ctr, value);
- return;
- case 13:
- SET_HIGH(ctr, value);
- return;
- }
- break;
-
- case 2:
- switch (offset) {
- case 0: /* MMU Command */
- switch (value >> 5) {
- case 0: /* no-op */
- break;
- case 1: /* Allocate for TX. */
- s->tx_alloc = 0x80;
- s->int_level &= ~INT_ALLOC;
- smc91c111_update(s);
- smc91c111_tx_alloc(s);
- break;
- case 2: /* Reset MMU. */
- s->allocated = 0;
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- s->rx_fifo_len = 0;
- s->tx_alloc = 0;
- break;
- case 3: /* Remove from RX FIFO. */
- smc91c111_pop_rx_fifo(s);
- break;
- case 4: /* Remove from RX FIFO and release. */
- if (s->rx_fifo_len > 0) {
- smc91c111_release_packet(s, s->rx_fifo[0]);
- }
- smc91c111_pop_rx_fifo(s);
- break;
- case 5: /* Release. */
- smc91c111_release_packet(s, s->packet_num);
- break;
- case 6: /* Add to TX FIFO. */
- smc91c111_queue_tx(s, s->packet_num);
- break;
- case 7: /* Reset TX FIFO. */
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- break;
- }
- return;
- case 1:
- /* Ignore. */
- return;
- case 2: /* Packet Number Register */
- s->packet_num = value;
- return;
- case 3: case 4: case 5:
- /* Should be readonly, but linux writes to them anyway. Ignore. */
- return;
- case 6: /* Pointer */
- SET_LOW(ptr, value);
- return;
- case 7:
- SET_HIGH(ptr, value);
- return;
- case 8: case 9: case 10: case 11: /* Data */
- {
- int p;
- int n;
-
- if (s->ptr & 0x8000)
- n = s->rx_fifo[0];
- else
- n = s->packet_num;
- p = s->ptr & 0x07ff;
- if (s->ptr & 0x4000) {
- s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x7ff);
- } else {
- p += (offset & 3);
- }
- s->data[n][p] = value;
- }
- return;
- case 12: /* Interrupt ACK. */
- s->int_level &= ~(value & 0xd6);
- if (value & INT_TX)
- smc91c111_pop_tx_fifo_done(s);
- smc91c111_update(s);
- return;
- case 13: /* Interrupt mask. */
- s->int_mask = value;
- smc91c111_update(s);
- return;
- }
- break;;
-
- case 3:
- switch (offset) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- /* Multicast table. */
- /* Not implemented. */
- return;
- case 8: case 9: /* Management Interface. */
- /* Not implemented. */
- return;
- case 12: /* Early receive. */
- s->ercv = value & 0x1f;
- case 13:
- /* Ignore. */
- return;
- }
- break;
- }
- cpu_abort (cpu_single_env, "smc91c111_write: Bad reg %d:%x\n",
- s->bank, (int)offset);
-}
-
-static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- offset -= s->base;
- if (offset == 14) {
- return s->bank;
- }
- if (offset == 15)
- return 0x33;
- switch (s->bank) {
- case 0:
- switch (offset) {
- case 0: /* TCR */
- return s->tcr & 0xff;
- case 1:
- return s->tcr >> 8;
- case 2: /* EPH Status */
- return 0;
- case 3:
- return 0x40;
- case 4: /* RCR */
- return s->rcr & 0xff;
- case 5:
- return s->rcr >> 8;
- case 6: /* Counter */
- case 7:
- /* Not implemented. */
- return 0;
- case 8: /* Memory size. */
- return NUM_PACKETS;
- case 9: /* Free memory available. */
- {
- int i;
- int n;
- n = 0;
- for (i = 0; i < NUM_PACKETS; i++) {
- if (s->allocated & (1 << i))
- n++;
- }
- return n;
- }
- case 10: case 11: /* RPCR */
- /* Not implemented. */
- return 0;
- }
- break;
-
- case 1:
- switch (offset) {
- case 0: /* CONFIG */
- return s->cr & 0xff;
- case 1:
- return s->cr >> 8;
- case 2: case 3: /* BASE */
- /* Not implemented. */
- return 0;
- case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
- return s->macaddr[offset - 4];
- case 10: /* General Purpose */
- return s->gpr & 0xff;
- case 11:
- return s->gpr >> 8;
- case 12: /* Control */
- return s->ctr & 0xff;
- case 13:
- return s->ctr >> 8;
- }
- break;
-
- case 2:
- switch (offset) {
- case 0: case 1: /* MMUCR Busy bit. */
- return 0;
- case 2: /* Packet Number. */
- return s->packet_num;
- case 3: /* Allocation Result. */
- return s->tx_alloc;
- case 4: /* TX FIFO */
- if (s->tx_fifo_done_len == 0)
- return 0x80;
- else
- return s->tx_fifo_done[0];
- case 5: /* RX FIFO */
- if (s->rx_fifo_len == 0)
- return 0x80;
- else
- return s->rx_fifo[0];
- case 6: /* Pointer */
- return s->ptr & 0xff;
- case 7:
- return (s->ptr >> 8) & 0xf7;
- case 8: case 9: case 10: case 11: /* Data */
- {
- int p;
- int n;
-
- if (s->ptr & 0x8000)
- n = s->rx_fifo[0];
- else
- n = s->packet_num;
- p = s->ptr & 0x07ff;
- if (s->ptr & 0x4000) {
- s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x07ff);
- } else {
- p += (offset & 3);
- }
- return s->data[n][p];
- }
- case 12: /* Interrupt status. */
- return s->int_level;
- case 13: /* Interrupt mask. */
- return s->int_mask;
- }
- break;
-
- case 3:
- switch (offset) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- /* Multicast table. */
- /* Not implemented. */
- return 0;
- case 8: /* Management Interface. */
- /* Not implemented. */
- return 0x30;
- case 9:
- return 0x33;
- case 10: /* Revision. */
- return 0x91;
- case 11:
- return 0x33;
- case 12:
- return s->ercv;
- case 13:
- return 0;
- }
- break;
- }
- cpu_abort (cpu_single_env, "smc91c111_read: Bad reg %d:%x\n",
- s->bank, (int)offset);
- return 0;
-}
-
-static void smc91c111_writew(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_writeb(opaque, offset, value & 0xff);
- smc91c111_writeb(opaque, offset + 1, value >> 8);
-}
-
-static void smc91c111_writel(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
- /* 32-bit writes to offset 0xc only actually write to the bank select
- register (offset 0xe) */
- if (offset != s->base + 0xc)
- smc91c111_writew(opaque, offset, value & 0xffff);
- smc91c111_writew(opaque, offset + 2, value >> 16);
-}
-
-static uint32_t smc91c111_readw(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = smc91c111_readb(opaque, offset);
- val |= smc91c111_readb(opaque, offset + 1) << 8;
- return val;
-}
-
-static uint32_t smc91c111_readl(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = smc91c111_readw(opaque, offset);
- val |= smc91c111_readw(opaque, offset + 2) << 16;
- return val;
-}
-
-static int smc91c111_can_receive(void *opaque)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
- return 1;
- if (s->allocated == (1 << NUM_PACKETS) - 1)
- return 0;
- return 1;
-}
-
-static void smc91c111_receive(void *opaque, const uint8_t *buf, int size)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
- int status;
- int packetsize;
- uint32_t crc;
- int packetnum;
- uint8_t *p;
-
- if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
- return;
- /* Short packets are padded with zeros. Receiving a packet
- < 64 bytes long is considered an error condition. */
- if (size < 64)
- packetsize = 64;
- else
- packetsize = (size & ~1);
- packetsize += 6;
- crc = (s->rcr & RCR_STRIP_CRC) == 0;
- if (crc)
- packetsize += 4;
- /* TODO: Flag overrun and receive errors. */
- if (packetsize > 2048)
- return;
- packetnum = smc91c111_allocate_packet(s);
- if (packetnum == 0x80)
- return;
- s->rx_fifo[s->rx_fifo_len++] = packetnum;
-
- p = &s->data[packetnum][0];
- /* ??? Multicast packets? */
- status = 0;
- if (size > 1518)
- status |= RS_TOOLONG;
- if (size & 1)
- status |= RS_ODDFRAME;
- *(p++) = status & 0xff;
- *(p++) = status >> 8;
- *(p++) = packetsize & 0xff;
- *(p++) = packetsize >> 8;
- memcpy(p, buf, size & ~1);
- p += (size & ~1);
- /* Pad short packets. */
- if (size < 64) {
- int pad;
-
- if (size & 1)
- *(p++) = buf[size - 1];
- pad = 64 - size;
- memset(p, 0, pad);
- p += pad;
- size = 64;
- }
- /* It's not clear if the CRC should go before or after the last byte in
- odd sized packets. Linux disables the CRC, so that's no help.
- The pictures in the documentation show the CRC aligned on a 16-bit
- boundary before the last odd byte, so that's what we do. */
- if (crc) {
- crc = crc32(~0, buf, size);
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- }
- if (size & 1) {
- *(p++) = buf[size - 1];
- *(p++) = 0x60;
- } else {
- *(p++) = 0;
- *(p++) = 0x40;
- }
- /* TODO: Raise early RX interrupt? */
- s->int_level |= INT_RCV;
- smc91c111_update(s);
-}
-
-static CPUReadMemoryFunc *smc91c111_readfn[] = {
- smc91c111_readb,
- smc91c111_readw,
- smc91c111_readl
-};
-
-static CPUWriteMemoryFunc *smc91c111_writefn[] = {
- smc91c111_writeb,
- smc91c111_writew,
- smc91c111_writel
-};
-
-void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
-{
- smc91c111_state *s;
- int iomemtype;
-
- s = (smc91c111_state *)qemu_mallocz(sizeof(smc91c111_state));
- iomemtype = cpu_register_io_memory(0, smc91c111_readfn,
- smc91c111_writefn, s);
- cpu_register_physical_memory(base, 16, iomemtype);
- s->base = base;
- s->irq = irq;
- memcpy(s->macaddr, nd->macaddr, 6);
-
- smc91c111_reset(s);
-
- s->vc = qemu_new_vlan_client(nd->vlan, smc91c111_receive,
- smc91c111_can_receive, s);
- /* ??? Save/restore. */
-}
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
deleted file mode 100644
index 406c9ab..0000000
--- a/hw/usb-hid.c
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- * QEMU USB HID devices
- *
- * Copyright (c) 2005 Fabrice Bellard
- * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw.h"
-#include "console.h"
-#include "usb.h"
-
-/* HID interface requests */
-#define GET_REPORT 0xa101
-#define GET_IDLE 0xa102
-#define GET_PROTOCOL 0xa103
-#define SET_REPORT 0x2109
-#define SET_IDLE 0x210a
-#define SET_PROTOCOL 0x210b
-
-/* HID descriptor types */
-#define USB_DT_HID 0x21
-#define USB_DT_REPORT 0x22
-#define USB_DT_PHY 0x23
-
-#define USB_MOUSE 1
-#define USB_TABLET 2
-#define USB_KEYBOARD 3
-
-typedef struct USBMouseState {
- int dx, dy, dz, buttons_state;
- int x, y;
- int mouse_grabbed;
- QEMUPutMouseEntry *eh_entry;
-} USBMouseState;
-
-typedef struct USBKeyboardState {
- uint16_t modifiers;
- uint8_t leds;
- uint8_t key[16];
- int keys;
-} USBKeyboardState;
-
-typedef struct USBHIDState {
- USBDevice dev;
- union {
- USBMouseState ptr;
- USBKeyboardState kbd;
- };
- int kind;
- int protocol;
- int idle;
- int changed;
-} USBHIDState;
-
-/* mostly the same values as the Bochs USB Mouse device */
-static const uint8_t qemu_mouse_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x00, 0x01, /* u16 bcdUSB; v1.0 */
-
- 0x00, /* u8 bDeviceClass; */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x27, 0x06, /* u16 idVendor; */
- 0x01, 0x00, /* u16 idProduct; */
- 0x00, 0x00, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-static const uint8_t qemu_mouse_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x04, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 50, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; */
- 0x01, /* u8 if_bInterfaceSubClass; */
- 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x07, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- 0x21, /* u8 bDescriptorType; */
- 0x01, 0x00, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- 0x22, /* u8 type; Report */
- 52, 0, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x04, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_tablet_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x05, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 50, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; */
- 0x01, /* u8 if_bInterfaceSubClass; */
- 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x07, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- 0x21, /* u8 bDescriptorType; */
- 0x01, 0x00, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- 0x22, /* u8 type; Report */
- 74, 0, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_keyboard_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- USB_DT_CONFIG, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x06, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x32, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- USB_DT_INTERFACE, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; HID */
- 0x01, /* u8 if_bInterfaceSubClass; Boot */
- 0x01, /* u8 if_bInterfaceProtocol; Keyboard */
- 0x07, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- USB_DT_HID, /* u8 bDescriptorType; */
- 0x11, 0x01, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- USB_DT_REPORT, /* u8 type; Report */
- 0x3f, 0x00, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; Endpoint */
- USB_DIR_IN | 0x01, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_mouse_hid_report_descriptor[] = {
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x02, /* Usage (Mouse) */
- 0xa1, 0x01, /* Collection (Application) */
- 0x09, 0x01, /* Usage (Pointer) */
- 0xa1, 0x00, /* Collection (Physical) */
- 0x05, 0x09, /* Usage Page (Button) */
- 0x19, 0x01, /* Usage Minimum (1) */
- 0x29, 0x03, /* Usage Maximum (3) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x01, /* Logical Maximum (1) */
- 0x95, 0x03, /* Report Count (3) */
- 0x75, 0x01, /* Report Size (1) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute) */
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x05, /* Report Size (5) */
- 0x81, 0x01, /* Input (Constant) */
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x30, /* Usage (X) */
- 0x09, 0x31, /* Usage (Y) */
- 0x09, 0x38, /* Usage (Wheel) */
- 0x15, 0x81, /* Logical Minimum (-0x7f) */
- 0x25, 0x7f, /* Logical Maximum (0x7f) */
- 0x75, 0x08, /* Report Size (8) */
- 0x95, 0x03, /* Report Count (3) */
- 0x81, 0x06, /* Input (Data, Variable, Relative) */
- 0xc0, /* End Collection */
- 0xc0, /* End Collection */
-};
-
-static const uint8_t qemu_tablet_hid_report_descriptor[] = {
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x01, /* Usage (Pointer) */
- 0xa1, 0x01, /* Collection (Application) */
- 0x09, 0x01, /* Usage (Pointer) */
- 0xa1, 0x00, /* Collection (Physical) */
- 0x05, 0x09, /* Usage Page (Button) */
- 0x19, 0x01, /* Usage Minimum (1) */
- 0x29, 0x03, /* Usage Maximum (3) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x01, /* Logical Maximum (1) */
- 0x95, 0x03, /* Report Count (3) */
- 0x75, 0x01, /* Report Size (1) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute) */
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x05, /* Report Size (5) */
- 0x81, 0x01, /* Input (Constant) */
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x30, /* Usage (X) */
- 0x09, 0x31, /* Usage (Y) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */
- 0x35, 0x00, /* Physical Minimum (0) */
- 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */
- 0x75, 0x10, /* Report Size (16) */
- 0x95, 0x02, /* Report Count (2) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute) */
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x38, /* Usage (Wheel) */
- 0x15, 0x81, /* Logical Minimum (-0x7f) */
- 0x25, 0x7f, /* Logical Maximum (0x7f) */
- 0x35, 0x00, /* Physical Minimum (same as logical) */
- 0x45, 0x00, /* Physical Maximum (same as logical) */
- 0x75, 0x08, /* Report Size (8) */
- 0x95, 0x01, /* Report Count (1) */
- 0x81, 0x06, /* Input (Data, Variable, Relative) */
- 0xc0, /* End Collection */
- 0xc0, /* End Collection */
-};
-
-static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x06, /* Usage (Keyboard) */
- 0xa1, 0x01, /* Collection (Application) */
- 0x75, 0x01, /* Report Size (1) */
- 0x95, 0x08, /* Report Count (8) */
- 0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0xe0, /* Usage Minimum (224) */
- 0x29, 0xe7, /* Usage Maximum (231) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x01, /* Logical Maximum (1) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute) */
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x08, /* Report Size (8) */
- 0x81, 0x01, /* Input (Constant) */
- 0x95, 0x05, /* Report Count (5) */
- 0x75, 0x01, /* Report Size (1) */
- 0x05, 0x08, /* Usage Page (LEDs) */
- 0x19, 0x01, /* Usage Minimum (1) */
- 0x29, 0x05, /* Usage Maximum (5) */
- 0x91, 0x02, /* Output (Data, Variable, Absolute) */
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x03, /* Report Size (3) */
- 0x91, 0x01, /* Output (Constant) */
- 0x95, 0x06, /* Report Count (6) */
- 0x75, 0x08, /* Report Size (8) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0xff, /* Logical Maximum (255) */
- 0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0x00, /* Usage Minimum (0) */
- 0x29, 0xff, /* Usage Maximum (255) */
- 0x81, 0x00, /* Input (Data, Array) */
- 0xc0, /* End Collection */
-};
-
-#define USB_HID_USAGE_ERROR_ROLLOVER 0x01
-#define USB_HID_USAGE_POSTFAIL 0x02
-#define USB_HID_USAGE_ERROR_UNDEFINED 0x03
-
-/* Indices are QEMU keycodes, values are from HID Usage Table. Indices
- * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
-static const uint8_t usb_hid_usage_keys[0x100] = {
- 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
- 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
- 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
- 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
- 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
- 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
- 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
- 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
- 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
- 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
- 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
- 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
- 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
- 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
- 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-static void usb_mouse_event(void *opaque,
- int dx1, int dy1, int dz1, int buttons_state)
-{
- USBHIDState *hs = opaque;
- USBMouseState *s = &hs->ptr;
-
- s->dx += dx1;
- s->dy += dy1;
- s->dz += dz1;
- s->buttons_state = buttons_state;
- hs->changed = 1;
-}
-
-static void usb_tablet_event(void *opaque,
- int x, int y, int dz, int buttons_state)
-{
- USBHIDState *hs = opaque;
- USBMouseState *s = &hs->ptr;
-
- s->x = x;
- s->y = y;
- s->dz += dz;
- s->buttons_state = buttons_state;
- hs->changed = 1;
-}
-
-static void usb_keyboard_event(void *opaque, int keycode)
-{
- USBHIDState *hs = opaque;
- USBKeyboardState *s = &hs->kbd;
- uint8_t hid_code, key;
- int i;
-
- key = keycode & 0x7f;
- hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
- s->modifiers &= ~(1 << 8);
-
- hs->changed = 1;
-
- switch (hid_code) {
- case 0x00:
- return;
-
- case 0xe0:
- if (s->modifiers & (1 << 9)) {
- s->modifiers ^= 3 << 8;
- return;
- }
- case 0xe1 ... 0xe7:
- if (keycode & (1 << 7)) {
- s->modifiers &= ~(1 << (hid_code & 0x0f));
- return;
- }
- case 0xe8 ... 0xef:
- s->modifiers |= 1 << (hid_code & 0x0f);
- return;
- }
-
- if (keycode & (1 << 7)) {
- for (i = s->keys - 1; i >= 0; i --)
- if (s->key[i] == hid_code) {
- s->key[i] = s->key[-- s->keys];
- s->key[s->keys] = 0x00;
- return;
- }
- } else {
- for (i = s->keys - 1; i >= 0; i --)
- if (s->key[i] == hid_code)
- return;
- if (s->keys < sizeof(s->key))
- s->key[s->keys ++] = hid_code;
- }
-}
-
-static inline int int_clamp(int val, int vmin, int vmax)
-{
- if (val < vmin)
- return vmin;
- else if (val > vmax)
- return vmax;
- else
- return val;
-}
-
-static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
-{
- int dx, dy, dz, b, l;
- USBMouseState *s = &hs->ptr;
-
- if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
- 0, "QEMU USB Mouse");
- s->mouse_grabbed = 1;
- }
-
- dx = int_clamp(s->dx, -127, 127);
- dy = int_clamp(s->dy, -127, 127);
- dz = int_clamp(s->dz, -127, 127);
-
- s->dx -= dx;
- s->dy -= dy;
- s->dz -= dz;
-
- /* Appears we have to invert the wheel direction */
- dz = 0 - dz;
-
- b = 0;
- if (s->buttons_state & MOUSE_EVENT_LBUTTON)
- b |= 0x01;
- if (s->buttons_state & MOUSE_EVENT_RBUTTON)
- b |= 0x02;
- if (s->buttons_state & MOUSE_EVENT_MBUTTON)
- b |= 0x04;
-
- l = 0;
- if (len > l)
- buf[l ++] = b;
- if (len > l)
- buf[l ++] = dx;
- if (len > l)
- buf[l ++] = dy;
- if (len > l)
- buf[l ++] = dz;
- return l;
-}
-
-static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
-{
- int dz, b, l;
- USBMouseState *s = &hs->ptr;
-
- if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
- 1, "QEMU USB Tablet");
- s->mouse_grabbed = 1;
- }
-
- dz = int_clamp(s->dz, -127, 127);
- s->dz -= dz;
-
- /* Appears we have to invert the wheel direction */
- dz = 0 - dz;
- b = 0;
- if (s->buttons_state & MOUSE_EVENT_LBUTTON)
- b |= 0x01;
- if (s->buttons_state & MOUSE_EVENT_RBUTTON)
- b |= 0x02;
- if (s->buttons_state & MOUSE_EVENT_MBUTTON)
- b |= 0x04;
-
- buf[0] = b;
- buf[1] = s->x & 0xff;
- buf[2] = s->x >> 8;
- buf[3] = s->y & 0xff;
- buf[4] = s->y >> 8;
- buf[5] = dz;
- l = 6;
-
- return l;
-}
-
-static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
-{
- if (len < 2)
- return 0;
-
- buf[0] = s->modifiers & 0xff;
- buf[1] = 0;
- if (s->keys > 6)
- memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
- else
- memcpy(buf + 2, s->key, MIN(8, len) - 2);
-
- return MIN(8, len);
-}
-
-static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
-{
- if (len > 0) {
- /* 0x01: Num Lock LED
- * 0x02: Caps Lock LED
- * 0x04: Scroll Lock LED
- * 0x08: Compose LED
- * 0x10: Kana LED */
- s->leds = buf[0];
- }
- return 0;
-}
-
-static void usb_mouse_handle_reset(USBDevice *dev)
-{
- USBHIDState *s = (USBHIDState *)dev;
-
- s->ptr.dx = 0;
- s->ptr.dy = 0;
- s->ptr.dz = 0;
- s->ptr.x = 0;
- s->ptr.y = 0;
- s->ptr.buttons_state = 0;
- s->protocol = 1;
-}
-
-static void usb_keyboard_handle_reset(USBDevice *dev)
-{
- USBHIDState *s = (USBHIDState *)dev;
-
- qemu_add_kbd_event_handler(usb_keyboard_event, s);
- s->protocol = 1;
-}
-
-static int usb_hid_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- USBHIDState *s = (USBHIDState *)dev;
- int ret = 0;
-
- switch(request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_mouse_dev_descriptor,
- sizeof(qemu_mouse_dev_descriptor));
- ret = sizeof(qemu_mouse_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_config_descriptor,
- sizeof(qemu_mouse_config_descriptor));
- ret = sizeof(qemu_mouse_config_descriptor);
- } else if (s->kind == USB_TABLET) {
- memcpy(data, qemu_tablet_config_descriptor,
- sizeof(qemu_tablet_config_descriptor));
- ret = sizeof(qemu_tablet_config_descriptor);
- } else if (s->kind == USB_KEYBOARD) {
- memcpy(data, qemu_keyboard_config_descriptor,
- sizeof(qemu_keyboard_config_descriptor));
- ret = sizeof(qemu_keyboard_config_descriptor);
- }
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* serial number */
- ret = set_usb_string(data, "1");
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, s->dev.devname);
- break;
- case 3:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- case 4:
- ret = set_usb_string(data, "HID Mouse");
- break;
- case 5:
- ret = set_usb_string(data, "HID Tablet");
- break;
- case 6:
- ret = set_usb_string(data, "HID Keyboard");
- break;
- case 7:
- ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- /* hid specific requests */
- case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case 0x22:
- if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_hid_report_descriptor,
- sizeof(qemu_mouse_hid_report_descriptor));
- ret = sizeof(qemu_mouse_hid_report_descriptor);
- } else if (s->kind == USB_TABLET) {
- memcpy(data, qemu_tablet_hid_report_descriptor,
- sizeof(qemu_tablet_hid_report_descriptor));
- ret = sizeof(qemu_tablet_hid_report_descriptor);
- } else if (s->kind == USB_KEYBOARD) {
- memcpy(data, qemu_keyboard_hid_report_descriptor,
- sizeof(qemu_keyboard_hid_report_descriptor));
- ret = sizeof(qemu_keyboard_hid_report_descriptor);
- }
- break;
- default:
- goto fail;
- }
- break;
- case GET_REPORT:
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, data, length);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, data, length);
- else if (s->kind == USB_KEYBOARD)
- ret = usb_keyboard_poll(&s->kbd, data, length);
- break;
- case SET_REPORT:
- if (s->kind == USB_KEYBOARD)
- ret = usb_keyboard_write(&s->kbd, data, length);
- else
- goto fail;
- break;
- case GET_PROTOCOL:
- if (s->kind != USB_KEYBOARD)
- goto fail;
- ret = 1;
- data[0] = s->protocol;
- break;
- case SET_PROTOCOL:
- if (s->kind != USB_KEYBOARD)
- goto fail;
- ret = 0;
- s->protocol = value;
- break;
- case GET_IDLE:
- ret = 1;
- data[0] = s->idle;
- break;
- case SET_IDLE:
- s->idle = value;
- ret = 0;
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
-{
- USBHIDState *s = (USBHIDState *)dev;
- int ret = 0;
-
- switch(p->pid) {
- case USB_TOKEN_IN:
- if (p->devep == 1) {
- /* TODO: Implement finite idle delays. */
- if (!(s->changed || s->idle))
- return USB_RET_NAK;
- s->changed = 0;
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, p->data, p->len);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, p->data, p->len);
- else if (s->kind == USB_KEYBOARD)
- ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
- } else {
- goto fail;
- }
- break;
- case USB_TOKEN_OUT:
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static void usb_hid_handle_destroy(USBDevice *dev)
-{
- USBHIDState *s = (USBHIDState *)dev;
-
- if (s->kind != USB_KEYBOARD)
- qemu_remove_mouse_event_handler(s->ptr.eh_entry);
- /* TODO: else */
- qemu_free(s);
-}
-
-USBDevice *usb_tablet_init(void)
-{
- USBHIDState *s;
-
- s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_mouse_handle_reset;
- s->dev.handle_control = usb_hid_handle_control;
- s->dev.handle_data = usb_hid_handle_data;
- s->dev.handle_destroy = usb_hid_handle_destroy;
- s->kind = USB_TABLET;
- /* Force poll routine to be run and grab input the first time. */
- s->changed = 1;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
-
- return (USBDevice *)s;
-}
-
-USBDevice *usb_mouse_init(void)
-{
- USBHIDState *s;
-
- s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_mouse_handle_reset;
- s->dev.handle_control = usb_hid_handle_control;
- s->dev.handle_data = usb_hid_handle_data;
- s->dev.handle_destroy = usb_hid_handle_destroy;
- s->kind = USB_MOUSE;
- /* Force poll routine to be run and grab input the first time. */
- s->changed = 1;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
-
- return (USBDevice *)s;
-}
-
-USBDevice *usb_keyboard_init(void)
-{
- USBHIDState *s;
-
- s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_keyboard_handle_reset;
- s->dev.handle_control = usb_hid_handle_control;
- s->dev.handle_data = usb_hid_handle_data;
- s->dev.handle_destroy = usb_hid_handle_destroy;
- s->kind = USB_KEYBOARD;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Keyboard");
-
- return (USBDevice *) s;
-}
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
deleted file mode 100644
index 97c3d05..0000000
--- a/hw/usb-hub.c
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * QEMU USB HUB emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "usb.h"
-
-//#define DEBUG
-
-#define MAX_PORTS 8
-
-typedef struct USBHubPort {
- USBPort port;
- uint16_t wPortStatus;
- uint16_t wPortChange;
-} USBHubPort;
-
-typedef struct USBHubState {
- USBDevice dev;
- int nb_ports;
- USBHubPort ports[MAX_PORTS];
-} USBHubState;
-
-#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
-#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
-#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
-#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
-#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
-#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
-#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
-
-#define PORT_STAT_CONNECTION 0x0001
-#define PORT_STAT_ENABLE 0x0002
-#define PORT_STAT_SUSPEND 0x0004
-#define PORT_STAT_OVERCURRENT 0x0008
-#define PORT_STAT_RESET 0x0010
-#define PORT_STAT_POWER 0x0100
-#define PORT_STAT_LOW_SPEED 0x0200
-#define PORT_STAT_HIGH_SPEED 0x0400
-#define PORT_STAT_TEST 0x0800
-#define PORT_STAT_INDICATOR 0x1000
-
-#define PORT_STAT_C_CONNECTION 0x0001
-#define PORT_STAT_C_ENABLE 0x0002
-#define PORT_STAT_C_SUSPEND 0x0004
-#define PORT_STAT_C_OVERCURRENT 0x0008
-#define PORT_STAT_C_RESET 0x0010
-
-#define PORT_CONNECTION 0
-#define PORT_ENABLE 1
-#define PORT_SUSPEND 2
-#define PORT_OVERCURRENT 3
-#define PORT_RESET 4
-#define PORT_POWER 8
-#define PORT_LOWSPEED 9
-#define PORT_HIGHSPEED 10
-#define PORT_C_CONNECTION 16
-#define PORT_C_ENABLE 17
-#define PORT_C_SUSPEND 18
-#define PORT_C_OVERCURRENT 19
-#define PORT_C_RESET 20
-#define PORT_TEST 21
-#define PORT_INDICATOR 22
-
-/* same as Linux kernel root hubs */
-
-static const uint8_t qemu_hub_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x10, 0x01, /* u16 bcdUSB; v1.1 */
-
- 0x09, /* u8 bDeviceClass; HUB_CLASSCODE */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x00, 0x00, /* u16 idVendor; */
- 0x00, 0x00, /* u16 idProduct; */
- 0x01, 0x01, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-/* XXX: patch interrupt size */
-static const uint8_t qemu_hub_config_descriptor[] = {
-
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x19, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x00, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */
- 0x00, /* u8 if_bInterfaceSubClass; */
- 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x00, /* u8 if_iInterface; */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
- 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_hub_hub_descriptor[] =
-{
- 0x00, /* u8 bLength; patched in later */
- 0x29, /* u8 bDescriptorType; Hub-descriptor */
- 0x00, /* u8 bNbrPorts; (patched later) */
- 0x0a, /* u16 wHubCharacteristics; */
- 0x00, /* (per-port OC, no power switching) */
- 0x01, /* u8 bPwrOn2pwrGood; 2ms */
- 0x00 /* u8 bHubContrCurrent; 0 mA */
-
- /* DeviceRemovable and PortPwrCtrlMask patched in later */
-};
-
-static void usb_hub_attach(USBPort *port1, USBDevice *dev)
-{
- USBHubState *s = port1->opaque;
- USBHubPort *port = &s->ports[port1->index];
-
- if (dev) {
- if (port->port.dev)
- usb_attach(port1, NULL);
-
- port->wPortStatus |= PORT_STAT_CONNECTION;
- port->wPortChange |= PORT_STAT_C_CONNECTION;
- if (dev->speed == USB_SPEED_LOW)
- port->wPortStatus |= PORT_STAT_LOW_SPEED;
- else
- port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
- port->port.dev = dev;
- /* send the attach message */
- usb_send_msg(dev, USB_MSG_ATTACH);
- } else {
- dev = port->port.dev;
- if (dev) {
- port->wPortStatus &= ~PORT_STAT_CONNECTION;
- port->wPortChange |= PORT_STAT_C_CONNECTION;
- if (port->wPortStatus & PORT_STAT_ENABLE) {
- port->wPortStatus &= ~PORT_STAT_ENABLE;
- port->wPortChange |= PORT_STAT_C_ENABLE;
- }
- /* send the detach message */
- usb_send_msg(dev, USB_MSG_DETACH);
- port->port.dev = NULL;
- }
- }
-}
-
-static void usb_hub_handle_reset(USBDevice *dev)
-{
- /* XXX: do it */
-}
-
-static int usb_hub_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- USBHubState *s = (USBHubState *)dev;
- int ret;
-
- switch(request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == 0 && index != 0x81) { /* clear ep halt */
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_hub_dev_descriptor,
- sizeof(qemu_hub_dev_descriptor));
- ret = sizeof(qemu_hub_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- memcpy(data, qemu_hub_config_descriptor,
- sizeof(qemu_hub_config_descriptor));
-
- /* status change endpoint size based on number
- * of ports */
- data[22] = (s->nb_ports + 1 + 7) / 8;
-
- ret = sizeof(qemu_hub_config_descriptor);
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* serial number */
- ret = set_usb_string(data, "314159");
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, "QEMU USB Hub");
- break;
- case 3:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- /* usb specific requests */
- case GetHubStatus:
- data[0] = 0;
- data[1] = 0;
- data[2] = 0;
- data[3] = 0;
- ret = 4;
- break;
- case GetPortStatus:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- data[0] = port->wPortStatus;
- data[1] = port->wPortStatus >> 8;
- data[2] = port->wPortChange;
- data[3] = port->wPortChange >> 8;
- ret = 4;
- }
- break;
- case SetHubFeature:
- case ClearHubFeature:
- if (value == 0 || value == 1) {
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case SetPortFeature:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- USBDevice *dev;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- dev = port->port.dev;
- switch(value) {
- case PORT_SUSPEND:
- port->wPortStatus |= PORT_STAT_SUSPEND;
- break;
- case PORT_RESET:
- if (dev) {
- usb_send_msg(dev, USB_MSG_RESET);
- port->wPortChange |= PORT_STAT_C_RESET;
- /* set enable bit */
- port->wPortStatus |= PORT_STAT_ENABLE;
- }
- break;
- case PORT_POWER:
- break;
- default:
- goto fail;
- }
- ret = 0;
- }
- break;
- case ClearPortFeature:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- USBDevice *dev;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- dev = port->port.dev;
- switch(value) {
- case PORT_ENABLE:
- port->wPortStatus &= ~PORT_STAT_ENABLE;
- break;
- case PORT_C_ENABLE:
- port->wPortChange &= ~PORT_STAT_C_ENABLE;
- break;
- case PORT_SUSPEND:
- port->wPortStatus &= ~PORT_STAT_SUSPEND;
- break;
- case PORT_C_SUSPEND:
- port->wPortChange &= ~PORT_STAT_C_SUSPEND;
- break;
- case PORT_C_CONNECTION:
- port->wPortChange &= ~PORT_STAT_C_CONNECTION;
- break;
- case PORT_C_OVERCURRENT:
- port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
- break;
- case PORT_C_RESET:
- port->wPortChange &= ~PORT_STAT_C_RESET;
- break;
- default:
- goto fail;
- }
- ret = 0;
- }
- break;
- case GetHubDescriptor:
- {
- unsigned int n, limit, var_hub_size = 0;
- memcpy(data, qemu_hub_hub_descriptor,
- sizeof(qemu_hub_hub_descriptor));
- data[2] = s->nb_ports;
-
- /* fill DeviceRemovable bits */
- limit = ((s->nb_ports + 1 + 7) / 8) + 7;
- for (n = 7; n < limit; n++) {
- data[n] = 0x00;
- var_hub_size++;
- }
-
- /* fill PortPwrCtrlMask bits */
- limit = limit + ((s->nb_ports + 7) / 8);
- for (;n < limit; n++) {
- data[n] = 0xff;
- var_hub_size++;
- }
-
- ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
- data[0] = ret;
- break;
- }
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hub_handle_data(USBDevice *dev, USBPacket *p)
-{
- USBHubState *s = (USBHubState *)dev;
- int ret;
-
- switch(p->pid) {
- case USB_TOKEN_IN:
- if (p->devep == 1) {
- USBHubPort *port;
- unsigned int status;
- int i, n;
- n = (s->nb_ports + 1 + 7) / 8;
- if (p->len == 1) { /* FreeBSD workaround */
- n = 1;
- } else if (n > p->len) {
- return USB_RET_BABBLE;
- }
- status = 0;
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- if (port->wPortChange)
- status |= (1 << (i + 1));
- }
- if (status != 0) {
- for(i = 0; i < n; i++) {
- p->data[i] = status >> (8 * i);
- }
- ret = n;
- } else {
- ret = USB_RET_NAK; /* usb11 11.13.1 */
- }
- } else {
- goto fail;
- }
- break;
- case USB_TOKEN_OUT:
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p)
-{
- USBHubPort *port;
- USBDevice *dev;
- int i, ret;
-
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- dev = port->port.dev;
- if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
- ret = dev->handle_packet(dev, p);
- if (ret != USB_RET_NODEV) {
- return ret;
- }
- }
- }
- return USB_RET_NODEV;
-}
-
-static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p)
-{
- USBHubState *s = (USBHubState *)dev;
-
-#if defined(DEBUG) && 0
- printf("usb_hub: pid=0x%x\n", pid);
-#endif
- if (dev->state == USB_STATE_DEFAULT &&
- dev->addr != 0 &&
- p->devaddr != dev->addr &&
- (p->pid == USB_TOKEN_SETUP ||
- p->pid == USB_TOKEN_OUT ||
- p->pid == USB_TOKEN_IN)) {
- /* broadcast the packet to the devices */
- return usb_hub_broadcast_packet(s, p);
- }
- return usb_generic_handle_packet(dev, p);
-}
-
-static void usb_hub_handle_destroy(USBDevice *dev)
-{
- USBHubState *s = (USBHubState *)dev;
-
- qemu_free(s);
-}
-
-USBDevice *usb_hub_init(int nb_ports)
-{
- USBHubState *s;
- USBHubPort *port;
- int i;
-
- if (nb_ports > MAX_PORTS)
- return NULL;
- s = qemu_mallocz(sizeof(USBHubState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_hub_handle_packet;
-
- /* generic USB device init */
- s->dev.handle_reset = usb_hub_handle_reset;
- s->dev.handle_control = usb_hub_handle_control;
- s->dev.handle_data = usb_hub_handle_data;
- s->dev.handle_destroy = usb_hub_handle_destroy;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Hub");
-
- s->nb_ports = nb_ports;
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- qemu_register_usb_port(&port->port, s, i, usb_hub_attach);
- port->wPortStatus = PORT_STAT_POWER;
- port->wPortChange = 0;
- }
- return (USBDevice *)s;
-}
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
deleted file mode 100644
index f7ad25e..0000000
--- a/hw/usb-msd.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * USB Mass Storage Device emulation
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- */
-
-#include "qemu-common.h"
-#include "usb.h"
-#include "block.h"
-#include "scsi-disk.h"
-
-//#define DEBUG_MSD
-
-#ifdef DEBUG_MSD
-#define DPRINTF(fmt, args...) \
-do { printf("usb-msd: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-/* USB requests. */
-#define MassStorageReset 0xff
-#define GetMaxLun 0xfe
-
-enum USBMSDMode {
- USB_MSDM_CBW, /* Command Block. */
- USB_MSDM_DATAOUT, /* Tranfer data to device. */
- USB_MSDM_DATAIN, /* Transfer data from device. */
- USB_MSDM_CSW /* Command Status. */
-};
-
-typedef struct {
- USBDevice dev;
- enum USBMSDMode mode;
- uint32_t scsi_len;
- uint8_t *scsi_buf;
- uint32_t usb_len;
- uint8_t *usb_buf;
- uint32_t data_len;
- uint32_t residue;
- uint32_t tag;
- BlockDriverState *bs;
- SCSIDevice *scsi_dev;
- int result;
- /* For async completion. */
- USBPacket *packet;
-} MSDState;
-
-struct usb_msd_cbw {
- uint32_t sig;
- uint32_t tag;
- uint32_t data_len;
- uint8_t flags;
- uint8_t lun;
- uint8_t cmd_len;
- uint8_t cmd[16];
-};
-
-struct usb_msd_csw {
- uint32_t sig;
- uint32_t tag;
- uint32_t residue;
- uint8_t status;
-};
-
-static const uint8_t qemu_msd_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x00, 0x01, /* u16 bcdUSB; v1.0 */
-
- 0x00, /* u8 bDeviceClass; */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- /* Vendor and product id are arbitrary. */
- 0x00, 0x00, /* u16 idVendor; */
- 0x00, 0x00, /* u16 idProduct; */
- 0x00, 0x00, /* u16 bcdDevice */
-
- 0x01, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x03, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-static const uint8_t qemu_msd_config_descriptor[] = {
-
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x20, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x00, /* u8 MaxPower; */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x02, /* u8 if_bNumEndpoints; */
- 0x08, /* u8 if_bInterfaceClass; MASS STORAGE */
- 0x06, /* u8 if_bInterfaceSubClass; SCSI */
- 0x50, /* u8 if_bInterfaceProtocol; Bulk Only */
- 0x00, /* u8 if_iInterface; */
-
- /* Bulk-In endpoint */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x02, /* u8 ep_bmAttributes; Bulk */
- 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x00, /* u8 ep_bInterval; */
-
- /* Bulk-Out endpoint */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x02, /* u8 ep_bEndpointAddress; OUT Endpoint 2 */
- 0x02, /* u8 ep_bmAttributes; Bulk */
- 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x00 /* u8 ep_bInterval; */
-};
-
-static void usb_msd_copy_data(MSDState *s)
-{
- uint32_t len;
- len = s->usb_len;
- if (len > s->scsi_len)
- len = s->scsi_len;
- if (s->mode == USB_MSDM_DATAIN) {
- memcpy(s->usb_buf, s->scsi_buf, len);
- } else {
- memcpy(s->scsi_buf, s->usb_buf, len);
- }
- s->usb_len -= len;
- s->scsi_len -= len;
- s->usb_buf += len;
- s->scsi_buf += len;
- s->data_len -= len;
- if (s->scsi_len == 0) {
- if (s->mode == USB_MSDM_DATAIN) {
- s->scsi_dev->read_data(s->scsi_dev, s->tag);
- } else if (s->mode == USB_MSDM_DATAOUT) {
- s->scsi_dev->write_data(s->scsi_dev, s->tag);
- }
- }
-}
-
-static void usb_msd_send_status(MSDState *s)
-{
- struct usb_msd_csw csw;
-
- csw.sig = cpu_to_le32(0x53425355);
- csw.tag = cpu_to_le32(s->tag);
- csw.residue = s->residue;
- csw.status = s->result;
- memcpy(s->usb_buf, &csw, 13);
-}
-
-static void usb_msd_command_complete(void *opaque, int reason, uint32_t tag,
- uint32_t arg)
-{
- MSDState *s = (MSDState *)opaque;
- USBPacket *p = s->packet;
-
- if (tag != s->tag) {
- fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", tag);
- }
- if (reason == SCSI_REASON_DONE) {
- DPRINTF("Command complete %d\n", arg);
- s->residue = s->data_len;
- s->result = arg != 0;
- if (s->packet) {
- if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
- /* A deferred packet with no write data remaining must be
- the status read packet. */
- usb_msd_send_status(s);
- s->mode = USB_MSDM_CBW;
- } else {
- if (s->data_len) {
- s->data_len -= s->usb_len;
- if (s->mode == USB_MSDM_DATAIN)
- memset(s->usb_buf, 0, s->usb_len);
- s->usb_len = 0;
- }
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- }
- s->packet = NULL;
- usb_packet_complete(p);
- } else if (s->data_len == 0) {
- s->mode = USB_MSDM_CSW;
- }
- return;
- }
- s->scsi_len = arg;
- s->scsi_buf = s->scsi_dev->get_buf(s->scsi_dev, tag);
- if (p) {
- usb_msd_copy_data(s);
- if (s->usb_len == 0) {
- /* Set s->packet to NULL before calling usb_packet_complete
- because annother request may be issued before
- usb_packet_complete returns. */
- DPRINTF("Packet complete %p\n", p);
- s->packet = NULL;
- usb_packet_complete(p);
- }
- }
-}
-
-static void usb_msd_handle_reset(USBDevice *dev)
-{
- MSDState *s = (MSDState *)dev;
-
- DPRINTF("Reset\n");
- s->mode = USB_MSDM_CBW;
-}
-
-static int usb_msd_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- MSDState *s = (MSDState *)dev;
- int ret = 0;
-
- switch (request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_msd_dev_descriptor,
- sizeof(qemu_msd_dev_descriptor));
- ret = sizeof(qemu_msd_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- memcpy(data, qemu_msd_config_descriptor,
- sizeof(qemu_msd_config_descriptor));
- ret = sizeof(qemu_msd_config_descriptor);
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, "QEMU USB HARDDRIVE");
- break;
- case 3:
- /* serial number */
- ret = set_usb_string(data, "1");
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == 0 && index != 0x81) { /* clear ep halt */
- goto fail;
- }
- ret = 0;
- break;
- /* Class specific requests. */
- case MassStorageReset:
- /* Reset state ready for the next CBW. */
- s->mode = USB_MSDM_CBW;
- ret = 0;
- break;
- case GetMaxLun:
- data[0] = 0;
- ret = 1;
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static void usb_msd_cancel_io(USBPacket *p, void *opaque)
-{
- MSDState *s = opaque;
- s->scsi_dev->cancel_io(s->scsi_dev, s->tag);
- s->packet = NULL;
- s->scsi_len = 0;
-}
-
-static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
-{
- MSDState *s = (MSDState *)dev;
- int ret = 0;
- struct usb_msd_cbw cbw;
- uint8_t devep = p->devep;
- uint8_t *data = p->data;
- int len = p->len;
-
- switch (p->pid) {
- case USB_TOKEN_OUT:
- if (devep != 2)
- goto fail;
-
- switch (s->mode) {
- case USB_MSDM_CBW:
- if (len != 31) {
- fprintf(stderr, "usb-msd: Bad CBW size");
- goto fail;
- }
- memcpy(&cbw, data, 31);
- if (le32_to_cpu(cbw.sig) != 0x43425355) {
- fprintf(stderr, "usb-msd: Bad signature %08x\n",
- le32_to_cpu(cbw.sig));
- goto fail;
- }
- DPRINTF("Command on LUN %d\n", cbw.lun);
- if (cbw.lun != 0) {
- fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);
- goto fail;
- }
- s->tag = le32_to_cpu(cbw.tag);
- s->data_len = le32_to_cpu(cbw.data_len);
- if (s->data_len == 0) {
- s->mode = USB_MSDM_CSW;
- } else if (cbw.flags & 0x80) {
- s->mode = USB_MSDM_DATAIN;
- } else {
- s->mode = USB_MSDM_DATAOUT;
- }
- DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
- s->tag, cbw.flags, cbw.cmd_len, s->data_len);
- s->residue = 0;
- s->scsi_dev->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
- /* ??? Should check that USB and SCSI data transfer
- directions match. */
- if (s->residue == 0) {
- if (s->mode == USB_MSDM_DATAIN) {
- s->scsi_dev->read_data(s->scsi_dev, s->tag);
- } else if (s->mode == USB_MSDM_DATAOUT) {
- s->scsi_dev->write_data(s->scsi_dev, s->tag);
- }
- }
- ret = len;
- break;
-
- case USB_MSDM_DATAOUT:
- DPRINTF("Data out %d/%d\n", len, s->data_len);
- if (len > s->data_len)
- goto fail;
-
- s->usb_buf = data;
- s->usb_len = len;
- if (s->scsi_len) {
- usb_msd_copy_data(s);
- }
- if (s->residue && s->usb_len) {
- s->data_len -= s->usb_len;
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- s->usb_len = 0;
- }
- if (s->usb_len) {
- DPRINTF("Deferring packet %p\n", p);
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- } else {
- ret = len;
- }
- break;
-
- default:
- DPRINTF("Unexpected write (len %d)\n", len);
- goto fail;
- }
- break;
-
- case USB_TOKEN_IN:
- if (devep != 1)
- goto fail;
-
- switch (s->mode) {
- case USB_MSDM_DATAOUT:
- if (s->data_len != 0 || len < 13)
- goto fail;
- /* Waiting for SCSI write to complete. */
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- break;
-
- case USB_MSDM_CSW:
- DPRINTF("Command status %d tag 0x%x, len %d\n",
- s->result, s->tag, len);
- if (len < 13)
- goto fail;
-
- s->usb_len = len;
- s->usb_buf = data;
- usb_msd_send_status(s);
- s->mode = USB_MSDM_CBW;
- ret = 13;
- break;
-
- case USB_MSDM_DATAIN:
- DPRINTF("Data in %d/%d\n", len, s->data_len);
- if (len > s->data_len)
- len = s->data_len;
- s->usb_buf = data;
- s->usb_len = len;
- if (s->scsi_len) {
- usb_msd_copy_data(s);
- }
- if (s->residue && s->usb_len) {
- s->data_len -= s->usb_len;
- memset(s->usb_buf, 0, s->usb_len);
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- s->usb_len = 0;
- }
- if (s->usb_len) {
- DPRINTF("Deferring packet %p\n", p);
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- } else {
- ret = len;
- }
- break;
-
- default:
- DPRINTF("Unexpected read (len %d)\n", len);
- goto fail;
- }
- break;
-
- default:
- DPRINTF("Bad token\n");
- fail:
- ret = USB_RET_STALL;
- break;
- }
-
- return ret;
-}
-
-static void usb_msd_handle_destroy(USBDevice *dev)
-{
- MSDState *s = (MSDState *)dev;
-
- s->scsi_dev->destroy(s->scsi_dev);
- bdrv_delete(s->bs);
- qemu_free(s);
-}
-
-USBDevice *usb_msd_init(const char *filename)
-{
- MSDState *s;
- BlockDriverState *bdrv;
- BlockDriver *drv = NULL;
- const char *p1;
- char fmt[32];
-
- p1 = strchr(filename, ':');
- if (p1++) {
- const char *p2;
-
- if (strstart(filename, "format=", &p2)) {
- int len = MIN(p1 - p2, sizeof(fmt));
- pstrcpy(fmt, len, p2);
-
- drv = bdrv_find_format(fmt);
- if (!drv) {
- printf("invalid format %s\n", fmt);
- return NULL;
- }
- } else if (*filename != ':') {
- printf("unrecognized USB mass-storage option %s\n", filename);
- return NULL;
- }
-
- filename = p1;
- }
-
- if (!*filename) {
- printf("block device specification needed\n");
- return NULL;
- }
-
- s = qemu_mallocz(sizeof(MSDState));
- if (!s)
- return NULL;
-
- bdrv = bdrv_new("usb");
- if (bdrv_open2(bdrv, filename, 0, drv) < 0)
- goto fail;
- if (qemu_key_check(bdrv, filename))
- goto fail;
- s->bs = bdrv;
-
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_msd_handle_reset;
- s->dev.handle_control = usb_msd_handle_control;
- s->dev.handle_data = usb_msd_handle_data;
- s->dev.handle_destroy = usb_msd_handle_destroy;
-
- snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB MSD(%.16s)",
- filename);
-
- s->scsi_dev = scsi_disk_init(bdrv, 0, usb_msd_command_complete, s);
- usb_msd_handle_reset((USBDevice *)s);
- return (USBDevice *)s;
- fail:
- qemu_free(s);
- return NULL;
-}
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
deleted file mode 100644
index 55cb77b..0000000
--- a/hw/usb-ohci.c
+++ /dev/null
@@ -1,1684 +0,0 @@
-/*
- * QEMU USB OHCI Emulation
- * Copyright (c) 2004 Gianni Tedesco
- * Copyright (c) 2006 CodeSourcery
- * Copyright (c) 2006 Openedhand Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * TODO:
- * o Isochronous transfers
- * o Allocate bandwidth in frames properly
- * o Disable timers when nothing needs to be done, or remove timer usage
- * all together.
- * o Handle unrecoverable errors properly
- * o BIOS work to boot from USB storage
-*/
-
-#include "hw.h"
-#include "qemu-timer.h"
-#include "usb.h"
-#include "pci.h"
-#include "pxa.h"
-
-//#define DEBUG_OHCI
-/* Dump packet contents. */
-//#define DEBUG_PACKET
-//#define DEBUG_ISOCH
-/* This causes frames to occur 1000x slower */
-//#define OHCI_TIME_WARP 1
-
-#ifdef DEBUG_OHCI
-#define dprintf printf
-#else
-#define dprintf(...)
-#endif
-
-/* Number of Downstream Ports on the root hub. */
-
-#define OHCI_MAX_PORTS 15
-
-static int64_t usb_frame_time;
-static int64_t usb_bit_time;
-
-typedef struct OHCIPort {
- USBPort port;
- uint32_t ctrl;
-} OHCIPort;
-
-enum ohci_type {
- OHCI_TYPE_PCI,
- OHCI_TYPE_PXA
-};
-
-typedef struct {
- qemu_irq irq;
- enum ohci_type type;
- target_phys_addr_t mem_base;
- int mem;
- int num_ports;
- const char *name;
-
- QEMUTimer *eof_timer;
- int64_t sof_time;
-
- /* OHCI state */
- /* Control partition */
- uint32_t ctl, status;
- uint32_t intr_status;
- uint32_t intr;
-
- /* memory pointer partition */
- uint32_t hcca;
- uint32_t ctrl_head, ctrl_cur;
- uint32_t bulk_head, bulk_cur;
- uint32_t per_cur;
- uint32_t done;
- int done_count;
-
- /* Frame counter partition */
- uint32_t fsmps:15;
- uint32_t fit:1;
- uint32_t fi:14;
- uint32_t frt:1;
- uint16_t frame_number;
- uint16_t padding;
- uint32_t pstart;
- uint32_t lst;
-
- /* Root Hub partition */
- uint32_t rhdesc_a, rhdesc_b;
- uint32_t rhstatus;
- OHCIPort rhport[OHCI_MAX_PORTS];
-
- /* PXA27x Non-OHCI events */
- uint32_t hstatus;
- uint32_t hmask;
- uint32_t hreset;
- uint32_t htest;
-
- /* Active packets. */
- uint32_t old_ctl;
- USBPacket usb_packet;
- uint8_t usb_buf[8192];
- uint32_t async_td;
- int async_complete;
-
-} OHCIState;
-
-/* Host Controller Communications Area */
-struct ohci_hcca {
- uint32_t intr[32];
- uint16_t frame, pad;
- uint32_t done;
-};
-
-static void ohci_bus_stop(OHCIState *ohci);
-
-/* Bitfields for the first word of an Endpoint Desciptor. */
-#define OHCI_ED_FA_SHIFT 0
-#define OHCI_ED_FA_MASK (0x7f<<OHCI_ED_FA_SHIFT)
-#define OHCI_ED_EN_SHIFT 7
-#define OHCI_ED_EN_MASK (0xf<<OHCI_ED_EN_SHIFT)
-#define OHCI_ED_D_SHIFT 11
-#define OHCI_ED_D_MASK (3<<OHCI_ED_D_SHIFT)
-#define OHCI_ED_S (1<<13)
-#define OHCI_ED_K (1<<14)
-#define OHCI_ED_F (1<<15)
-#define OHCI_ED_MPS_SHIFT 16
-#define OHCI_ED_MPS_MASK (0x7ff<<OHCI_ED_MPS_SHIFT)
-
-/* Flags in the head field of an Endpoint Desciptor. */
-#define OHCI_ED_H 1
-#define OHCI_ED_C 2
-
-/* Bitfields for the first word of a Transfer Desciptor. */
-#define OHCI_TD_R (1<<18)
-#define OHCI_TD_DP_SHIFT 19
-#define OHCI_TD_DP_MASK (3<<OHCI_TD_DP_SHIFT)
-#define OHCI_TD_DI_SHIFT 21
-#define OHCI_TD_DI_MASK (7<<OHCI_TD_DI_SHIFT)
-#define OHCI_TD_T0 (1<<24)
-#define OHCI_TD_T1 (1<<24)
-#define OHCI_TD_EC_SHIFT 26
-#define OHCI_TD_EC_MASK (3<<OHCI_TD_EC_SHIFT)
-#define OHCI_TD_CC_SHIFT 28
-#define OHCI_TD_CC_MASK (0xf<<OHCI_TD_CC_SHIFT)
-
-/* Bitfields for the first word of an Isochronous Transfer Desciptor. */
-/* CC & DI - same as in the General Transfer Desciptor */
-#define OHCI_TD_SF_SHIFT 0
-#define OHCI_TD_SF_MASK (0xffff<<OHCI_TD_SF_SHIFT)
-#define OHCI_TD_FC_SHIFT 24
-#define OHCI_TD_FC_MASK (7<<OHCI_TD_FC_SHIFT)
-
-/* Isochronous Transfer Desciptor - Offset / PacketStatusWord */
-#define OHCI_TD_PSW_CC_SHIFT 12
-#define OHCI_TD_PSW_CC_MASK (0xf<<OHCI_TD_PSW_CC_SHIFT)
-#define OHCI_TD_PSW_SIZE_SHIFT 0
-#define OHCI_TD_PSW_SIZE_MASK (0xfff<<OHCI_TD_PSW_SIZE_SHIFT)
-
-#define OHCI_PAGE_MASK 0xfffff000
-#define OHCI_OFFSET_MASK 0xfff
-
-#define OHCI_DPTR_MASK 0xfffffff0
-
-#define OHCI_BM(val, field) \
- (((val) & OHCI_##field##_MASK) >> OHCI_##field##_SHIFT)
-
-#define OHCI_SET_BM(val, field, newval) do { \
- val &= ~OHCI_##field##_MASK; \
- val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \
- } while(0)
-
-/* endpoint descriptor */
-struct ohci_ed {
- uint32_t flags;
- uint32_t tail;
- uint32_t head;
- uint32_t next;
-};
-
-/* General transfer descriptor */
-struct ohci_td {
- uint32_t flags;
- uint32_t cbp;
- uint32_t next;
- uint32_t be;
-};
-
-/* Isochronous transfer descriptor */
-struct ohci_iso_td {
- uint32_t flags;
- uint32_t bp;
- uint32_t next;
- uint32_t be;
- uint16_t offset[8];
-};
-
-#define USB_HZ 12000000
-
-/* OHCI Local stuff */
-#define OHCI_CTL_CBSR ((1<<0)|(1<<1))
-#define OHCI_CTL_PLE (1<<2)
-#define OHCI_CTL_IE (1<<3)
-#define OHCI_CTL_CLE (1<<4)
-#define OHCI_CTL_BLE (1<<5)
-#define OHCI_CTL_HCFS ((1<<6)|(1<<7))
-#define OHCI_USB_RESET 0x00
-#define OHCI_USB_RESUME 0x40
-#define OHCI_USB_OPERATIONAL 0x80
-#define OHCI_USB_SUSPEND 0xc0
-#define OHCI_CTL_IR (1<<8)
-#define OHCI_CTL_RWC (1<<9)
-#define OHCI_CTL_RWE (1<<10)
-
-#define OHCI_STATUS_HCR (1<<0)
-#define OHCI_STATUS_CLF (1<<1)
-#define OHCI_STATUS_BLF (1<<2)
-#define OHCI_STATUS_OCR (1<<3)
-#define OHCI_STATUS_SOC ((1<<6)|(1<<7))
-
-#define OHCI_INTR_SO (1<<0) /* Scheduling overrun */
-#define OHCI_INTR_WD (1<<1) /* HcDoneHead writeback */
-#define OHCI_INTR_SF (1<<2) /* Start of frame */
-#define OHCI_INTR_RD (1<<3) /* Resume detect */
-#define OHCI_INTR_UE (1<<4) /* Unrecoverable error */
-#define OHCI_INTR_FNO (1<<5) /* Frame number overflow */
-#define OHCI_INTR_RHSC (1<<6) /* Root hub status change */
-#define OHCI_INTR_OC (1<<30) /* Ownership change */
-#define OHCI_INTR_MIE (1<<31) /* Master Interrupt Enable */
-
-#define OHCI_HCCA_SIZE 0x100
-#define OHCI_HCCA_MASK 0xffffff00
-
-#define OHCI_EDPTR_MASK 0xfffffff0
-
-#define OHCI_FMI_FI 0x00003fff
-#define OHCI_FMI_FSMPS 0xffff0000
-#define OHCI_FMI_FIT 0x80000000
-
-#define OHCI_FR_RT (1<<31)
-
-#define OHCI_LS_THRESH 0x628
-
-#define OHCI_RHA_RW_MASK 0x00000000 /* Mask of supported features. */
-#define OHCI_RHA_PSM (1<<8)
-#define OHCI_RHA_NPS (1<<9)
-#define OHCI_RHA_DT (1<<10)
-#define OHCI_RHA_OCPM (1<<11)
-#define OHCI_RHA_NOCP (1<<12)
-#define OHCI_RHA_POTPGT_MASK 0xff000000
-
-#define OHCI_RHS_LPS (1<<0)
-#define OHCI_RHS_OCI (1<<1)
-#define OHCI_RHS_DRWE (1<<15)
-#define OHCI_RHS_LPSC (1<<16)
-#define OHCI_RHS_OCIC (1<<17)
-#define OHCI_RHS_CRWE (1<<31)
-
-#define OHCI_PORT_CCS (1<<0)
-#define OHCI_PORT_PES (1<<1)
-#define OHCI_PORT_PSS (1<<2)
-#define OHCI_PORT_POCI (1<<3)
-#define OHCI_PORT_PRS (1<<4)
-#define OHCI_PORT_PPS (1<<8)
-#define OHCI_PORT_LSDA (1<<9)
-#define OHCI_PORT_CSC (1<<16)
-#define OHCI_PORT_PESC (1<<17)
-#define OHCI_PORT_PSSC (1<<18)
-#define OHCI_PORT_OCIC (1<<19)
-#define OHCI_PORT_PRSC (1<<20)
-#define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \
- |OHCI_PORT_OCIC|OHCI_PORT_PRSC)
-
-#define OHCI_TD_DIR_SETUP 0x0
-#define OHCI_TD_DIR_OUT 0x1
-#define OHCI_TD_DIR_IN 0x2
-#define OHCI_TD_DIR_RESERVED 0x3
-
-#define OHCI_CC_NOERROR 0x0
-#define OHCI_CC_CRC 0x1
-#define OHCI_CC_BITSTUFFING 0x2
-#define OHCI_CC_DATATOGGLEMISMATCH 0x3
-#define OHCI_CC_STALL 0x4
-#define OHCI_CC_DEVICENOTRESPONDING 0x5
-#define OHCI_CC_PIDCHECKFAILURE 0x6
-#define OHCI_CC_UNDEXPETEDPID 0x7
-#define OHCI_CC_DATAOVERRUN 0x8
-#define OHCI_CC_DATAUNDERRUN 0x9
-#define OHCI_CC_BUFFEROVERRUN 0xc
-#define OHCI_CC_BUFFERUNDERRUN 0xd
-
-#define OHCI_HRESET_FSBIR (1 << 0)
-
-/* Update IRQ levels */
-static inline void ohci_intr_update(OHCIState *ohci)
-{
- int level = 0;
-
- if ((ohci->intr & OHCI_INTR_MIE) &&
- (ohci->intr_status & ohci->intr))
- level = 1;
-
- qemu_set_irq(ohci->irq, level);
-}
-
-/* Set an interrupt */
-static inline void ohci_set_interrupt(OHCIState *ohci, uint32_t intr)
-{
- ohci->intr_status |= intr;
- ohci_intr_update(ohci);
-}
-
-/* Attach or detach a device on a root hub port. */
-static void ohci_attach(USBPort *port1, USBDevice *dev)
-{
- OHCIState *s = port1->opaque;
- OHCIPort *port = &s->rhport[port1->index];
- uint32_t old_state = port->ctrl;
-
- if (dev) {
- if (port->port.dev) {
- usb_attach(port1, NULL);
- }
- /* set connect status */
- port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
-
- /* update speed */
- if (dev->speed == USB_SPEED_LOW)
- port->ctrl |= OHCI_PORT_LSDA;
- else
- port->ctrl &= ~OHCI_PORT_LSDA;
- port->port.dev = dev;
-
- /* notify of remote-wakeup */
- if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND)
- ohci_set_interrupt(s, OHCI_INTR_RD);
-
- /* send the attach message */
- usb_send_msg(dev, USB_MSG_ATTACH);
- dprintf("usb-ohci: Attached port %d\n", port1->index);
- } else {
- /* set connect status */
- if (port->ctrl & OHCI_PORT_CCS) {
- port->ctrl &= ~OHCI_PORT_CCS;
- port->ctrl |= OHCI_PORT_CSC;
- }
- /* disable port */
- if (port->ctrl & OHCI_PORT_PES) {
- port->ctrl &= ~OHCI_PORT_PES;
- port->ctrl |= OHCI_PORT_PESC;
- }
- dev = port->port.dev;
- if (dev) {
- /* send the detach message */
- usb_send_msg(dev, USB_MSG_DETACH);
- }
- port->port.dev = NULL;
- dprintf("usb-ohci: Detached port %d\n", port1->index);
- }
-
- if (old_state != port->ctrl)
- ohci_set_interrupt(s, OHCI_INTR_RHSC);
-}
-
-/* Reset the controller */
-static void ohci_reset(void *opaque)
-{
- OHCIState *ohci = opaque;
- OHCIPort *port;
- int i;
-
- ohci_bus_stop(ohci);
- ohci->ctl = 0;
- ohci->old_ctl = 0;
- ohci->status = 0;
- ohci->intr_status = 0;
- ohci->intr = OHCI_INTR_MIE;
-
- ohci->hcca = 0;
- ohci->ctrl_head = ohci->ctrl_cur = 0;
- ohci->bulk_head = ohci->bulk_cur = 0;
- ohci->per_cur = 0;
- ohci->done = 0;
- ohci->done_count = 7;
-
- /* FSMPS is marked TBD in OCHI 1.0, what gives ffs?
- * I took the value linux sets ...
- */
- ohci->fsmps = 0x2778;
- ohci->fi = 0x2edf;
- ohci->fit = 0;
- ohci->frt = 0;
- ohci->frame_number = 0;
- ohci->pstart = 0;
- ohci->lst = OHCI_LS_THRESH;
-
- ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports;
- ohci->rhdesc_b = 0x0; /* Impl. specific */
- ohci->rhstatus = 0;
-
- for (i = 0; i < ohci->num_ports; i++)
- {
- port = &ohci->rhport[i];
- port->ctrl = 0;
- if (port->port.dev)
- ohci_attach(&port->port, port->port.dev);
- }
- if (ohci->async_td) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- dprintf("usb-ohci: Reset %s\n", ohci->name);
-}
-
-/* Get an array of dwords from main memory */
-static inline int get_dwords(uint32_t addr, uint32_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
- *buf = le32_to_cpu(*buf);
- }
-
- return 1;
-}
-
-/* Put an array of dwords in to main memory */
-static inline int put_dwords(uint32_t addr, uint32_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- uint32_t tmp = cpu_to_le32(*buf);
- cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
- }
-
- return 1;
-}
-
-/* Get an array of words from main memory */
-static inline int get_words(uint32_t addr, uint16_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
- *buf = le16_to_cpu(*buf);
- }
-
- return 1;
-}
-
-/* Put an array of words in to main memory */
-static inline int put_words(uint32_t addr, uint16_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- uint16_t tmp = cpu_to_le16(*buf);
- cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
- }
-
- return 1;
-}
-
-static inline int ohci_read_ed(uint32_t addr, struct ohci_ed *ed)
-{
- return get_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
-}
-
-static inline int ohci_read_td(uint32_t addr, struct ohci_td *td)
-{
- return get_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
-}
-
-static inline int ohci_read_iso_td(uint32_t addr, struct ohci_iso_td *td)
-{
- return (get_dwords(addr, (uint32_t *)td, 4) &&
- get_words(addr + 16, td->offset, 8));
-}
-
-static inline int ohci_put_ed(uint32_t addr, struct ohci_ed *ed)
-{
- return put_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
-}
-
-static inline int ohci_put_td(uint32_t addr, struct ohci_td *td)
-{
- return put_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
-}
-
-static inline int ohci_put_iso_td(uint32_t addr, struct ohci_iso_td *td)
-{
- return (put_dwords(addr, (uint32_t *)td, 4) &&
- put_words(addr + 16, td->offset, 8));
-}
-
-/* Read/Write the contents of a TD from/to main memory. */
-static void ohci_copy_td(struct ohci_td *td, uint8_t *buf, int len, int write)
-{
- uint32_t ptr;
- uint32_t n;
-
- ptr = td->cbp;
- n = 0x1000 - (ptr & 0xfff);
- if (n > len)
- n = len;
- cpu_physical_memory_rw(ptr, buf, n, write);
- if (n == len)
- return;
- ptr = td->be & ~0xfffu;
- buf += n;
- cpu_physical_memory_rw(ptr, buf, len - n, write);
-}
-
-/* Read/Write the contents of an ISO TD from/to main memory. */
-static void ohci_copy_iso_td(uint32_t start_addr, uint32_t end_addr,
- uint8_t *buf, int len, int write)
-{
- uint32_t ptr;
- uint32_t n;
-
- ptr = start_addr;
- n = 0x1000 - (ptr & 0xfff);
- if (n > len)
- n = len;
- cpu_physical_memory_rw(ptr, buf, n, write);
- if (n == len)
- return;
- ptr = end_addr & ~0xfffu;
- buf += n;
- cpu_physical_memory_rw(ptr, buf, len - n, write);
-}
-
-static void ohci_process_lists(OHCIState *ohci, int completion);
-
-static void ohci_async_complete_packet(USBPacket *packet, void *opaque)
-{
- OHCIState *ohci = opaque;
-#ifdef DEBUG_PACKET
- dprintf("Async packet complete\n");
-#endif
- ohci->async_complete = 1;
- ohci_process_lists(ohci, 1);
-}
-
-#define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b)))
-
-static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
- int completion)
-{
- int dir;
- size_t len = 0;
- const char *str = NULL;
- int pid;
- int ret;
- int i;
- USBDevice *dev;
- struct ohci_iso_td iso_td;
- uint32_t addr;
- uint16_t starting_frame;
- int16_t relative_frame_number;
- int frame_count;
- uint32_t start_offset, next_offset, end_offset = 0;
- uint32_t start_addr, end_addr;
-
- addr = ed->head & OHCI_DPTR_MASK;
-
- if (!ohci_read_iso_td(addr, &iso_td)) {
- printf("usb-ohci: ISO_TD read error at %x\n", addr);
- return 0;
- }
-
- starting_frame = OHCI_BM(iso_td.flags, TD_SF);
- frame_count = OHCI_BM(iso_td.flags, TD_FC);
- relative_frame_number = USUB(ohci->frame_number, starting_frame);
-
-#ifdef DEBUG_ISOCH
- printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n"
- "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
- "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
- "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
- "frame_number 0x%.8x starting_frame 0x%.8x\n"
- "frame_count 0x%.8x relative %d\n"
- "di 0x%.8x cc 0x%.8x\n",
- ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK,
- iso_td.flags, iso_td.bp, iso_td.next, iso_td.be,
- iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3],
- iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7],
- ohci->frame_number, starting_frame,
- frame_count, relative_frame_number,
- OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC));
-#endif
-
- if (relative_frame_number < 0) {
- dprintf("usb-ohci: ISO_TD R=%d < 0\n", relative_frame_number);
- return 1;
- } else if (relative_frame_number > frame_count) {
- /* ISO TD expired - retire the TD to the Done Queue and continue with
- the next ISO TD of the same ED */
- dprintf("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number,
- frame_count);
- OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
- ed->head &= ~OHCI_DPTR_MASK;
- ed->head |= (iso_td.next & OHCI_DPTR_MASK);
- iso_td.next = ohci->done;
- ohci->done = addr;
- i = OHCI_BM(iso_td.flags, TD_DI);
- if (i < ohci->done_count)
- ohci->done_count = i;
- ohci_put_iso_td(addr, &iso_td);
- return 0;
- }
-
- dir = OHCI_BM(ed->flags, ED_D);
- switch (dir) {
- case OHCI_TD_DIR_IN:
- str = "in";
- pid = USB_TOKEN_IN;
- break;
- case OHCI_TD_DIR_OUT:
- str = "out";
- pid = USB_TOKEN_OUT;
- break;
- case OHCI_TD_DIR_SETUP:
- str = "setup";
- pid = USB_TOKEN_SETUP;
- break;
- default:
- printf("usb-ohci: Bad direction %d\n", dir);
- return 1;
- }
-
- if (!iso_td.bp || !iso_td.be) {
- printf("usb-ohci: ISO_TD bp 0x%.8x be 0x%.8x\n", iso_td.bp, iso_td.be);
- return 1;
- }
-
- start_offset = iso_td.offset[relative_frame_number];
- next_offset = iso_td.offset[relative_frame_number + 1];
-
- if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) ||
- ((relative_frame_number < frame_count) &&
- !(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) {
- printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n",
- start_offset, next_offset);
- return 1;
- }
-
- if ((relative_frame_number < frame_count) && (start_offset > next_offset)) {
- printf("usb-ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n",
- start_offset, next_offset);
- return 1;
- }
-
- if ((start_offset & 0x1000) == 0) {
- start_addr = (iso_td.bp & OHCI_PAGE_MASK) |
- (start_offset & OHCI_OFFSET_MASK);
- } else {
- start_addr = (iso_td.be & OHCI_PAGE_MASK) |
- (start_offset & OHCI_OFFSET_MASK);
- }
-
- if (relative_frame_number < frame_count) {
- end_offset = next_offset - 1;
- if ((end_offset & 0x1000) == 0) {
- end_addr = (iso_td.bp & OHCI_PAGE_MASK) |
- (end_offset & OHCI_OFFSET_MASK);
- } else {
- end_addr = (iso_td.be & OHCI_PAGE_MASK) |
- (end_offset & OHCI_OFFSET_MASK);
- }
- } else {
- /* Last packet in the ISO TD */
- end_addr = iso_td.be;
- }
-
- if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) {
- len = (end_addr & OHCI_OFFSET_MASK) + 0x1001
- - (start_addr & OHCI_OFFSET_MASK);
- } else {
- len = end_addr - start_addr + 1;
- }
-
- if (len && dir != OHCI_TD_DIR_IN) {
- ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, len, 0);
- }
-
- if (completion) {
- ret = ohci->usb_packet.len;
- } else {
- ret = USB_RET_NODEV;
- for (i = 0; i < ohci->num_ports; i++) {
- dev = ohci->rhport[i].port.dev;
- if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
- continue;
- ohci->usb_packet.pid = pid;
- ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
- ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
- ohci->usb_packet.data = ohci->usb_buf;
- ohci->usb_packet.len = len;
- ohci->usb_packet.complete_cb = ohci_async_complete_packet;
- ohci->usb_packet.complete_opaque = ohci;
- ret = dev->handle_packet(dev, &ohci->usb_packet);
- if (ret != USB_RET_NODEV)
- break;
- }
-
- if (ret == USB_RET_ASYNC) {
- return 1;
- }
- }
-
-#ifdef DEBUG_ISOCH
- printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n",
- start_offset, end_offset, start_addr, end_addr, str, len, ret);
-#endif
-
- /* Writeback */
- if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
- /* IN transfer succeeded */
- ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, ret, 1);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_NOERROR);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
- } else if (dir == OHCI_TD_DIR_OUT && ret == len) {
- /* OUT transfer succeeded */
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_NOERROR);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0);
- } else {
- if (ret > (ssize_t) len) {
- printf("usb-ohci: DataOverrun %d > %zu\n", ret, len);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_DATAOVERRUN);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
- len);
- } else if (ret >= 0) {
- printf("usb-ohci: DataUnderrun %d\n", ret);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_DATAUNDERRUN);
- } else {
- switch (ret) {
- case USB_RET_NODEV:
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_DEVICENOTRESPONDING);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
- 0);
- break;
- case USB_RET_NAK:
- case USB_RET_STALL:
- printf("usb-ohci: got NAK/STALL %d\n", ret);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_STALL);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
- 0);
- break;
- default:
- printf("usb-ohci: Bad device response %d\n", ret);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_UNDEXPETEDPID);
- break;
- }
- }
- }
-
- if (relative_frame_number == frame_count) {
- /* Last data packet of ISO TD - retire the TD to the Done Queue */
- OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR);
- ed->head &= ~OHCI_DPTR_MASK;
- ed->head |= (iso_td.next & OHCI_DPTR_MASK);
- iso_td.next = ohci->done;
- ohci->done = addr;
- i = OHCI_BM(iso_td.flags, TD_DI);
- if (i < ohci->done_count)
- ohci->done_count = i;
- }
- ohci_put_iso_td(addr, &iso_td);
- return 1;
-}
-
-/* Service a transport descriptor.
- Returns nonzero to terminate processing of this endpoint. */
-
-static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
-{
- int dir;
- size_t len = 0;
- const char *str = NULL;
- int pid;
- int ret;
- int i;
- USBDevice *dev;
- struct ohci_td td;
- uint32_t addr;
- int flag_r;
- int completion;
-
- addr = ed->head & OHCI_DPTR_MASK;
- /* See if this TD has already been submitted to the device. */
- completion = (addr == ohci->async_td);
- if (completion && !ohci->async_complete) {
-#ifdef DEBUG_PACKET
- dprintf("Skipping async TD\n");
-#endif
- return 1;
- }
- if (!ohci_read_td(addr, &td)) {
- fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
- return 0;
- }
-
- dir = OHCI_BM(ed->flags, ED_D);
- switch (dir) {
- case OHCI_TD_DIR_OUT:
- case OHCI_TD_DIR_IN:
- /* Same value. */
- break;
- default:
- dir = OHCI_BM(td.flags, TD_DP);
- break;
- }
-
- switch (dir) {
- case OHCI_TD_DIR_IN:
- str = "in";
- pid = USB_TOKEN_IN;
- break;
- case OHCI_TD_DIR_OUT:
- str = "out";
- pid = USB_TOKEN_OUT;
- break;
- case OHCI_TD_DIR_SETUP:
- str = "setup";
- pid = USB_TOKEN_SETUP;
- break;
- default:
- fprintf(stderr, "usb-ohci: Bad direction\n");
- return 1;
- }
- if (td.cbp && td.be) {
- if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {
- len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);
- } else {
- len = (td.be - td.cbp) + 1;
- }
-
- if (len && dir != OHCI_TD_DIR_IN && !completion) {
- ohci_copy_td(&td, ohci->usb_buf, len, 0);
- }
- }
-
- flag_r = (td.flags & OHCI_TD_R) != 0;
-#ifdef DEBUG_PACKET
- dprintf(" TD @ 0x%.8x %u bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
- addr, len, str, flag_r, td.cbp, td.be);
-
- if (len > 0 && dir != OHCI_TD_DIR_IN) {
- dprintf(" data:");
- for (i = 0; i < len; i++)
- printf(" %.2x", ohci->usb_buf[i]);
- dprintf("\n");
- }
-#endif
- if (completion) {
- ret = ohci->usb_packet.len;
- ohci->async_td = 0;
- ohci->async_complete = 0;
- } else {
- ret = USB_RET_NODEV;
- for (i = 0; i < ohci->num_ports; i++) {
- dev = ohci->rhport[i].port.dev;
- if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
- continue;
-
- if (ohci->async_td) {
- /* ??? The hardware should allow one active packet per
- endpoint. We only allow one active packet per controller.
- This should be sufficient as long as devices respond in a
- timely manner.
- */
-#ifdef DEBUG_PACKET
- dprintf("Too many pending packets\n");
-#endif
- return 1;
- }
- ohci->usb_packet.pid = pid;
- ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
- ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
- ohci->usb_packet.data = ohci->usb_buf;
- ohci->usb_packet.len = len;
- ohci->usb_packet.complete_cb = ohci_async_complete_packet;
- ohci->usb_packet.complete_opaque = ohci;
- ret = dev->handle_packet(dev, &ohci->usb_packet);
- if (ret != USB_RET_NODEV)
- break;
- }
-#ifdef DEBUG_PACKET
- dprintf("ret=%d\n", ret);
-#endif
- if (ret == USB_RET_ASYNC) {
- ohci->async_td = addr;
- return 1;
- }
- }
- if (ret >= 0) {
- if (dir == OHCI_TD_DIR_IN) {
- ohci_copy_td(&td, ohci->usb_buf, ret, 1);
-#ifdef DEBUG_PACKET
- dprintf(" data:");
- for (i = 0; i < ret; i++)
- printf(" %.2x", ohci->usb_buf[i]);
- dprintf("\n");
-#endif
- } else {
- ret = len;
- }
- }
-
- /* Writeback */
- if (ret == len || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {
- /* Transmission succeeded. */
- if (ret == len) {
- td.cbp = 0;
- } else {
- td.cbp += ret;
- if ((td.cbp & 0xfff) + ret > 0xfff) {
- td.cbp &= 0xfff;
- td.cbp |= td.be & ~0xfff;
- }
- }
- td.flags |= OHCI_TD_T1;
- td.flags ^= OHCI_TD_T0;
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);
- OHCI_SET_BM(td.flags, TD_EC, 0);
-
- ed->head &= ~OHCI_ED_C;
- if (td.flags & OHCI_TD_T0)
- ed->head |= OHCI_ED_C;
- } else {
- if (ret >= 0) {
- dprintf("usb-ohci: Underrun\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);
- } else {
- switch (ret) {
- case USB_RET_NODEV:
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);
- case USB_RET_NAK:
- dprintf("usb-ohci: got NAK\n");
- return 1;
- case USB_RET_STALL:
- dprintf("usb-ohci: got STALL\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL);
- break;
- case USB_RET_BABBLE:
- dprintf("usb-ohci: got BABBLE\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
- break;
- default:
- fprintf(stderr, "usb-ohci: Bad device response %d\n", ret);
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);
- OHCI_SET_BM(td.flags, TD_EC, 3);
- break;
- }
- }
- ed->head |= OHCI_ED_H;
- }
-
- /* Retire this TD */
- ed->head &= ~OHCI_DPTR_MASK;
- ed->head |= td.next & OHCI_DPTR_MASK;
- td.next = ohci->done;
- ohci->done = addr;
- i = OHCI_BM(td.flags, TD_DI);
- if (i < ohci->done_count)
- ohci->done_count = i;
- ohci_put_td(addr, &td);
- return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
-}
-
-/* Service an endpoint list. Returns nonzero if active TD were found. */
-static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
-{
- struct ohci_ed ed;
- uint32_t next_ed;
- uint32_t cur;
- int active;
-
- active = 0;
-
- if (head == 0)
- return 0;
-
- for (cur = head; cur; cur = next_ed) {
- if (!ohci_read_ed(cur, &ed)) {
- fprintf(stderr, "usb-ohci: ED read error at %x\n", cur);
- return 0;
- }
-
- next_ed = ed.next & OHCI_DPTR_MASK;
-
- if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
- uint32_t addr;
- /* Cancel pending packets for ED that have been paused. */
- addr = ed.head & OHCI_DPTR_MASK;
- if (ohci->async_td && addr == ohci->async_td) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- continue;
- }
-
- while ((ed.head & OHCI_DPTR_MASK) != ed.tail) {
-#ifdef DEBUG_PACKET
- dprintf("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u "
- "h=%u c=%u\n head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur,
- OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN),
- OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0,
- (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0,
- OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0,
- (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK,
- ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK);
-#endif
- active = 1;
-
- if ((ed.flags & OHCI_ED_F) == 0) {
- if (ohci_service_td(ohci, &ed))
- break;
- } else {
- /* Handle isochronous endpoints */
- if (ohci_service_iso_td(ohci, &ed, completion))
- break;
- }
- }
-
- ohci_put_ed(cur, &ed);
- }
-
- return active;
-}
-
-/* Generate a SOF event, and set a timer for EOF */
-static void ohci_sof(OHCIState *ohci)
-{
- ohci->sof_time = qemu_get_clock(vm_clock);
- qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time);
- ohci_set_interrupt(ohci, OHCI_INTR_SF);
-}
-
-/* Process Control and Bulk lists. */
-static void ohci_process_lists(OHCIState *ohci, int completion)
-{
- if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
- if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head)
- dprintf("usb-ohci: head %x, cur %x\n",
- ohci->ctrl_head, ohci->ctrl_cur);
- if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion)) {
- ohci->ctrl_cur = 0;
- ohci->status &= ~OHCI_STATUS_CLF;
- }
- }
-
- if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
- if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion)) {
- ohci->bulk_cur = 0;
- ohci->status &= ~OHCI_STATUS_BLF;
- }
- }
-}
-
-/* Do frame processing on frame boundary */
-static void ohci_frame_boundary(void *opaque)
-{
- OHCIState *ohci = opaque;
- struct ohci_hcca hcca;
-
- cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 0);
-
- /* Process all the lists at the end of the frame */
- if (ohci->ctl & OHCI_CTL_PLE) {
- int n;
-
- n = ohci->frame_number & 0x1f;
- ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]), 0);
- }
-
- /* Cancel all pending packets if either of the lists has been disabled. */
- if (ohci->async_td &&
- ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- ohci->old_ctl = ohci->ctl;
- ohci_process_lists(ohci, 0);
-
- /* Frame boundary, so do EOF stuf here */
- ohci->frt = ohci->fit;
-
- /* XXX: endianness */
- ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
- hcca.frame = cpu_to_le32(ohci->frame_number);
-
- if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
- if (!ohci->done)
- abort();
- if (ohci->intr & ohci->intr_status)
- ohci->done |= 1;
- hcca.done = cpu_to_le32(ohci->done);
- ohci->done = 0;
- ohci->done_count = 7;
- ohci_set_interrupt(ohci, OHCI_INTR_WD);
- }
-
- if (ohci->done_count != 7 && ohci->done_count != 0)
- ohci->done_count--;
-
- /* Do SOF stuff here */
- ohci_sof(ohci);
-
- /* Writeback HCCA */
- cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 1);
-}
-
-/* Start sending SOF tokens across the USB bus, lists are processed in
- * next frame
- */
-static int ohci_bus_start(OHCIState *ohci)
-{
- ohci->eof_timer = qemu_new_timer(vm_clock,
- ohci_frame_boundary,
- ohci);
-
- if (ohci->eof_timer == NULL) {
- fprintf(stderr, "usb-ohci: %s: qemu_new_timer failed\n", ohci->name);
- /* TODO: Signal unrecoverable error */
- return 0;
- }
-
- dprintf("usb-ohci: %s: USB Operational\n", ohci->name);
-
- ohci_sof(ohci);
-
- return 1;
-}
-
-/* Stop sending SOF tokens on the bus */
-static void ohci_bus_stop(OHCIState *ohci)
-{
- if (ohci->eof_timer)
- qemu_del_timer(ohci->eof_timer);
- ohci->eof_timer = NULL;
-}
-
-/* Sets a flag in a port status register but only set it if the port is
- * connected, if not set ConnectStatusChange flag. If flag is enabled
- * return 1.
- */
-static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
-{
- int ret = 1;
-
- /* writing a 0 has no effect */
- if (val == 0)
- return 0;
-
- /* If CurrentConnectStatus is cleared we set
- * ConnectStatusChange
- */
- if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
- ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
- if (ohci->rhstatus & OHCI_RHS_DRWE) {
- /* TODO: CSC is a wakeup event */
- }
- return 0;
- }
-
- if (ohci->rhport[i].ctrl & val)
- ret = 0;
-
- /* set the bit */
- ohci->rhport[i].ctrl |= val;
-
- return ret;
-}
-
-/* Set the frame interval - frame interval toggle is manipulated by the hcd only */
-static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
-{
- val &= OHCI_FMI_FI;
-
- if (val != ohci->fi) {
- dprintf("usb-ohci: %s: FrameInterval = 0x%x (%u)\n",
- ohci->name, ohci->fi, ohci->fi);
- }
-
- ohci->fi = val;
-}
-
-static void ohci_port_power(OHCIState *ohci, int i, int p)
-{
- if (p) {
- ohci->rhport[i].ctrl |= OHCI_PORT_PPS;
- } else {
- ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS|
- OHCI_PORT_CCS|
- OHCI_PORT_PSS|
- OHCI_PORT_PRS);
- }
-}
-
-/* Set HcControlRegister */
-static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
-{
- uint32_t old_state;
- uint32_t new_state;
-
- old_state = ohci->ctl & OHCI_CTL_HCFS;
- ohci->ctl = val;
- new_state = ohci->ctl & OHCI_CTL_HCFS;
-
- /* no state change */
- if (old_state == new_state)
- return;
-
- switch (new_state) {
- case OHCI_USB_OPERATIONAL:
- ohci_bus_start(ohci);
- break;
- case OHCI_USB_SUSPEND:
- ohci_bus_stop(ohci);
- dprintf("usb-ohci: %s: USB Suspended\n", ohci->name);
- break;
- case OHCI_USB_RESUME:
- dprintf("usb-ohci: %s: USB Resume\n", ohci->name);
- break;
- case OHCI_USB_RESET:
- ohci_reset(ohci);
- dprintf("usb-ohci: %s: USB Reset\n", ohci->name);
- break;
- }
-}
-
-static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
-{
- uint16_t fr;
- int64_t tks;
-
- if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL)
- return (ohci->frt << 31);
-
- /* Being in USB operational state guarnatees sof_time was
- * set already.
- */
- tks = qemu_get_clock(vm_clock) - ohci->sof_time;
-
- /* avoid muldiv if possible */
- if (tks >= usb_frame_time)
- return (ohci->frt << 31);
-
- tks = muldiv64(1, tks, usb_bit_time);
- fr = (uint16_t)(ohci->fi - tks);
-
- return (ohci->frt << 31) | fr;
-}
-
-
-/* Set root hub status */
-static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
-{
- uint32_t old_state;
-
- old_state = ohci->rhstatus;
-
- /* write 1 to clear OCIC */
- if (val & OHCI_RHS_OCIC)
- ohci->rhstatus &= ~OHCI_RHS_OCIC;
-
- if (val & OHCI_RHS_LPS) {
- int i;
-
- for (i = 0; i < ohci->num_ports; i++)
- ohci_port_power(ohci, i, 0);
- dprintf("usb-ohci: powered down all ports\n");
- }
-
- if (val & OHCI_RHS_LPSC) {
- int i;
-
- for (i = 0; i < ohci->num_ports; i++)
- ohci_port_power(ohci, i, 1);
- dprintf("usb-ohci: powered up all ports\n");
- }
-
- if (val & OHCI_RHS_DRWE)
- ohci->rhstatus |= OHCI_RHS_DRWE;
-
- if (val & OHCI_RHS_CRWE)
- ohci->rhstatus &= ~OHCI_RHS_DRWE;
-
- if (old_state != ohci->rhstatus)
- ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
-}
-
-/* Set root hub port status */
-static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
-{
- uint32_t old_state;
- OHCIPort *port;
-
- port = &ohci->rhport[portnum];
- old_state = port->ctrl;
-
- /* Write to clear CSC, PESC, PSSC, OCIC, PRSC */
- if (val & OHCI_PORT_WTC)
- port->ctrl &= ~(val & OHCI_PORT_WTC);
-
- if (val & OHCI_PORT_CCS)
- port->ctrl &= ~OHCI_PORT_PES;
-
- ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES);
-
- if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS))
- dprintf("usb-ohci: port %d: SUSPEND\n", portnum);
-
- if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
- dprintf("usb-ohci: port %d: RESET\n", portnum);
- usb_send_msg(port->port.dev, USB_MSG_RESET);
- port->ctrl &= ~OHCI_PORT_PRS;
- /* ??? Should this also set OHCI_PORT_PESC. */
- port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
- }
-
- /* Invert order here to ensure in ambiguous case, device is
- * powered up...
- */
- if (val & OHCI_PORT_LSDA)
- ohci_port_power(ohci, portnum, 0);
- if (val & OHCI_PORT_PPS)
- ohci_port_power(ohci, portnum, 1);
-
- if (old_state != port->ctrl)
- ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
-
- return;
-}
-
-static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
-{
- OHCIState *ohci = ptr;
-
- addr -= ohci->mem_base;
-
- /* Only aligned reads are allowed on OHCI */
- if (addr & 3) {
- fprintf(stderr, "usb-ohci: Mis-aligned read\n");
- return 0xffffffff;
- }
-
- if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
- /* HcRhPortStatus */
- return ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS;
- }
-
- switch (addr >> 2) {
- case 0: /* HcRevision */
- return 0x10;
-
- case 1: /* HcControl */
- return ohci->ctl;
-
- case 2: /* HcCommandStatus */
- return ohci->status;
-
- case 3: /* HcInterruptStatus */
- return ohci->intr_status;
-
- case 4: /* HcInterruptEnable */
- case 5: /* HcInterruptDisable */
- return ohci->intr;
-
- case 6: /* HcHCCA */
- return ohci->hcca;
-
- case 7: /* HcPeriodCurrentED */
- return ohci->per_cur;
-
- case 8: /* HcControlHeadED */
- return ohci->ctrl_head;
-
- case 9: /* HcControlCurrentED */
- return ohci->ctrl_cur;
-
- case 10: /* HcBulkHeadED */
- return ohci->bulk_head;
-
- case 11: /* HcBulkCurrentED */
- return ohci->bulk_cur;
-
- case 12: /* HcDoneHead */
- return ohci->done;
-
- case 13: /* HcFmInterval */
- return (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi);
-
- case 14: /* HcFmRemaining */
- return ohci_get_frame_remaining(ohci);
-
- case 15: /* HcFmNumber */
- return ohci->frame_number;
-
- case 16: /* HcPeriodicStart */
- return ohci->pstart;
-
- case 17: /* HcLSThreshold */
- return ohci->lst;
-
- case 18: /* HcRhDescriptorA */
- return ohci->rhdesc_a;
-
- case 19: /* HcRhDescriptorB */
- return ohci->rhdesc_b;
-
- case 20: /* HcRhStatus */
- return ohci->rhstatus;
-
- /* PXA27x specific registers */
- case 24: /* HcStatus */
- return ohci->hstatus & ohci->hmask;
-
- case 25: /* HcHReset */
- return ohci->hreset;
-
- case 26: /* HcHInterruptEnable */
- return ohci->hmask;
-
- case 27: /* HcHInterruptTest */
- return ohci->htest;
-
- default:
- fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr);
- return 0xffffffff;
- }
-}
-
-static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
-{
- OHCIState *ohci = ptr;
-
- addr -= ohci->mem_base;
-
- /* Only aligned reads are allowed on OHCI */
- if (addr & 3) {
- fprintf(stderr, "usb-ohci: Mis-aligned write\n");
- return;
- }
-
- if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
- /* HcRhPortStatus */
- ohci_port_set_status(ohci, (addr - 0x54) >> 2, val);
- return;
- }
-
- switch (addr >> 2) {
- case 1: /* HcControl */
- ohci_set_ctl(ohci, val);
- break;
-
- case 2: /* HcCommandStatus */
- /* SOC is read-only */
- val = (val & ~OHCI_STATUS_SOC);
-
- /* Bits written as '0' remain unchanged in the register */
- ohci->status |= val;
-
- if (ohci->status & OHCI_STATUS_HCR)
- ohci_reset(ohci);
- break;
-
- case 3: /* HcInterruptStatus */
- ohci->intr_status &= ~val;
- ohci_intr_update(ohci);
- break;
-
- case 4: /* HcInterruptEnable */
- ohci->intr |= val;
- ohci_intr_update(ohci);
- break;
-
- case 5: /* HcInterruptDisable */
- ohci->intr &= ~val;
- ohci_intr_update(ohci);
- break;
-
- case 6: /* HcHCCA */
- ohci->hcca = val & OHCI_HCCA_MASK;
- break;
-
- case 8: /* HcControlHeadED */
- ohci->ctrl_head = val & OHCI_EDPTR_MASK;
- break;
-
- case 9: /* HcControlCurrentED */
- ohci->ctrl_cur = val & OHCI_EDPTR_MASK;
- break;
-
- case 10: /* HcBulkHeadED */
- ohci->bulk_head = val & OHCI_EDPTR_MASK;
- break;
-
- case 11: /* HcBulkCurrentED */
- ohci->bulk_cur = val & OHCI_EDPTR_MASK;
- break;
-
- case 13: /* HcFmInterval */
- ohci->fsmps = (val & OHCI_FMI_FSMPS) >> 16;
- ohci->fit = (val & OHCI_FMI_FIT) >> 31;
- ohci_set_frame_interval(ohci, val);
- break;
-
- case 15: /* HcFmNumber */
- break;
-
- case 16: /* HcPeriodicStart */
- ohci->pstart = val & 0xffff;
- break;
-
- case 17: /* HcLSThreshold */
- ohci->lst = val & 0xffff;
- break;
-
- case 18: /* HcRhDescriptorA */
- ohci->rhdesc_a &= ~OHCI_RHA_RW_MASK;
- ohci->rhdesc_a |= val & OHCI_RHA_RW_MASK;
- break;
-
- case 19: /* HcRhDescriptorB */
- break;
-
- case 20: /* HcRhStatus */
- ohci_set_hub_status(ohci, val);
- break;
-
- /* PXA27x specific registers */
- case 24: /* HcStatus */
- ohci->hstatus &= ~(val & ohci->hmask);
-
- case 25: /* HcHReset */
- ohci->hreset = val & ~OHCI_HRESET_FSBIR;
- if (val & OHCI_HRESET_FSBIR)
- ohci_reset(ohci);
- break;
-
- case 26: /* HcHInterruptEnable */
- ohci->hmask = val;
- break;
-
- case 27: /* HcHInterruptTest */
- ohci->htest = val;
- break;
-
- default:
- fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr);
- break;
- }
-}
-
-/* Only dword reads are defined on OHCI register space */
-static CPUReadMemoryFunc *ohci_readfn[3]={
- ohci_mem_read,
- ohci_mem_read,
- ohci_mem_read
-};
-
-/* Only dword writes are defined on OHCI register space */
-static CPUWriteMemoryFunc *ohci_writefn[3]={
- ohci_mem_write,
- ohci_mem_write,
- ohci_mem_write
-};
-
-static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
- qemu_irq irq, enum ohci_type type, const char *name)
-{
- int i;
-
- if (usb_frame_time == 0) {
-#ifdef OHCI_TIME_WARP
- usb_frame_time = ticks_per_sec;
- usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ/1000);
-#else
- usb_frame_time = muldiv64(1, ticks_per_sec, 1000);
- if (ticks_per_sec >= USB_HZ) {
- usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ);
- } else {
- usb_bit_time = 1;
- }
-#endif
- dprintf("usb-ohci: usb_bit_time=%lli usb_frame_time=%lli\n",
- usb_frame_time, usb_bit_time);
- }
-
- ohci->mem = cpu_register_io_memory(0, ohci_readfn, ohci_writefn, ohci);
- ohci->name = name;
-
- ohci->irq = irq;
- ohci->type = type;
-
- ohci->num_ports = num_ports;
- for (i = 0; i < num_ports; i++) {
- qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
- }
-
- ohci->async_td = 0;
- qemu_register_reset(ohci_reset, ohci);
- ohci_reset(ohci);
-}
-
-typedef struct {
- PCIDevice pci_dev;
- OHCIState state;
-} OHCIPCIState;
-
-static void ohci_mapfunc(PCIDevice *pci_dev, int i,
- uint32_t addr, uint32_t size, int type)
-{
- OHCIPCIState *ohci = (OHCIPCIState *)pci_dev;
- ohci->state.mem_base = addr;
- cpu_register_physical_memory(addr, size, ohci->state.mem);
-}
-
-void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn)
-{
- OHCIPCIState *ohci;
- int vid = 0x106b;
- int did = 0x003f;
-
- ohci = (OHCIPCIState *)pci_register_device(bus, "OHCI USB", sizeof(*ohci),
- devfn, NULL, NULL);
- if (ohci == NULL) {
- fprintf(stderr, "usb-ohci: Failed to register PCI device\n");
- return;
- }
-
- ohci->pci_dev.config[0x00] = vid & 0xff;
- ohci->pci_dev.config[0x01] = (vid >> 8) & 0xff;
- ohci->pci_dev.config[0x02] = did & 0xff;
- ohci->pci_dev.config[0x03] = (did >> 8) & 0xff;
- ohci->pci_dev.config[0x09] = 0x10; /* OHCI */
- ohci->pci_dev.config[0x0a] = 0x3;
- ohci->pci_dev.config[0x0b] = 0xc;
- ohci->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
-
- usb_ohci_init(&ohci->state, num_ports, devfn, ohci->pci_dev.irq[0],
- OHCI_TYPE_PCI, ohci->pci_dev.name);
-
- pci_register_io_region((struct PCIDevice *)ohci, 0, 256,
- PCI_ADDRESS_SPACE_MEM, ohci_mapfunc);
-}
-
-void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
- qemu_irq irq)
-{
- OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
-
- usb_ohci_init(ohci, num_ports, devfn, irq,
- OHCI_TYPE_PXA, "OHCI USB");
- ohci->mem_base = base;
-
- cpu_register_physical_memory(ohci->mem_base, 0x1000, ohci->mem);
-}
diff --git a/hw/usb.c b/hw/usb.c
deleted file mode 100644
index c17266d..0000000
--- a/hw/usb.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * QEMU USB emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * 2008 Generic packet handler rewrite by Max Krasnyansky
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "usb.h"
-
-void usb_attach(USBPort *port, USBDevice *dev)
-{
- port->attach(port, dev);
-}
-
-/**********************/
-
-/* generic USB device helpers (you are not forced to use them when
- writing your USB device driver, but they help handling the
- protocol)
-*/
-
-#define SETUP_STATE_IDLE 0
-#define SETUP_STATE_DATA 1
-#define SETUP_STATE_ACK 2
-
-static int do_token_setup(USBDevice *s, USBPacket *p)
-{
- int request, value, index;
- int ret = 0;
-
- if (p->len != 8)
- return USB_RET_STALL;
-
- memcpy(s->setup_buf, p->data, 8);
- s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
- s->setup_index = 0;
-
- request = (s->setup_buf[0] << 8) | s->setup_buf[1];
- value = (s->setup_buf[3] << 8) | s->setup_buf[2];
- index = (s->setup_buf[5] << 8) | s->setup_buf[4];
-
- if (s->setup_buf[0] & USB_DIR_IN) {
- ret = s->handle_control(s, request, value, index,
- s->setup_len, s->data_buf);
- if (ret < 0)
- return ret;
-
- if (ret < s->setup_len)
- s->setup_len = ret;
- s->setup_state = SETUP_STATE_DATA;
- } else {
- if (s->setup_len == 0)
- s->setup_state = SETUP_STATE_ACK;
- else
- s->setup_state = SETUP_STATE_DATA;
- }
-
- return ret;
-}
-
-static int do_token_in(USBDevice *s, USBPacket *p)
-{
- int request, value, index;
- int ret = 0;
-
- if (p->devep != 0)
- return s->handle_data(s, p);
-
- request = (s->setup_buf[0] << 8) | s->setup_buf[1];
- value = (s->setup_buf[3] << 8) | s->setup_buf[2];
- index = (s->setup_buf[5] << 8) | s->setup_buf[4];
-
- switch(s->setup_state) {
- case SETUP_STATE_ACK:
- if (!(s->setup_buf[0] & USB_DIR_IN)) {
- s->setup_state = SETUP_STATE_IDLE;
- ret = s->handle_control(s, request, value, index,
- s->setup_len, s->data_buf);
- if (ret > 0)
- return 0;
- return ret;
- }
-
- /* return 0 byte */
- return 0;
-
- case SETUP_STATE_DATA:
- if (s->setup_buf[0] & USB_DIR_IN) {
- int len = s->setup_len - s->setup_index;
- if (len > p->len)
- len = p->len;
- memcpy(p->data, s->data_buf + s->setup_index, len);
- s->setup_index += len;
- if (s->setup_index >= s->setup_len)
- s->setup_state = SETUP_STATE_ACK;
- return len;
- }
-
- s->setup_state = SETUP_STATE_IDLE;
- return USB_RET_STALL;
-
- default:
- return USB_RET_STALL;
- }
-}
-
-static int do_token_out(USBDevice *s, USBPacket *p)
-{
- if (p->devep != 0)
- return s->handle_data(s, p);
-
- switch(s->setup_state) {
- case SETUP_STATE_ACK:
- if (s->setup_buf[0] & USB_DIR_IN) {
- s->setup_state = SETUP_STATE_IDLE;
- /* transfer OK */
- } else {
- /* ignore additional output */
- }
- return 0;
-
- case SETUP_STATE_DATA:
- if (!(s->setup_buf[0] & USB_DIR_IN)) {
- int len = s->setup_len - s->setup_index;
- if (len > p->len)
- len = p->len;
- memcpy(s->data_buf + s->setup_index, p->data, len);
- s->setup_index += len;
- if (s->setup_index >= s->setup_len)
- s->setup_state = SETUP_STATE_ACK;
- return len;
- }
-
- s->setup_state = SETUP_STATE_IDLE;
- return USB_RET_STALL;
-
- default:
- return USB_RET_STALL;
- }
-}
-
-/*
- * Generic packet handler.
- * Called by the HC (host controller).
- *
- * Returns length of the transaction or one of the USB_RET_XXX codes.
- */
-int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
-{
- switch(p->pid) {
- case USB_MSG_ATTACH:
- s->state = USB_STATE_ATTACHED;
- return 0;
-
- case USB_MSG_DETACH:
- s->state = USB_STATE_NOTATTACHED;
- return 0;
-
- case USB_MSG_RESET:
- s->remote_wakeup = 0;
- s->addr = 0;
- s->state = USB_STATE_DEFAULT;
- s->handle_reset(s);
- return 0;
- }
-
- /* Rest of the PIDs must match our address */
- if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
- return USB_RET_NODEV;
-
- switch (p->pid) {
- case USB_TOKEN_SETUP:
- return do_token_setup(s, p);
-
- case USB_TOKEN_IN:
- return do_token_in(s, p);
-
- case USB_TOKEN_OUT:
- return do_token_out(s, p);
-
- default:
- return USB_RET_STALL;
- }
-}
-
-/* XXX: fix overflow */
-int set_usb_string(uint8_t *buf, const char *str)
-{
- int len, i;
- uint8_t *q;
-
- q = buf;
- len = strlen(str);
- *q++ = 2 * len + 2;
- *q++ = 3;
- for(i = 0; i < len; i++) {
- *q++ = str[i];
- *q++ = 0;
- }
- return q - buf;
-}
-
-/* Send an internal message to a USB device. */
-void usb_send_msg(USBDevice *dev, int msg)
-{
- USBPacket p;
- memset(&p, 0, sizeof(p));
- p.pid = msg;
- dev->handle_packet(dev, &p);
-
- /* This _must_ be synchronous */
-}
diff --git a/hw/usb.h b/hw/usb.h
deleted file mode 100644
index 1a353bb..0000000
--- a/hw/usb.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * QEMU USB API
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define USB_TOKEN_SETUP 0x2d
-#define USB_TOKEN_IN 0x69 /* device -> host */
-#define USB_TOKEN_OUT 0xe1 /* host -> device */
-
-/* specific usb messages, also sent in the 'pid' parameter */
-#define USB_MSG_ATTACH 0x100
-#define USB_MSG_DETACH 0x101
-#define USB_MSG_RESET 0x102
-
-#define USB_RET_NODEV (-1)
-#define USB_RET_NAK (-2)
-#define USB_RET_STALL (-3)
-#define USB_RET_BABBLE (-4)
-#define USB_RET_ASYNC (-5)
-
-#define USB_SPEED_LOW 0
-#define USB_SPEED_FULL 1
-#define USB_SPEED_HIGH 2
-
-#define USB_STATE_NOTATTACHED 0
-#define USB_STATE_ATTACHED 1
-//#define USB_STATE_POWERED 2
-#define USB_STATE_DEFAULT 3
-//#define USB_STATE_ADDRESS 4
-//#define USB_STATE_CONFIGURED 5
-#define USB_STATE_SUSPENDED 6
-
-#define USB_CLASS_AUDIO 1
-#define USB_CLASS_COMM 2
-#define USB_CLASS_HID 3
-#define USB_CLASS_PHYSICAL 5
-#define USB_CLASS_STILL_IMAGE 6
-#define USB_CLASS_PRINTER 7
-#define USB_CLASS_MASS_STORAGE 8
-#define USB_CLASS_HUB 9
-#define USB_CLASS_CDC_DATA 0x0a
-#define USB_CLASS_CSCID 0x0b
-#define USB_CLASS_CONTENT_SEC 0x0d
-#define USB_CLASS_APP_SPEC 0xfe
-#define USB_CLASS_VENDOR_SPEC 0xff
-
-#define USB_DIR_OUT 0
-#define USB_DIR_IN 0x80
-
-#define USB_TYPE_MASK (0x03 << 5)
-#define USB_TYPE_STANDARD (0x00 << 5)
-#define USB_TYPE_CLASS (0x01 << 5)
-#define USB_TYPE_VENDOR (0x02 << 5)
-#define USB_TYPE_RESERVED (0x03 << 5)
-
-#define USB_RECIP_MASK 0x1f
-#define USB_RECIP_DEVICE 0x00
-#define USB_RECIP_INTERFACE 0x01
-#define USB_RECIP_ENDPOINT 0x02
-#define USB_RECIP_OTHER 0x03
-
-#define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define InterfaceRequest \
- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define InterfaceOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-#define EndpointOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-
-#define USB_REQ_GET_STATUS 0x00
-#define USB_REQ_CLEAR_FEATURE 0x01
-#define USB_REQ_SET_FEATURE 0x03
-#define USB_REQ_SET_ADDRESS 0x05
-#define USB_REQ_GET_DESCRIPTOR 0x06
-#define USB_REQ_SET_DESCRIPTOR 0x07
-#define USB_REQ_GET_CONFIGURATION 0x08
-#define USB_REQ_SET_CONFIGURATION 0x09
-#define USB_REQ_GET_INTERFACE 0x0A
-#define USB_REQ_SET_INTERFACE 0x0B
-#define USB_REQ_SYNCH_FRAME 0x0C
-
-#define USB_DEVICE_SELF_POWERED 0
-#define USB_DEVICE_REMOTE_WAKEUP 1
-
-#define USB_DT_DEVICE 0x01
-#define USB_DT_CONFIG 0x02
-#define USB_DT_STRING 0x03
-#define USB_DT_INTERFACE 0x04
-#define USB_DT_ENDPOINT 0x05
-
-#define USB_ENDPOINT_XFER_CONTROL 0
-#define USB_ENDPOINT_XFER_ISOC 1
-#define USB_ENDPOINT_XFER_BULK 2
-#define USB_ENDPOINT_XFER_INT 3
-
-typedef struct USBPort USBPort;
-typedef struct USBDevice USBDevice;
-typedef struct USBPacket USBPacket;
-
-/* definition of a USB device */
-struct USBDevice {
- void *opaque;
-
- /*
- * Process USB packet.
- * Called by the HC (Host Controller).
- *
- * Returns length of the transaction
- * or one of the USB_RET_XXX codes.
- */
- int (*handle_packet)(USBDevice *dev, USBPacket *p);
-
- /*
- * Called when device is destroyed.
- */
- void (*handle_destroy)(USBDevice *dev);
-
- int speed;
-
- /* The following fields are used by the generic USB device
- layer. They are here just to avoid creating a new structure
- for them. */
-
- /*
- * Reset the device
- */
- void (*handle_reset)(USBDevice *dev);
-
- /*
- * Process control request.
- * Called from handle_packet().
- *
- * Returns length or one of the USB_RET_ codes.
- */
- int (*handle_control)(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data);
-
- /*
- * Process data transfers (both BULK and ISOC).
- * Called from handle_packet().
- *
- * Returns length or one of the USB_RET_ codes.
- */
- int (*handle_data)(USBDevice *dev, USBPacket *p);
-
- uint8_t addr;
- char devname[32];
-
- int state;
- uint8_t setup_buf[8];
- uint8_t data_buf[1024];
- int remote_wakeup;
- int setup_state;
- int setup_len;
- int setup_index;
-};
-
-typedef void (*usb_attachfn)(USBPort *port, USBDevice *dev);
-
-/* USB port on which a device can be connected */
-struct USBPort {
- USBDevice *dev;
- usb_attachfn attach;
- void *opaque;
- int index; /* internal port index, may be used with the opaque */
- struct USBPort *next; /* Used internally by qemu. */
-};
-
-typedef void USBCallback(USBPacket * packet, void *opaque);
-
-/* Structure used to hold information about an active USB packet. */
-struct USBPacket {
- /* Data fields for use by the driver. */
- int pid;
- uint8_t devaddr;
- uint8_t devep;
- uint8_t *data;
- int len;
- /* Internal use by the USB layer. */
- USBCallback *complete_cb;
- void *complete_opaque;
- USBCallback *cancel_cb;
- void *cancel_opaque;
-};
-
-/* Defer completion of a USB packet. The hadle_packet routine should then
- return USB_RET_ASYNC. Packets that complete immediately (before
- handle_packet returns) should not call this method. */
-static inline void usb_defer_packet(USBPacket *p, USBCallback *cancel,
- void * opaque)
-{
- p->cancel_cb = cancel;
- p->cancel_opaque = opaque;
-}
-
-/* Notify the controller that an async packet is complete. This should only
- be called for packets previously deferred with usb_defer_packet, and
- should never be called from within handle_packet. */
-static inline void usb_packet_complete(USBPacket *p)
-{
- p->complete_cb(p, p->complete_opaque);
-}
-
-/* Cancel an active packet. The packed must have been deferred with
- usb_defer_packet, and not yet completed. */
-static inline void usb_cancel_packet(USBPacket * p)
-{
- p->cancel_cb(p, p->cancel_opaque);
-}
-
-int usb_device_add_dev(USBDevice *dev);
-int usb_device_del_addr(int bus_num, int addr);
-void usb_attach(USBPort *port, USBDevice *dev);
-int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
-int set_usb_string(uint8_t *buf, const char *str);
-void usb_send_msg(USBDevice *dev, int msg);
-
-/* usb hub */
-USBDevice *usb_hub_init(int nb_ports);
-
-/* usb-linux.c */
-USBDevice *usb_host_device_open(const char *devname);
-int usb_host_device_close(const char *devname);
-void usb_host_info(void);
-
-/* usb-hid.c */
-USBDevice *usb_mouse_init(void);
-USBDevice *usb_tablet_init(void);
-USBDevice *usb_keyboard_init(void);
-
-/* usb-msd.c */
-USBDevice *usb_msd_init(const char *filename);
-
-/* usb-net.c */
-USBDevice *usb_net_init(NICInfo *nd);
-
-/* usb-wacom.c */
-USBDevice *usb_wacom_init(void);
-
-/* usb-serial.c */
-USBDevice *usb_serial_init(const char *filename);
-
-/* usb ports of the VM */
-
-void qemu_register_usb_port(USBPort *port, void *opaque, int index,
- usb_attachfn attach);
-
-#define VM_USB_HUB_SIZE 8
-
-/* usb-musb.c */
-enum musb_irq_source_e {
- musb_irq_suspend = 0,
- musb_irq_resume,
- musb_irq_rst_babble,
- musb_irq_sof,
- musb_irq_connect,
- musb_irq_disconnect,
- musb_irq_vbus_request,
- musb_irq_vbus_error,
- musb_irq_rx,
- musb_irq_tx,
- musb_set_vbus,
- musb_set_session,
- __musb_irq_max,
-};
-
-struct musb_s;
-struct musb_s *musb_init(qemu_irq *irqs);
-uint32_t musb_core_intr_get(struct musb_s *s);
-void musb_core_intr_clear(struct musb_s *s, uint32_t mask);
-void musb_set_size(struct musb_s *s, int epnum, int size, int is_tx);