on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
-
+
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
(Johannes Schindelin)
version 0.7.2:
-
+
- x86_64 fixes (Win2000 and Linux 2.6 boot in 32 bit)
- merge self modifying code handling in dirty ram page mecanism.
- MIPS fixes (Ralf Baechle)
- Mac OS X port (Pierre d'Herbemont)
- Virtual console support
- Better monitor line edition
- - New block device layer
+ - New block device layer
- New 'qcow' growable disk image support with AES encryption and
transparent decompression
- VMware 3 and 4 read-only disk image support (untested)
- FDC fixes for Win98
version 0.5.4:
-
+
- qemu-fast fixes
- BIOS area protection fix (aka EMM386.EXE fix) (Mike Nordell)
- keyboard/mouse fix (Mike Nordell)
- added accurate CR0.MP/ME/TS emulation
- fixed DMA memory write access (Win95 boot floppy fix)
- graphical x86 linux loader
- - command line monitor
+ - command line monitor
- generic removable device support
- support of CD-ROM change
- multiple network interface support
- eflags optimisation fix for string operations
version 0.5.1:
-
+
- float access fixes when using soft mmu
- PC emulation support on PowerPC
- A20 support
- Major SPARC target fixes (dynamically linked programs begin to work)
version 0.5.0:
-
+
- full hardware level VGA emulation
- graphical display with SDL
- added PS/2 mouse and keyboard emulation
- SMP kernels can at least be booted
version 0.4.1:
-
+
- more accurate timer support in vl.
- more reliable NE2000 probe in vl.
- added 2.5.66 kernel in vl-test.
- added bound, cmpxchg8b, cpuid instructions
- added 16 bit addressing support/override for string operations
- poll() fix
-
+
version 0.1.2:
- compile fixes
clean:
# avoid old build problems by removing potentially incorrect old files
- rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
+ rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
$(MAKE) -C tests clean
for d in $(TARGET_DIRS); do \
test speed test2: all
$(MAKE) -C tests $@
-TAGS:
+TAGS:
etags *.[ch] tests/*.[ch]
cscope:
# cpu emulator library
LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\
- translate.o op.o
+ translate.o op.o
ifdef CONFIG_SOFTFLOAT
LIBOBJS+=fpu/softfloat.o
else
endif
# NOTE: the disassembler code is only needed for debugging
-LIBOBJS+=disas.o
+LIBOBJS+=disas.o
ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
USE_I386_DIS=y
endif
VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
endif
ifdef CONFIG_GDBSTUB
-VL_OBJS+=gdbstub.o
+VL_OBJS+=gdbstub.o
endif
ifdef CONFIG_SDL
VL_OBJS+=sdl.o x_keymap.o
VL_LDFLAGS+=-static
endif
ifndef CONFIG_SOFTMMU
-VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386-vl.ld
+VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386-vl.ld
endif
ifndef CONFIG_DARWIN
ifndef CONFIG_WIN32
vldepend: $(VL_OBJS:.o=.c)
$(CC) -MM $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $^ 1>.depend
-# libqemu
+# libqemu
libqemu.a: $(LIBOBJS)
rm -f $@
clean:
rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o fpu/*.o
-install: all
+install: all
ifneq ($(PROGS),)
$(INSTALL) -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)"
endif
- do not resize vga if invalid size.
- avoid looping if only exceptions
- TLB code protection support for PPC
-- see openMosix Doc
+- see openMosix Doc
- disable SMC handling for ARM/SPARC/PPC (not finished)
- see undefined flags for BTx insn
- user/kernel PUSHL/POPL in helper.c
/**
- *
+ *
* aes.c - integrated in QEMU by Fabrice Bellard from the OpenSSL project.
*/
/*
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc)
+ unsigned char *ivec, const int enc)
{
unsigned long n;
AES_encrypt(tmp, tmp, key);
memcpy(out, tmp, AES_BLOCK_SIZE);
memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
+ }
} else {
while (len >= AES_BLOCK_SIZE) {
memcpy(tmp, in, AES_BLOCK_SIZE);
for(n=0; n < len; ++n)
out[n] = tmp[n] ^ ivec[n];
memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
+ }
}
}
/* The signed "23-bit" aligned displacement of Branch format insns */
#define BDISP (MDISP + 1)
- { 21, 0, BFD_RELOC_23_PCREL_S2,
+ { 21, 0, BFD_RELOC_23_PCREL_S2,
AXP_OPERAND_RELATIVE, insert_bdisp, extract_bdisp },
/* The 26-bit PALcode function */
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
Modification by James G. Smith (jsmith@cygnus.co.uk)
-This file is part of libopcodes.
+This file is part of libopcodes.
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.
+any later version.
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.
+more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
};
/* format of the assembler string :
-
+
%% %
%<bitfield>d print the bitfield in decimal
%<bitfield>x print the bitfield in hex
{0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
{0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
{0xf450f000, 0xfc70f000, "pld\t%a"},
-
+
/* V5 Instructions. */
{0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
{0xfa000000, 0xfe000000, "blx\t%B"},
{0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
{0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
- /* V5E "El Segundo" Instructions. */
+ /* V5E "El Segundo" Instructions. */
{0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
{0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
{0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
{0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
{0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
{0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
- {0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
+ {0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
{0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
{0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
{0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
static char * arm_fp_const[] =
{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
-static char * arm_shift[] =
+static char * arm_shift[] =
{"lsl", "lsr", "asr", "ror"};
\f
/* Forward declarations. */
void * stream;
{
func (stream, "%s", arm_regnames[given & 0xf]);
-
+
if ((given & 0xff0) != 0)
{
if ((given & 0x10) == 0)
{
int amount = (given & 0xf80) >> 7;
int shift = (given & 0x60) >> 5;
-
+
if (amount == 0)
{
if (shift == 3)
func (stream, ", rrx");
return;
}
-
+
amount = 32;
}
-
+
func (stream, ", %s #%d", arm_shift[shift], amount);
}
else
if ((given & insn->mask) == insn->value)
{
char * c;
-
+
for (c = insn->assembler; *c; c++)
{
if (*c == '%')
&& ((given & 0x02000000) == 0))
{
int offset = given & 0xfff;
-
+
func (stream, "[pc");
-
+
if (given & 0x01000000)
{
if ((given & 0x00800000) == 0)
offset = - offset;
-
+
/* Pre-indexed. */
func (stream, ", #%d]", offset);
/* ie ignore the offset. */
offset = pc + 8;
}
-
+
func (stream, "\t; ");
info->print_address_func (offset, info);
}
else
{
- func (stream, "[%s",
+ func (stream, "[%s",
arm_regnames[(given >> 16) & 0xf]);
if ((given & 0x01000000) != 0)
{
arm_decode_shift (given, func, stream);
}
- func (stream, "]%s",
+ func (stream, "]%s",
((given & 0x00200000) != 0) ? "!" : "");
}
else
func (stream, "], %s#%d",
(((given & 0x00800000) == 0)
? "-" : ""), offset);
- else
+ else
func (stream, "]");
}
else
{
func (stream, "], %s",
- (((given & 0x00800000) == 0)
+ (((given & 0x00800000) == 0)
? "-" : ""));
arm_decode_shift (given, func, stream);
}
{
/* PC relative with immediate offset. */
int offset = ((given & 0xf00) >> 4) | (given & 0xf);
-
+
if ((given & 0x00800000) == 0)
offset = -offset;
-
+
func (stream, "[pc, #%d]\t; ", offset);
-
+
(*info->print_address_func)
(offset + pc + 8, info);
}
else
{
- func (stream, "[%s",
+ func (stream, "[%s",
arm_regnames[(given >> 16) & 0xf]);
if ((given & 0x01000000) != 0)
{
arm_regnames[given & 0xf]);
}
- func (stream, "]%s",
+ func (stream, "]%s",
((given & 0x00200000) != 0) ? "!" : "");
}
else
func (stream, "], %s#%d",
(((given & 0x00800000) == 0)
? "-" : ""), offset);
- else
+ else
func (stream, "]");
}
else
}
}
break;
-
+
case 'b':
(*info->print_address_func)
(BDISP (given) * 4 + pc + 8, info);
{
bfd_vma address;
bfd_vma offset = 0;
-
+
if (given & 0x00800000)
/* Is signed, hi bits should be ones. */
offset = (-1) ^ 0x00ffffff;
offset += given & 0x00ffffff;
offset <<= 2;
address = offset + pc + 8;
-
+
if (given & 0x01000000)
/* H bit allows addressing to 2-byte boundaries. */
address += 2;
func (stream, "3");
}
break;
-
+
case 'P':
switch (given & 0x00080080)
{
}
break;
- case '0': case '1': case '2': case '3': case '4':
+ case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int bitstart = *c++ - '0';
{
case '-':
c++;
-
+
while (*c >= '0' && *c <= '9')
bitend = (bitend * 10) + *c++ - '0';
-
+
if (!bitend)
abort ();
-
+
switch (*c)
{
case 'r':
{
long reg;
-
+
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
-
+
func (stream, "%s", arm_regnames[reg]);
}
break;
case 'd':
{
long reg;
-
+
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
-
+
func (stream, "%d", reg);
}
break;
case 'x':
{
long reg;
-
+
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
-
+
func (stream, "0x%08x", reg);
-
+
/* Some SWI instructions have special
meanings. */
if ((given & 0x0fffffff) == 0x0FF00000)
case 'X':
{
long reg;
-
+
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
-
+
func (stream, "%01x", reg & 0xf);
}
break;
case 'f':
{
long reg;
-
+
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
-
+
if (reg > 7)
func (stream, "#%s",
arm_fp_const[reg & 7]);
}
break;
-
+
default:
abort ();
}
if (!*c) /* Check for empty (not NULL) assembler string. */
{
long offset;
-
+
info->bytes_per_chunk = 4;
info->bytes_per_line = 4;
{
info->bytes_per_chunk = 2;
info->bytes_per_line = 4;
-
+
given &= 0xffff;
-
+
for (; *c; c++)
{
if (*c == '%')
{
int domaskpc = 0;
int domasklr = 0;
-
+
switch (*++c)
{
case '%':
case 'S':
{
long reg;
-
+
reg = (given >> 3) & 0x7;
if (given & (1 << 6))
reg += 8;
-
+
func (stream, "%s", arm_regnames[reg]);
}
break;
case 'D':
{
long reg;
-
+
reg = given & 0x7;
if (given & (1 << 7))
reg += 8;
-
+
func (stream, "%s", arm_regnames[reg]);
}
break;
{
int started = 0;
int reg;
-
+
func (stream, "{");
-
+
/* It would be nice if we could spot
ranges, and generate the rS-rE format: */
for (reg = 0; (reg < 8); reg++)
break;
- case '0': case '1': case '2': case '3': case '4':
+ case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int bitstart = *c++ - '0';
int bitend = 0;
-
+
while (*c >= '0' && *c <= '9')
bitstart = (bitstart * 10) + *c++ - '0';
case '-':
{
long reg;
-
+
c++;
while (*c >= '0' && *c <= '9')
bitend = (bitend * 10) + *c++ - '0';
{
if (option == NULL)
return;
-
+
if (strneq (option, "reg-names-", 10))
{
int i;
-
+
option += 10;
for (i = NUM_ARM_REGNAMES; i--;)
regname_selected = i;
break;
}
-
+
if (i < 0)
fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
}
force_thumb = 0;
else
fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
-
+
return;
}
char * options;
{
char * space;
-
+
if (options == NULL)
return;
if (info->disassembler_options)
{
parse_disassembler_options (info->disassembler_options);
-
+
/* To avoid repeated parsing of these options, we remove them here. */
info->disassembler_options = NULL;
}
-
+
is_thumb = force_thumb;
if (pc & 1)
{
is_thumb = 1;
pc &= ~(bfd_vma) 1;
}
-
+
#if 0
if (!is_thumb && info->symbols != NULL)
{
if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
{
coff_symbol_type * cs;
-
+
cs = coffsymbol (*info->symbols);
is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
|| cs->native->u.syment.n_sclass == C_THUMBSTAT
{
elf_symbol_type * es;
unsigned int type;
-
+
es = *(elf_symbol_type **)(info->symbols);
type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
-
+
is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
}
}
#endif
-
+
little = (info->endian == BFD_ENDIAN_LITTLE);
info->bytes_per_chunk = 4;
info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
if (status != 0 && is_thumb)
{
info->bytes_per_chunk = 2;
-
+
status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
b[3] = b[2] = 0;
}
-
+
if (status != 0)
{
info->memory_error_func (status, pc, info);
return -1;
}
-
+
given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
}
else
info->memory_error_func (status, pc, info);
return -1;
}
-
+
if (is_thumb)
{
if (pc & 0x2)
{
given = (b[2] << 8) | b[3];
-
+
status = info->read_memory_func
((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
if (status != 0)
info->memory_error_func (status, pc + 4, info);
return -1;
}
-
+
given |= (b[0] << 24) | (b[1] << 16);
}
else
else
given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
}
-
+
if (info->flags & INSN_HAS_RELOC)
/* If the instruction has a reloc associated with it, then
the offset field in the instruction will actually be the
fprintf (stream, _("\n\
The following ARM specific disassembler options are supported for use with\n\
the -M switch:\n"));
-
+
for (i = NUM_ARM_REGNAMES; i--;)
fprintf (stream, " reg-names-%s %*c%s\n",
regnames[i].name,
/*
* Arm "Angel" semihosting syscalls
- *
+ *
* Copyright (c) 2005, 2007 CodeSourcery.
* Written by Paul Brook.
*
}
ts->heap_limit = limit;
}
-
+
ptr = lock_user(ARG(0), 16, 0);
ptr[0] = tswap32(ts->heap_base);
ptr[1] = tswap32(ts->heap_limit);
if (wav->f) {
le_store (rlen, rifflen, 4);
le_store (dlen, datalen, 4);
-
+
qemu_fseek (wav->f, 4, SEEK_SET);
qemu_put_buffer (wav->f, rlen, 4);
-
+
qemu_fseek (wav->f, 32, SEEK_CUR);
qemu_put_buffer (wav->f, dlen, 4);
qemu_fclose (wav->f);
}
-
+
qemu_free (wav->path);
}
/*
* Block driver for the various disk image formats used by Bochs
* Currently only for "growing" type in read-only mode
- *
+ *
* Copyright (c) 2005 Alex Beregszaszi
- *
+ *
* 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
char subtype[16]; // "Undoable" / "Volatile" / "Growing"
uint32_t version;
uint32_t header; // size of header
-
+
union {
struct {
uint32_t catalog; // num of entries
char subtype[16]; // "Undoable" / "Volatile" / "Growing"
uint32_t version;
uint32_t header; // size of header
-
+
union {
struct {
uint32_t catalog; // num of entries
uint32_t *catalog_bitmap;
int catalog_size;
-
+
int data_offset;
-
+
int bitmap_blocks;
int extent_blocks;
int extent_size;
static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
{
const struct bochs_header *bochs = (const void *)buf;
-
+
if (buf_size < HEADER_SIZE)
return 0;
if (fd < 0)
return -1;
}
-
+
bs->read_only = 1; // no write support yet
-
+
s->fd = fd;
if (read(fd, &bochs, sizeof(bochs)) != sizeof(bochs)) {
s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512;
s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512;
-
+
s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
return 0;
// seek to sector
extent_index = offset / s->extent_size;
extent_offset = (offset % s->extent_size) / 512;
-
+
if (s->catalog_bitmap[extent_index] == 0xffffffff)
{
// fprintf(stderr, "page not allocated [%x - %x:%x]\n",
bitmap_offset = s->data_offset + (512 * s->catalog_bitmap[extent_index] *
(s->extent_blocks + s->bitmap_blocks));
block_offset = bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
-
+
// fprintf(stderr, "sect: %x [ext i: %x o: %x] -> %x bitmap: %x block: %x\n",
// sector_num, extent_index, extent_offset,
// le32_to_cpu(s->catalog_bitmap[extent_index]),
// bitmap_offset, block_offset);
-
+
// read in bitmap for current extent
lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
-
+
read(s->fd, &bitmap_entry, 1);
-
+
if (!((bitmap_entry >> (extent_offset % 8)) & 1))
{
// fprintf(stderr, "sector (%x) in bitmap not allocated\n",
}
lseek(s->fd, block_offset, SEEK_SET);
-
+
return 0;
}
-static int bochs_read(BlockDriverState *bs, int64_t sector_num,
+static int bochs_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVBochsState *s = bs->opaque;
/*
* QEMU Block driver for CLOOP images
- *
+ *
* Copyright (c) 2004 Johannes E. Schindelin
- *
+ *
* 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
if(inflateInit(&s->zstream) != Z_OK)
goto cloop_close;
s->current_block=s->n_blocks;
-
+
s->sectors_per_block = s->block_size/512;
bs->total_sectors = s->n_blocks*s->sectors_per_block;
return 0;
if(s->current_block != block_num) {
int ret;
uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
-
+
lseek(s->fd, s->offsets[block_num], SEEK_SET);
ret = read(s->fd, s->compressed_block, bytes);
- if (ret != bytes)
+ if (ret != bytes)
return -1;
-
+
s->zstream.next_in = s->compressed_block;
s->zstream.avail_in = bytes;
s->zstream.next_out = s->uncompressed_block;
ret = inflate(&s->zstream, Z_FINISH);
if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
return -1;
-
+
s->current_block = block_num;
}
return 0;
}
-static int cloop_read(BlockDriverState *bs, int64_t sector_num,
+static int cloop_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVCloopState *s = bs->opaque;
/*
* Block driver for the COW format
- *
+ *
* 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
if (buf_size >= sizeof(struct cow_header_v2) &&
be32_to_cpu(cow_header->magic) == COW_MAGIC &&
- be32_to_cpu(cow_header->version) == COW_VERSION)
+ be32_to_cpu(cow_header->version) == COW_VERSION)
return 100;
else
return 0;
be32_to_cpu(cow_header.version) != COW_VERSION) {
goto fail;
}
-
+
/* cow image found */
size = be64_to_cpu(cow_header.size);
bs->total_sectors = size / 512;
- pstrcpy(bs->backing_file, sizeof(bs->backing_file),
+ pstrcpy(bs->backing_file, sizeof(bs->backing_file),
cow_header.backing_file);
-
+
/* mmap the bitmap */
s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
- s->cow_bitmap_addr = mmap(get_mmap_addr(s->cow_bitmap_size),
- s->cow_bitmap_size,
+ s->cow_bitmap_addr = mmap(get_mmap_addr(s->cow_bitmap_size),
+ s->cow_bitmap_size,
PROT_READ | PROT_WRITE,
MAP_SHARED, s->fd, 0);
if (s->cow_bitmap_addr == MAP_FAILED)
return changed;
}
-static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
+static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum)
{
BDRVCowState *s = bs->opaque;
return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);
}
-static int cow_read(BlockDriverState *bs, int64_t sector_num,
+static int cow_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVCowState *s = bs->opaque;
int ret, n;
-
+
while (nb_sectors > 0) {
if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {
lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
ret = read(s->fd, buf, n * 512);
- if (ret != n * 512)
+ if (ret != n * 512)
return -1;
} else {
if (bs->backing_hd) {
return 0;
}
-static int cow_write(BlockDriverState *bs, int64_t sector_num,
+static int cow_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
BDRVCowState *s = bs->opaque;
int ret, i;
-
+
lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
ret = write(s->fd, buf, nb_sectors * 512);
- if (ret != nb_sectors * 512)
+ if (ret != nb_sectors * 512)
return -1;
for (i = 0; i < nb_sectors; i++)
cow_set_bit(s->cow_bitmap, sector_num + i);
if (flags)
return -ENOTSUP;
- cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+ cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
if (cow_fd < 0)
return -1;
/*
* QEMU Block driver for DMG images
- *
+ *
* Copyright (c) 2004 Johannes E. Schindelin
- *
+ *
* 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
typedef struct BDRVDMGState {
int fd;
-
+
/* each chunk contains a certain number of sectors,
* offsets[i] is the offset in the .dmg file,
* lengths[i] is the length of the compressed chunk,
bs->read_only = 1;
s->n_chunks = 0;
s->offsets = s->lengths = s->sectors = s->sectorcounts = 0;
-
+
/* read offset of info blocks */
if(lseek(s->fd,-0x1d8,SEEK_END)<0) {
dmg_close:
goto dmg_close;
s->current_chunk = s->n_chunks;
-
+
return 0;
}
if (ret != s->lengths[chunk])
return -1;
-
+
s->zstream.next_in = s->compressed_chunk;
s->zstream.avail_in = s->lengths[chunk];
s->zstream.next_out = s->uncompressed_chunk;
return 0;
}
-static int dmg_read(BlockDriverState *bs, int64_t sector_num,
+static int dmg_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVDMGState *s = bs->opaque;
/*
* Block driver for the QCOW format
- *
+ *
* Copyright (c) 2004-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
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
{
const QCowHeader *cow_header = (const void *)buf;
-
+
if (buf_size >= sizeof(QCowHeader) &&
be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) == QCOW_VERSION)
+ be32_to_cpu(cow_header->version) == QCOW_VERSION)
return 100;
else
return 0;
be64_to_cpus(&header.size);
be32_to_cpus(&header.crypt_method);
be64_to_cpus(&header.l1_table_offset);
-
+
if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
goto fail;
if (header.size <= 1 || header.cluster_bits < 9)
s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
if (!s->l1_table)
goto fail;
- if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
+ if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
s->l1_size * sizeof(uint64_t))
goto fail;
for(i = 0;i < s->l1_size; i++) {
if (!s->cluster_data)
goto fail;
s->cluster_cache_offset = -1;
-
+
/* read the backing file name */
if (header.backing_file_offset != 0) {
len = header.backing_file_size;
BDRVQcowState *s = bs->opaque;
uint8_t keybuf[16];
int len, i;
-
+
memset(keybuf, 0, 16);
len = strlen(key);
if (len > 16)
for(i = 0; i < nb_sectors; i++) {
ivec.ll[0] = cpu_to_le64(sector_num);
ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
+ AES_cbc_encrypt(in_buf, out_buf, 512, key,
ivec.b, enc);
sector_num++;
in_buf += 512;
*
* 2 to allocate a compressed cluster of size
* 'compressed_size'. 'compressed_size' must be > 0 and <
- * cluster_size
+ * cluster_size
*
* return 0 if not allocated.
*/
uint64_t l2_offset, *l2_table, cluster_offset, tmp;
uint32_t min_count;
int new_l2_table;
-
+
l1_index = offset >> (s->l2_bits + s->cluster_bits);
l2_offset = s->l1_table[l1_index];
new_l2_table = 0;
/* update the L1 entry */
s->l1_table[l1_index] = l2_offset;
tmp = cpu_to_be64(l2_offset);
- if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
+ if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
&tmp, sizeof(tmp)) != sizeof(tmp))
return 0;
new_l2_table = 1;
s->l2_size * sizeof(uint64_t))
return 0;
} else {
- if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
+ if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
s->l2_size * sizeof(uint64_t))
return 0;
}
found:
l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
cluster_offset = be64_to_cpu(l2_table[l2_index]);
- if (!cluster_offset ||
+ if (!cluster_offset ||
((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
if (!allocate)
return 0;
if (decompress_cluster(s, cluster_offset) < 0)
return 0;
cluster_offset = bdrv_getlength(s->hd);
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
+ cluster_offset = (cluster_offset + s->cluster_size - 1) &
~(s->cluster_size - 1);
/* write the cluster content */
- if (bdrv_pwrite(s->hd, cluster_offset, s->cluster_cache, s->cluster_size) !=
+ if (bdrv_pwrite(s->hd, cluster_offset, s->cluster_cache, s->cluster_size) !=
s->cluster_size)
return -1;
} else {
cluster_offset = bdrv_getlength(s->hd);
if (allocate == 1) {
/* round to cluster size */
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
+ cluster_offset = (cluster_offset + s->cluster_size - 1) &
~(s->cluster_size - 1);
bdrv_truncate(s->hd, cluster_offset + s->cluster_size);
/* if encrypted, we must initialize the cluster
content which won't be written */
- if (s->crypt_method &&
+ if (s->crypt_method &&
(n_end - n_start) < s->cluster_sectors) {
uint64_t start_sect;
start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
memset(s->cluster_data + 512, 0x00, 512);
for(i = 0; i < s->cluster_sectors; i++) {
if (i < n_start || i >= n_end) {
- encrypt_sectors(s, start_sect + i,
- s->cluster_data,
+ encrypt_sectors(s, start_sect + i,
+ s->cluster_data,
s->cluster_data + 512, 1, 1,
&s->aes_encrypt_key);
- if (bdrv_pwrite(s->hd, cluster_offset + i * 512,
+ if (bdrv_pwrite(s->hd, cluster_offset + i * 512,
s->cluster_data, 512) != 512)
return -1;
}
}
}
} else {
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
+ cluster_offset |= QCOW_OFLAG_COMPRESSED |
(uint64_t)compressed_size << (63 - s->cluster_bits);
}
}
/* update L2 table */
tmp = cpu_to_be64(cluster_offset);
l2_table[l2_index] = tmp;
- if (bdrv_pwrite(s->hd,
+ if (bdrv_pwrite(s->hd,
l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp))
return 0;
}
return cluster_offset;
}
-static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
+static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum)
{
BDRVQcowState *s = bs->opaque;
inflateEnd(strm);
return 0;
}
-
+
static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
{
int ret, csize;
csize = cluster_offset >> (63 - s->cluster_bits);
csize &= (s->cluster_size - 1);
ret = bdrv_pread(s->hd, coffset, s->cluster_data, csize);
- if (ret != csize)
+ if (ret != csize)
return -1;
if (decompress_buffer(s->cluster_cache, s->cluster_size,
s->cluster_data, csize) < 0) {
#if 0
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
+static int qcow_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVQcowState *s = bs->opaque;
int ret, index_in_cluster, n;
uint64_t cluster_offset;
-
+
while (nb_sectors > 0) {
cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
index_in_cluster = sector_num & (s->cluster_sectors - 1);
memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
} else {
ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- if (ret != n * 512)
+ if (ret != n * 512)
return -1;
if (s->crypt_method) {
- encrypt_sectors(s, sector_num, buf, buf, n, 0,
+ encrypt_sectors(s, sector_num, buf, buf, n, 0,
&s->aes_decrypt_key);
}
}
}
#endif
-static int qcow_write(BlockDriverState *bs, int64_t sector_num,
+static int qcow_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
BDRVQcowState *s = bs->opaque;
int ret, index_in_cluster, n;
uint64_t cluster_offset;
-
+
while (nb_sectors > 0) {
index_in_cluster = sector_num & (s->cluster_sectors - 1);
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
- index_in_cluster,
+ cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
+ index_in_cluster,
index_in_cluster + n);
if (!cluster_offset)
return -1;
if (s->crypt_method) {
encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
&s->aes_encrypt_key);
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
+ ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
s->cluster_data, n * 512);
} else {
ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
}
- if (ret != n * 512)
+ if (ret != n * 512)
return -1;
nb_sectors -= n;
sector_num += n;
int nb_sectors;
int n;
uint64_t cluster_offset;
- uint8_t *cluster_data;
+ uint8_t *cluster_data;
BlockDriverAIOCB *hd_aiocb;
} QCowAIOCB;
/* nothing to do */
} else {
if (s->crypt_method) {
- encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
- acb->n, 0,
+ encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
+ acb->n, 0,
&s->aes_decrypt_key);
}
}
qemu_aio_release(acb);
return;
}
-
+
/* prepare next AIO request */
- acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
+ acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
0, 0, 0, 0);
index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
acb->n = s->cluster_sectors - index_in_cluster;
/* add AIO support for compressed blocks ? */
if (decompress_cluster(s, acb->cluster_offset) < 0)
goto fail;
- memcpy(acb->buf,
+ memcpy(acb->buf,
s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
goto redo;
} else {
goto fail;
}
acb->hd_aiocb = bdrv_aio_read(s->hd,
- (acb->cluster_offset >> 9) + index_in_cluster,
+ (acb->cluster_offset >> 9) + index_in_cluster,
acb->buf, acb->n, qcow_aio_read_cb, acb);
if (acb->hd_aiocb == NULL)
goto fail;
acb->buf = buf;
acb->nb_sectors = nb_sectors;
acb->n = 0;
- acb->cluster_offset = 0;
+ acb->cluster_offset = 0;
qcow_aio_read_cb(acb, 0);
return &acb->common;
qemu_aio_release(acb);
return;
}
-
+
index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
acb->n = s->cluster_sectors - index_in_cluster;
if (acb->n > acb->nb_sectors)
acb->n = acb->nb_sectors;
- cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
- index_in_cluster,
+ cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
+ index_in_cluster,
index_in_cluster + acb->n);
if (!cluster_offset || (cluster_offset & 511) != 0) {
ret = -EIO;
goto fail;
}
}
- encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
+ encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
acb->n, 1, &s->aes_encrypt_key);
src_buf = acb->cluster_data;
} else {
src_buf = acb->buf;
}
acb->hd_aiocb = bdrv_aio_write(s->hd,
- (cluster_offset >> 9) + index_in_cluster,
- src_buf, acb->n,
+ (cluster_offset >> 9) + index_in_cluster,
+ src_buf, acb->n,
qcow_aio_write_cb, acb);
if (acb->hd_aiocb == NULL)
goto fail;
{
BDRVQcowState *s = bs->opaque;
QCowAIOCB *acb;
-
+
s->cluster_cache_offset = -1; /* disable compressed cache */
acb = qemu_aio_get(bs, cb, opaque);
acb->buf = (uint8_t *)buf;
acb->nb_sectors = nb_sectors;
acb->n = 0;
-
+
qcow_aio_write_cb(acb, 0);
return &acb->common;
}
} else {
header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
}
-
+
/* write all the data */
write(fd, &header, sizeof(header));
if (backing_file) {
/* XXX: put compressed sectors first, then all the cluster aligned
tables to avoid losing bytes in alignment */
-static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
+static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
BDRVQcowState *s = bs->opaque;
/* best compression, small window, no zlib header */
memset(&strm, 0, sizeof(strm));
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
+ Z_DEFLATED, -12,
9, Z_DEFAULT_STRATEGY);
if (ret != 0) {
qemu_free(out_buf);
/* could not compress: write normal cluster */
qcow_write(bs, sector_num, buf, s->cluster_sectors);
} else {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
+ cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
out_len, 0, 0);
cluster_offset &= s->cluster_offset_mask;
if (bdrv_pwrite(s->hd, cluster_offset, out_buf, out_len) != out_len) {
return -1;
}
}
-
+
qemu_free(out_buf);
return 0;
}
/*
* Block driver for the QCOW version 2 format
- *
+ *
* Copyright (c) 2004-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
- Memory management by reference counts.
- Clusters which have a reference count of one have the bit
QCOW_OFLAG_COPIED to optimize write performance.
- - Size of compressed clusters is stored in sectors to reduce bit usage
+ - Size of compressed clusters is stored in sectors to reduce bit usage
in the cluster offsets.
- Support for storing additional data (such as the VM state) in the
- snapshots.
+ snapshots.
- If a backing store is used, the cluster size is not constrained
(could be backported to QCOW).
- L2 tables have always a size of one cluster.
//#define DEBUG_ALLOC
//#define DEBUG_ALLOC2
-
+
#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
#define QCOW_VERSION 2
} BDRVQcowState;
static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
+static int qcow_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors);
static int qcow_read_snapshots(BlockDriverState *bs);
static void qcow_free_snapshots(BlockDriverState *bs);
static int refcount_init(BlockDriverState *bs);
static void refcount_close(BlockDriverState *bs);
static int get_refcount(BlockDriverState *bs, int64_t cluster_index);
-static int update_cluster_refcount(BlockDriverState *bs,
+static int update_cluster_refcount(BlockDriverState *bs,
int64_t cluster_index,
int addend);
-static void update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length,
+static void update_refcount(BlockDriverState *bs,
+ int64_t offset, int64_t length,
int addend);
static int64_t alloc_clusters(BlockDriverState *bs, int64_t size);
static int64_t alloc_bytes(BlockDriverState *bs, int size);
-static void free_clusters(BlockDriverState *bs,
+static void free_clusters(BlockDriverState *bs,
int64_t offset, int64_t size);
#ifdef DEBUG_ALLOC
static void check_refcounts(BlockDriverState *bs);
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
{
const QCowHeader *cow_header = (const void *)buf;
-
+
if (buf_size >= sizeof(QCowHeader) &&
be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) == QCOW_VERSION)
+ be32_to_cpu(cow_header->version) == QCOW_VERSION)
return 100;
else
return 0;
be32_to_cpus(&header.refcount_table_clusters);
be64_to_cpus(&header.snapshots_offset);
be32_to_cpus(&header.nb_snapshots);
-
+
if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
goto fail;
- if (header.size <= 1 ||
- header.cluster_bits < 9 ||
+ if (header.size <= 1 ||
+ header.cluster_bits < 9 ||
header.cluster_bits > 16)
goto fail;
if (header.crypt_method > QCOW_CRYPT_AES)
s->csize_mask = (1 << (s->cluster_bits - 8)) - 1;
s->cluster_offset_mask = (1LL << s->csize_shift) - 1;
s->refcount_table_offset = header.refcount_table_offset;
- s->refcount_table_size =
+ s->refcount_table_size =
header.refcount_table_clusters << (s->cluster_bits - 3);
s->snapshots_offset = header.snapshots_offset;
s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
if (!s->l1_table)
goto fail;
- if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
+ if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
s->l1_size * sizeof(uint64_t))
goto fail;
for(i = 0;i < s->l1_size; i++) {
if (!s->cluster_data)
goto fail;
s->cluster_cache_offset = -1;
-
+
if (refcount_init(bs) < 0)
goto fail;
BDRVQcowState *s = bs->opaque;
uint8_t keybuf[16];
int len, i;
-
+
memset(keybuf, 0, 16);
len = strlen(key);
if (len > 16)
for(i = 0; i < nb_sectors; i++) {
ivec.ll[0] = cpu_to_le64(sector_num);
ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
+ AES_cbc_encrypt(in_buf, out_buf, 512, key,
ivec.b, enc);
sector_num++;
in_buf += 512;
if (ret < 0)
return ret;
if (s->crypt_method) {
- encrypt_sectors(s, start_sect + n_start,
- s->cluster_data,
+ encrypt_sectors(s, start_sect + n_start,
+ s->cluster_data,
s->cluster_data, n, 1,
&s->aes_encrypt_key);
}
- ret = bdrv_write(s->hd, (cluster_offset >> 9) + n_start,
+ ret = bdrv_write(s->hd, (cluster_offset >> 9) + n_start,
s->cluster_data, n);
if (ret < 0)
return ret;
/* write new table (align to cluster) */
new_l1_table_offset = alloc_clusters(bs, new_l1_size2);
-
+
for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
ret = bdrv_pwrite(s->hd, new_l1_table_offset, new_l1_table, new_l1_size2);
goto fail;
for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
-
+
/* set new table */
data64 = cpu_to_be64(new_l1_table_offset);
if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_table_offset),
*
* 2 to allocate a compressed cluster of size
* 'compressed_size'. 'compressed_size' must be > 0 and <
- * cluster_size
+ * cluster_size
*
* return 0 if not allocated.
*/
BDRVQcowState *s = bs->opaque;
int min_index, i, j, l1_index, l2_index, ret;
uint64_t l2_offset, *l2_table, cluster_offset, tmp, old_l2_offset;
-
+
l1_index = offset >> (s->l2_bits + s->cluster_bits);
if (l1_index >= s->l1_size) {
/* outside l1 table is allowed: we grow the table if needed */
/* update the L1 entry */
s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
tmp = cpu_to_be64(l2_offset | QCOW_OFLAG_COPIED);
- if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
+ if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
&tmp, sizeof(tmp)) != sizeof(tmp))
return 0;
min_index = l2_cache_new_entry(bs);
if (old_l2_offset == 0) {
memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
} else {
- if (bdrv_pread(s->hd, old_l2_offset,
+ if (bdrv_pread(s->hd, old_l2_offset,
l2_table, s->l2_size * sizeof(uint64_t)) !=
s->l2_size * sizeof(uint64_t))
return 0;
}
- if (bdrv_pwrite(s->hd, l2_offset,
+ if (bdrv_pwrite(s->hd, l2_offset,
l2_table, s->l2_size * sizeof(uint64_t)) !=
s->l2_size * sizeof(uint64_t))
return 0;
/* not found: load a new entry in the least used one */
min_index = l2_cache_new_entry(bs);
l2_table = s->l2_cache + (min_index << s->l2_bits);
- if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
+ if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
s->l2_size * sizeof(uint64_t))
return 0;
}
/* free the cluster */
if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
int nb_csectors;
- nb_csectors = ((cluster_offset >> s->csize_shift) &
+ nb_csectors = ((cluster_offset >> s->csize_shift) &
s->csize_mask) + 1;
free_clusters(bs, (cluster_offset & s->cluster_offset_mask) & ~511,
nb_csectors * 512);
written */
if ((n_end - n_start) < s->cluster_sectors) {
uint64_t start_sect;
-
+
start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
ret = copy_sectors(bs, start_sect,
cluster_offset, 0, n_start);
} else {
int nb_csectors;
cluster_offset = alloc_bytes(bs, compressed_size);
- nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
+ nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
(cluster_offset >> 9);
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
+ cluster_offset |= QCOW_OFLAG_COMPRESSED |
((uint64_t)nb_csectors << s->csize_shift);
/* compressed clusters never have the copied flag */
tmp = cpu_to_be64(cluster_offset);
}
/* update L2 table */
l2_table[l2_index] = tmp;
- if (bdrv_pwrite(s->hd,
+ if (bdrv_pwrite(s->hd,
l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp))
return 0;
return cluster_offset;
}
-static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
+static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum)
{
BDRVQcowState *s = bs->opaque;
inflateEnd(strm);
return 0;
}
-
+
static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
{
int ret, csize, nb_csectors, sector_offset;
}
/* handle reading after the end of the backing file */
-static int backing_read1(BlockDriverState *bs,
+static int backing_read1(BlockDriverState *bs,
int64_t sector_num, uint8_t *buf, int nb_sectors)
{
int n1;
return n1;
}
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
+static int qcow_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVQcowState *s = bs->opaque;
int ret, index_in_cluster, n, n1;
uint64_t cluster_offset;
-
+
while (nb_sectors > 0) {
cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
index_in_cluster = sector_num & (s->cluster_sectors - 1);
memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
} else {
ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- if (ret != n * 512)
+ if (ret != n * 512)
return -1;
if (s->crypt_method) {
- encrypt_sectors(s, sector_num, buf, buf, n, 0,
+ encrypt_sectors(s, sector_num, buf, buf, n, 0,
&s->aes_decrypt_key);
}
}
return 0;
}
-static int qcow_write(BlockDriverState *bs, int64_t sector_num,
+static int qcow_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
BDRVQcowState *s = bs->opaque;
int ret, index_in_cluster, n;
uint64_t cluster_offset;
-
+
while (nb_sectors > 0) {
index_in_cluster = sector_num & (s->cluster_sectors - 1);
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
- index_in_cluster,
+ cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
+ index_in_cluster,
index_in_cluster + n);
if (!cluster_offset)
return -1;
if (s->crypt_method) {
encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
&s->aes_encrypt_key);
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
+ ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
s->cluster_data, n * 512);
} else {
ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
}
- if (ret != n * 512)
+ if (ret != n * 512)
return -1;
nb_sectors -= n;
sector_num += n;
int nb_sectors;
int n;
uint64_t cluster_offset;
- uint8_t *cluster_data;
+ uint8_t *cluster_data;
BlockDriverAIOCB *hd_aiocb;
} QCowAIOCB;
/* nothing to do */
} else {
if (s->crypt_method) {
- encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
- acb->n, 0,
+ encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
+ acb->n, 0,
&s->aes_decrypt_key);
}
}
qemu_aio_release(acb);
return;
}
-
+
/* prepare next AIO request */
- acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
+ acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
0, 0, 0, 0);
index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
acb->n = s->cluster_sectors - index_in_cluster;
if (!acb->cluster_offset) {
if (bs->backing_hd) {
/* read from the base image */
- n1 = backing_read1(bs->backing_hd, acb->sector_num,
+ n1 = backing_read1(bs->backing_hd, acb->sector_num,
acb->buf, acb->n);
if (n1 > 0) {
- acb->hd_aiocb = bdrv_aio_read(bs->backing_hd, acb->sector_num,
+ acb->hd_aiocb = bdrv_aio_read(bs->backing_hd, acb->sector_num,
acb->buf, acb->n, qcow_aio_read_cb, acb);
if (acb->hd_aiocb == NULL)
goto fail;
/* add AIO support for compressed blocks ? */
if (decompress_cluster(s, acb->cluster_offset) < 0)
goto fail;
- memcpy(acb->buf,
+ memcpy(acb->buf,
s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
goto redo;
} else {
goto fail;
}
acb->hd_aiocb = bdrv_aio_read(s->hd,
- (acb->cluster_offset >> 9) + index_in_cluster,
+ (acb->cluster_offset >> 9) + index_in_cluster,
acb->buf, acb->n, qcow_aio_read_cb, acb);
if (acb->hd_aiocb == NULL)
goto fail;
qemu_aio_release(acb);
return;
}
-
+
index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
acb->n = s->cluster_sectors - index_in_cluster;
if (acb->n > acb->nb_sectors)
acb->n = acb->nb_sectors;
- cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
- index_in_cluster,
+ cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
+ index_in_cluster,
index_in_cluster + acb->n);
if (!cluster_offset || (cluster_offset & 511) != 0) {
ret = -EIO;
goto fail;
}
}
- encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
+ encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
acb->n, 1, &s->aes_encrypt_key);
src_buf = acb->cluster_data;
} else {
src_buf = acb->buf;
}
acb->hd_aiocb = bdrv_aio_write(s->hd,
- (cluster_offset >> 9) + index_in_cluster,
- src_buf, acb->n,
+ (cluster_offset >> 9) + index_in_cluster,
+ src_buf, acb->n,
qcow_aio_write_cb, acb);
if (acb->hd_aiocb == NULL)
goto fail;
{
BDRVQcowState *s = bs->opaque;
QCowAIOCB *acb;
-
+
s->cluster_cache_offset = -1; /* disable compressed cache */
acb = qcow_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
if (!acb)
return NULL;
-
+
qcow_aio_write_cb(acb, 0);
return &acb->common;
}
start = offset & ~(s->cluster_size - 1);
last = (offset + size - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
+ for(cluster_offset = start; cluster_offset <= last;
cluster_offset += s->cluster_size) {
p = &s->refcount_block[cluster_offset >> s->cluster_bits];
refcount = be16_to_cpu(*p);
QCowHeader header;
uint64_t tmp, offset;
QCowCreateState s1, *s = &s1;
-
+
memset(s, 0, sizeof(*s));
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
s->refcount_block = qemu_mallocz(s->cluster_size);
if (!s->refcount_block)
goto fail;
-
+
s->refcount_table_offset = offset;
header.refcount_table_offset = cpu_to_be64(offset);
header.refcount_table_clusters = cpu_to_be32(1);
create_refcount_update(s, s->l1_table_offset, l1_size * sizeof(uint64_t));
create_refcount_update(s, s->refcount_table_offset, s->cluster_size);
create_refcount_update(s, s->refcount_block_offset, s->cluster_size);
-
+
/* write all the data */
write(fd, &header, sizeof(header));
if (backing_file) {
}
lseek(fd, s->refcount_table_offset, SEEK_SET);
write(fd, s->refcount_table, s->cluster_size);
-
+
lseek(fd, s->refcount_block_offset, SEEK_SET);
write(fd, s->refcount_block, s->cluster_size);
ret = bdrv_truncate(s->hd, s->l1_table_offset + l1_length);
if (ret < 0)
return ret;
-
+
l2_cache_reset(bs);
#endif
return 0;
/* XXX: put compressed sectors first, then all the cluster aligned
tables to avoid losing bytes in alignment */
-static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
+static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
BDRVQcowState *s = bs->opaque;
/* best compression, small window, no zlib header */
memset(&strm, 0, sizeof(strm));
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
+ Z_DEFLATED, -12,
9, Z_DEFAULT_STRATEGY);
if (ret != 0) {
qemu_free(out_buf);
/* could not compress: write normal cluster */
qcow_write(bs, sector_num, buf, s->cluster_sectors);
} else {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
+ cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
out_len, 0, 0);
cluster_offset &= s->cluster_offset_mask;
if (bdrv_pwrite(s->hd, cluster_offset, out_buf, out_len) != out_len) {
return -1;
}
}
-
+
qemu_free(out_buf);
return 0;
}
{
BDRVQcowState *s = bs->opaque;
bdi->cluster_size = s->cluster_size;
- bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
+ bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
(s->cluster_bits + s->l2_bits);
return 0;
}
/* snapshot support */
/* update the refcounts of snapshots and the copied flag */
-static int update_snapshot_refcount(BlockDriverState *bs,
+static int update_snapshot_refcount(BlockDriverState *bs,
int64_t l1_table_offset,
int l1_size,
int addend)
uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated;
int64_t old_offset, old_l2_offset;
int l2_size, i, j, l1_modified, l2_modified, nb_csectors, refcount;
-
+
l2_cache_reset(bs);
l2_table = NULL;
if (!l1_table)
goto fail;
l1_allocated = 1;
- if (bdrv_pread(s->hd, l1_table_offset,
+ if (bdrv_pread(s->hd, l1_table_offset,
l1_table, l1_size2) != l1_size2)
goto fail;
for(i = 0;i < l1_size; i++)
l1_table = s->l1_table;
l1_allocated = 0;
}
-
+
l2_size = s->l2_size * sizeof(uint64_t);
l2_table = qemu_malloc(l2_size);
if (!l2_table)
old_offset = offset;
offset &= ~QCOW_OFLAG_COPIED;
if (offset & QCOW_OFLAG_COMPRESSED) {
- nb_csectors = ((offset >> s->csize_shift) &
+ nb_csectors = ((offset >> s->csize_shift) &
s->csize_mask) + 1;
if (addend != 0)
update_refcount(bs, (offset & s->cluster_offset_mask) & ~511,
nb_csectors * 512, addend);
/* compressed clusters are never modified */
- refcount = 2;
+ refcount = 2;
} else {
if (addend != 0) {
refcount = update_cluster_refcount(bs, offset >> s->cluster_bits, addend);
}
}
if (l2_modified) {
- if (bdrv_pwrite(s->hd,
+ if (bdrv_pwrite(s->hd,
l2_offset, l2_table, l2_size) != l2_size)
goto fail;
}
if (l1_modified) {
for(i = 0; i < l1_size; i++)
cpu_to_be64s(&l1_table[i]);
- if (bdrv_pwrite(s->hd, l1_table_offset, l1_table,
+ if (bdrv_pwrite(s->hd, l1_table_offset, l1_table,
l1_size2) != l1_size2)
goto fail;
for(i = 0; i < l1_size; i++)
snapshots_offset = alloc_clusters(bs, snapshots_size);
offset = snapshots_offset;
-
+
for(i = 0; i < s->nb_snapshots; i++) {
sn = s->snapshots + i;
memset(&h, 0, sizeof(h));
h.date_sec = cpu_to_be32(sn->date_sec);
h.date_nsec = cpu_to_be32(sn->date_nsec);
h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);
-
+
id_str_size = strlen(sn->id_str);
name_size = strlen(sn->name);
h.id_str_size = cpu_to_be16(id_str_size);
{
BDRVQcowState *s = bs->opaque;
int i, ret;
-
+
ret = find_snapshot_by_id(bs, name);
if (ret >= 0)
return ret;
}
/* if no id is provided, a new one is constructed */
-static int qcow_snapshot_create(BlockDriverState *bs,
+static int qcow_snapshot_create(BlockDriverState *bs,
QEMUSnapshotInfo *sn_info)
{
BDRVQcowState *s = bs->opaque;
QCowSnapshot *snapshots1, sn1, *sn = &sn1;
int i, ret;
uint64_t *l1_table = NULL;
-
+
memset(sn, 0, sizeof(*sn));
if (sn_info->id_str[0] == '\0') {
l1_table[i] = cpu_to_be64(s->l1_table[i]);
}
if (bdrv_pwrite(s->hd, sn->l1_table_offset,
- l1_table, s->l1_size * sizeof(uint64_t)) !=
+ l1_table, s->l1_size * sizeof(uint64_t)) !=
(s->l1_size * sizeof(uint64_t)))
goto fail;
qemu_free(l1_table);
}
/* copy the snapshot 'snapshot_name' into the current disk image */
-static int qcow_snapshot_goto(BlockDriverState *bs,
+static int qcow_snapshot_goto(BlockDriverState *bs,
const char *snapshot_id)
{
BDRVQcowState *s = bs->opaque;
s->l1_size = sn->l1_size;
l1_size2 = s->l1_size * sizeof(uint64_t);
/* copy the snapshot l1 table to the current l1 table */
- if (bdrv_pread(s->hd, sn->l1_table_offset,
+ if (bdrv_pread(s->hd, sn->l1_table_offset,
s->l1_table, l1_size2) != l1_size2)
goto fail;
if (bdrv_pwrite(s->hd, s->l1_table_offset,
BDRVQcowState *s = bs->opaque;
QCowSnapshot *sn;
int snapshot_index, ret;
-
+
snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
if (snapshot_index < 0)
return -ENOENT;
return 0;
}
-static int qcow_snapshot_list(BlockDriverState *bs,
+static int qcow_snapshot_list(BlockDriverState *bs,
QEMUSnapshotInfo **psn_tab)
{
BDRVQcowState *s = bs->opaque;
{
BDRVQcowState *s = bs->opaque;
int ret, refcount_table_size2, i;
-
+
s->refcount_block_cache = qemu_malloc(s->cluster_size);
if (!s->refcount_block_cache)
goto fail;
}
-static int load_refcount_block(BlockDriverState *bs,
+static int load_refcount_block(BlockDriverState *bs,
int64_t refcount_block_offset)
{
BDRVQcowState *s = bs->opaque;
int ret;
- ret = bdrv_pread(s->hd, refcount_block_offset, s->refcount_block_cache,
+ ret = bdrv_pread(s->hd, refcount_block_offset, s->refcount_block_cache,
s->cluster_size);
if (ret != s->cluster_size)
return -EIO;
if (load_refcount_block(bs, refcount_block_offset) < 0)
return 1;
}
- block_index = cluster_index &
+ block_index = cluster_index &
((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
return be16_to_cpu(s->refcount_block_cache[block_index]);
}
}
#ifdef DEBUG_ALLOC2
printf("alloc_clusters: size=%lld -> %lld\n",
- size,
+ size,
(s->free_cluster_index - nb_clusters) << s->cluster_bits);
#endif
return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
BDRVQcowState *s = bs->opaque;
int64_t offset, cluster_offset;
int free_in_cluster;
-
+
assert(size > 0 && size <= s->cluster_size);
if (s->free_byte_offset == 0) {
s->free_byte_offset = alloc_clusters(bs, s->cluster_size);
}
redo:
- free_in_cluster = s->cluster_size -
+ free_in_cluster = s->cluster_size -
(s->free_byte_offset & (s->cluster_size - 1));
if (size <= free_in_cluster) {
/* enough space in current cluster */
return offset;
}
-static void free_clusters(BlockDriverState *bs,
+static void free_clusters(BlockDriverState *bs,
int64_t offset, int64_t size)
{
update_refcount(bs, offset, size, -1);
new_table = qemu_mallocz(new_table_size2);
if (!new_table)
return -ENOMEM;
- memcpy(new_table, s->refcount_table,
+ memcpy(new_table, s->refcount_table,
s->refcount_table_size * sizeof(uint64_t));
for(i = 0; i < s->refcount_table_size; i++)
cpu_to_be64s(&new_table[i]);
/* Note: we cannot update the refcount now to avoid recursion */
table_offset = alloc_clusters_noref(bs, new_table_size2);
ret = bdrv_pwrite(s->hd, table_offset, new_table, new_table_size2);
- if (ret != new_table_size2)
+ if (ret != new_table_size2)
goto fail;
for(i = 0; i < s->refcount_table_size; i++)
be64_to_cpus(&new_table[i]);
/* addend must be 1 or -1 */
/* XXX: cache several refcount block clusters ? */
-static int update_cluster_refcount(BlockDriverState *bs,
+static int update_cluster_refcount(BlockDriverState *bs,
int64_t cluster_index,
int addend)
{
return -EINVAL;
s->refcount_table[refcount_table_index] = offset;
data64 = cpu_to_be64(offset);
- ret = bdrv_pwrite(s->hd, s->refcount_table_offset +
- refcount_table_index * sizeof(uint64_t),
+ ret = bdrv_pwrite(s->hd, s->refcount_table_offset +
+ refcount_table_index * sizeof(uint64_t),
&data64, sizeof(data64));
if (ret != sizeof(data64))
return -EINVAL;
}
}
/* we can update the count and save it */
- block_index = cluster_index &
+ block_index = cluster_index &
((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
refcount += addend;
s->free_cluster_index = cluster_index;
}
s->refcount_block_cache[block_index] = cpu_to_be16(refcount);
- if (bdrv_pwrite(s->hd,
- refcount_block_offset + (block_index << REFCOUNT_SHIFT),
+ if (bdrv_pwrite(s->hd,
+ refcount_block_offset + (block_index << REFCOUNT_SHIFT),
&s->refcount_block_cache[block_index], 2) != 2)
return -EIO;
return refcount;
}
-static void update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length,
+static void update_refcount(BlockDriverState *bs,
+ int64_t offset, int64_t length,
int addend)
{
BDRVQcowState *s = bs->opaque;
int64_t start, last, cluster_offset;
#ifdef DEBUG_ALLOC2
- printf("update_refcount: offset=%lld size=%lld addend=%d\n",
+ printf("update_refcount: offset=%lld size=%lld addend=%d\n",
offset, length, addend);
#endif
if (length <= 0)
return;
start = offset & ~(s->cluster_size - 1);
last = (offset + length - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
+ for(cluster_offset = start; cluster_offset <= last;
cluster_offset += s->cluster_size) {
update_cluster_refcount(bs, cluster_offset >> s->cluster_bits, addend);
}
}
#ifdef DEBUG_ALLOC
-static void inc_refcounts(BlockDriverState *bs,
- uint16_t *refcount_table,
+static void inc_refcounts(BlockDriverState *bs,
+ uint16_t *refcount_table,
int refcount_table_size,
int64_t offset, int64_t size)
{
BDRVQcowState *s = bs->opaque;
int64_t start, last, cluster_offset;
int k;
-
+
if (size <= 0)
return;
start = offset & ~(s->cluster_size - 1);
last = (offset + size - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
+ for(cluster_offset = start; cluster_offset <= last;
cluster_offset += s->cluster_size) {
k = cluster_offset >> s->cluster_bits;
if (k < 0 || k >= refcount_table_size) {
}
}
-static int check_refcounts_l1(BlockDriverState *bs,
- uint16_t *refcount_table,
+static int check_refcounts_l1(BlockDriverState *bs,
+ uint16_t *refcount_table,
int refcount_table_size,
int64_t l1_table_offset, int l1_size,
int check_copied)
l1_table = qemu_malloc(l1_size2);
if (!l1_table)
goto fail;
- if (bdrv_pread(s->hd, l1_table_offset,
+ if (bdrv_pread(s->hd, l1_table_offset,
l1_table, l1_size2) != l1_size2)
goto fail;
for(i = 0;i < l1_size; i++)
be64_to_cpus(&l1_table[i]);
-
+
l2_size = s->l2_size * sizeof(uint64_t);
l2_table = qemu_malloc(l2_size);
if (!l2_table)
offset >> s->cluster_bits);
offset &= ~QCOW_OFLAG_COPIED;
}
- nb_csectors = ((offset >> s->csize_shift) &
+ nb_csectors = ((offset >> s->csize_shift) &
s->csize_mask) + 1;
offset &= s->cluster_offset_mask;
- inc_refcounts(bs, refcount_table,
+ inc_refcounts(bs, refcount_table,
refcount_table_size,
offset & ~511, nb_csectors * 512);
} else {
}
}
offset &= ~QCOW_OFLAG_COPIED;
- inc_refcounts(bs, refcount_table,
+ inc_refcounts(bs, refcount_table,
refcount_table_size,
offset, s->cluster_size);
}
}
}
- inc_refcounts(bs, refcount_table,
+ inc_refcounts(bs, refcount_table,
refcount_table_size,
l2_offset,
s->cluster_size);
/* header */
inc_refcounts(bs, refcount_table, nb_clusters,
0, s->cluster_size);
-
+
check_refcounts_l1(bs, refcount_table, nb_clusters,
s->l1_table_offset, s->l1_size, 1);
/* refcount data */
inc_refcounts(bs, refcount_table, nb_clusters,
- s->refcount_table_offset,
+ s->refcount_table_offset,
s->refcount_table_size * sizeof(uint64_t));
for(i = 0; i < s->refcount_table_size; i++) {
int64_t offset;
/*
* Block driver for RAW files
- *
+ *
* 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
#endif
*/
-static int raw_pread(BlockDriverState *bs, int64_t offset,
+static int raw_pread(BlockDriverState *bs, int64_t offset,
uint8_t *buf, int count)
{
BDRVRawState *s = bs->opaque;
int ret;
-
+
ret = fd_open(bs);
if (ret < 0)
return ret;
return ret;
}
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
+static int raw_pwrite(BlockDriverState *bs, int64_t offset,
const uint8_t *buf, int count)
{
BDRVRawState *s = bs->opaque;
int ret;
-
+
ret = fd_open(bs);
if (ret < 0)
return ret;
struct sigaction act;
aio_initialized = 1;
-
+
sigfillset(&act.sa_mask);
act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
act.sa_handler = aio_signal_handler;
if (aio_read(&acb->aiocb) < 0) {
qemu_aio_release(acb);
return NULL;
- }
+ }
return &acb->common;
}
if (aio_write(&acb->aiocb) < 0) {
qemu_aio_release(acb);
return NULL;
- }
+ }
return &acb->common;
}
if (flags || backing_file)
return -ENOTSUP;
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
if (fd < 0)
return -EIO;
raw_close,
raw_create,
raw_flush,
-
+
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
{
- kern_return_t kernResult;
+ kern_return_t kernResult;
mach_port_t masterPort;
CFMutableDictionaryRef classesToMatch;
if ( KERN_SUCCESS != kernResult ) {
printf( "IOMasterPort returned %d\n", kernResult );
}
-
- classesToMatch = IOServiceMatching( kIOCDMediaClass );
+
+ classesToMatch = IOServiceMatching( kIOCDMediaClass );
if ( classesToMatch == NULL ) {
printf( "IOServiceMatching returned a NULL dictionary.\n" );
} else {
{
printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
}
-
+
return kernResult;
}
}
IOObjectRelease( nextMedia );
}
-
+
return kernResult;
}
io_iterator_t mediaIterator;
char bsdPath[ MAXPATHLEN ];
int fd;
-
+
kernResult = FindEjectableCDMedia( &mediaIterator );
kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
-
+
if ( bsdPath[ 0 ] != '\0' ) {
strcat(bsdPath,"s0");
/* some CDs don't have a partition 0 */
}
filename = bsdPath;
}
-
+
if ( mediaIterator )
IOObjectRelease( mediaIterator );
}
if (s->type != FTYPE_FD)
return 0;
last_media_present = (s->fd >= 0);
- if (s->fd >= 0 &&
+ if (s->fd >= 0 &&
(qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
close(s->fd);
s->fd = -1;
#endif
}
if (s->fd < 0) {
- if (s->fd_got_error &&
+ if (s->fd_got_error &&
(qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
#ifdef DEBUG_FLOPPY
printf("No floppy (open delayed)\n");
raw_close,
NULL,
raw_flush,
-
+
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
#else
overlapped = FILE_FLAG_OVERLAPPED;
#endif
- s->hfile = CreateFile(filename, access_flags,
+ s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
create_flags, overlapped, NULL);
if (s->hfile == INVALID_HANDLE_VALUE) {
return 0;
}
-static int raw_pread(BlockDriverState *bs, int64_t offset,
+static int raw_pread(BlockDriverState *bs, int64_t offset,
uint8_t *buf, int count)
{
BDRVRawState *s = bs->opaque;
OVERLAPPED ov;
DWORD ret_count;
int ret;
-
+
memset(&ov, 0, sizeof(ov));
ov.Offset = offset;
ov.OffsetHigh = offset >> 32;
return ret_count;
}
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
+static int raw_pwrite(BlockDriverState *bs, int64_t offset,
const uint8_t *buf, int count)
{
BDRVRawState *s = bs->opaque;
OVERLAPPED ov;
DWORD ret_count;
int ret;
-
+
memset(&ov, 0, sizeof(ov));
ov.Offset = offset;
ov.OffsetHigh = offset >> 32;
{
BDRVRawState *s = bs->opaque;
LARGE_INTEGER l;
- ULARGE_INTEGER available, total, total_free;
+ ULARGE_INTEGER available, total, total_free;
DISK_GEOMETRY dg;
DWORD count;
BOOL status;
if (flags || backing_file)
return -ENOTSUP;
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
if (fd < 0)
return -EIO;
raw_close,
raw_create,
raw_flush,
-
+
#if 0
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
}
}
s->type = find_device_type(bs, filename);
-
+
if ((flags & BDRV_O_ACCESS) == O_RDWR) {
access_flags = GENERIC_READ | GENERIC_WRITE;
} else {
#else
overlapped = FILE_FLAG_OVERLAPPED;
#endif
- s->hfile = CreateFile(filename, access_flags,
+ s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
create_flags, overlapped, NULL);
if (s->hfile == INVALID_HANDLE_VALUE) {
if (s->type == FTYPE_FILE)
return -ENOTSUP;
if (eject_flag) {
- DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
+ DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
NULL, 0, NULL, 0, &lpBytesReturned, NULL);
} else {
- DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
+ DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
NULL, 0, NULL, 0, &lpBytesReturned, NULL);
}
}
raw_close,
NULL,
raw_flush,
-
+
#if 0
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
/*
* Block driver for the VMDK format
- *
+ *
* Copyright (c) 2004 Fabrice Bellard
* Copyright (c) 2005 Filip Navara
- *
+ *
* 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
#define CHECK_CID 1
-#define SECTOR_SIZE 512
+#define SECTOR_SIZE 512
#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each
-#define HEADER_SIZE 512 // first sector of 512 bytes
+#define HEADER_SIZE 512 // first sector of 512 bytes
static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
{
BDRVVmdkState *s = bs->opaque;
char desc[DESC_SIZE];
uint32_t cid;
- char *p_name, *cid_str;
+ char *p_name, *cid_str;
size_t cid_str_size;
/* the descriptor offset = 0x200 */
{
int snp_fd, p_fd;
uint32_t p_cid;
- char *p_name, *gd_buf, *rgd_buf;
+ char *p_name, *gd_buf, *rgd_buf;
const char *real_filename, *temp_str;
VMDK4Header header;
uint32_t gde_entries, gd_size;
gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE;
if (!gt_size)
goto fail;
- gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde
+ gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde
gd_size = gde_entries * sizeof(uint32_t);
/* write RGD */
fail_gd:
qemu_free(gd_buf);
- fail_rgd:
+ fail_rgd:
qemu_free(rgd_buf);
fail:
close(p_fd);
static int vmdk_parent_open(BlockDriverState *bs, const char * filename)
{
BDRVVmdkState *s = bs->opaque;
- char *p_name;
+ char *p_name;
char desc[DESC_SIZE];
char parent_img_name[1024];
p_name += sizeof("parentFileNameHint") + 1;
if ((end_name = strchr(p_name,'\"')) == 0)
return -1;
-
+
strncpy(s->hd->backing_file, p_name, end_name - p_name);
if (stat(s->hd->backing_file, &file_buf) != 0) {
path_combine(parent_img_name, sizeof(parent_img_name),
s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
if (s->l1_entry_sectors <= 0)
goto fail;
- s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
+ s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
/ s->l1_entry_sectors;
s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
if (!vmdk_is_cid_valid(bs))
return -1;
parent_cluster_offset = get_cluster_offset(s->hd->backing_hd, offset, allocate);
- if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) !=
+ if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) !=
ps->cluster_sectors*512)
return -1;
- if (bdrv_pwrite(s->hd, cluster_offset << 9, whole_grain, sizeof(whole_grain)) !=
+ if (bdrv_pwrite(s->hd, cluster_offset << 9, whole_grain, sizeof(whole_grain)) !=
sizeof(whole_grain))
return -1;
}
int min_index, i, j;
uint32_t min_count, *l2_table, tmp;
uint64_t cluster_offset;
-
+
l1_index = (offset >> 9) / s->l1_entry_sectors;
if (l1_index >= s->l1_size)
return 0;
}
}
l2_table = s->l2_cache + (min_index * s->l2_size);
- if (bdrv_pread(s->hd, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
+ if (bdrv_pread(s->hd, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
s->l2_size * sizeof(uint32_t))
return 0;
/* update L2 table */
tmp = cpu_to_le32(cluster_offset);
l2_table[l2_index] = tmp;
- if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
+ if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
&tmp, sizeof(tmp)) != sizeof(tmp))
return 0;
/* update backup L2 table */
if (s->l1_backup_table_offset != 0) {
l2_offset = s->l1_backup_table[l1_index];
- if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
+ if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
&tmp, sizeof(tmp)) != sizeof(tmp))
return 0;
}
return cluster_offset;
}
-static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
+static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum)
{
BDRVVmdkState *s = bs->opaque;
return (cluster_offset != 0);
}
-static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
+static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVVmdkState *s = bs->opaque;
return 0;
}
-static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
+static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
BDRVVmdkState *s = bs->opaque;
header.check_bytes[1] = 0x20;
header.check_bytes[2] = 0xd;
header.check_bytes[3] = 0xa;
-
- /* write all the data */
+
+ /* write all the data */
write(fd, &magic, sizeof(magic));
write(fd, &header, sizeof(header));
for (i = 0, tmp = header.rgd_offset + gd_size;
i < gt_count; i++, tmp += gt_size)
write(fd, &tmp, sizeof(tmp));
-
+
/* write backup grain directory */
lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
for (i = 0, tmp = header.gd_offset + gd_size;
/*
* Block driver for Conectix/Microsoft Virtual PC images
- *
+ *
* Copyright (c) 2005 Alex Beregszaszi
- *
+ *
* 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
typedef struct BDRVVPCState {
int fd;
-
+
int pagetable_entries;
uint32_t *pagetable;
uint8_t *pageentry_u8;
uint32_t *pageentry_u32;
uint16_t *pageentry_u16;
-
+
uint64_t last_bitmap;
#endif
} BDRVVPCState;
return -1;
bs->read_only = 1; // no write support yet
-
+
s->fd = fd;
if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE)
pagetable_index = offset / s->pageentry_size;
pageentry_index = (offset % s->pageentry_size) / 512;
-
+
if (pagetable_index > s->pagetable_entries || s->pagetable[pagetable_index] == 0xffffffff)
return -1; // not allocated
bitmap_offset = 512 * s->pagetable[pagetable_index];
block_offset = bitmap_offset + 512 + (512 * pageentry_index);
-
+
// printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
// sector_num, pagetable_index, pageentry_index,
// bitmap_offset, block_offset);
lseek(s->fd, bitmap_offset, SEEK_SET);
s->last_bitmap = bitmap_offset;
-
+
// Scary! Bitmap is stored as big endian 32bit entries,
// while we used to look it up byte by byte
read(s->fd, s->pageentry_u8, 512);
return -1;
#else
lseek(s->fd, bitmap_offset + (pageentry_index / 8), SEEK_SET);
-
+
read(s->fd, &bitmap_entry, 1);
if ((bitmap_entry >> (pageentry_index % 8)) & 1)
return 0;
}
-static int vpc_read(BlockDriverState *bs, int64_t sector_num,
+static int vpc_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVVPCState *s = bs->opaque;
/* vim:set shiftwidth=4 ts=8: */
/*
* QEMU Block driver for virtual VFAT (shadows a local directory)
- *
+ *
* Copyright (c) 2004,2005 Johannes E. Schindelin
- *
+ *
* 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
/* TODO: add ":bootsector=blabla.img:" */
/* LATER TODO: add automatic boot sector generation from
BOOTEASY.ASM and Ranish Partition Manager
- Note that DOS assumes the system files to be the first files in the
+ Note that DOS assumes the system files to be the first files in the
file system (test if the boot sector still relies on that fact)! */
/* MAYBE TODO: write block-visofs.c */
/* TODO: call try_commit() only after a timeout */
index_to<0 || index_to>=array->next ||
index_from<0 || index_from>=array->next)
return -1;
-
+
if(index_to==index_from)
return 0;
memmove(to+is*count,to,from-to);
else
memmove(from,from+is*count,to-from);
-
+
memcpy(to,buf,is*count);
free(buf);
BlockDriverState* bs; /* pointer to parent */
unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
unsigned char first_sectors[0x40*0x200];
-
+
int fat_type; /* 16 or 32 */
array_t fat,directory,mapping;
-
+
unsigned int cluster_size;
unsigned int sectors_per_cluster;
unsigned int sectors_per_fat;
uint32_t sector_count; /* total number of sectors of the partition */
uint32_t cluster_count; /* total number of clusters of this partition */
uint32_t max_fat_value;
-
+
int current_fd;
mapping_t* current_mapping;
unsigned char* cluster; /* points to current cluster */
partition_t* partition=&(real_mbr->partition[0]);
memset(s->first_sectors,0,512);
-
+
partition->attributes=0x80; /* bootable */
partition->start_head=1;
partition->start_sector=1;
for(i=0;i<11;i++)
chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0))
+(unsigned char)entry->name[i];
-
+
return chksum;
}
s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
}
memset(s->fat.pointer,0,s->fat.size);
-
+
switch(s->fat_type) {
case 12: s->max_fat_value=0xfff; break;
case 16: s->max_fat_value=0xffff; break;
memcpy(entry->name,filename,strlen(filename));
return entry;
}
-
+
entry_long=create_long_filename(s,filename);
-
- i = strlen(filename);
+
+ i = strlen(filename);
for(j = i - 1; j>0 && filename[j]!='.';j--);
if (j > 0)
i = (j > 8 ? 8 : j);
entry=array_get_next(&(s->directory));
memset(entry->name,0x20,11);
strncpy(entry->name,filename,i);
-
+
if(j > 0)
for (i = 0; i < 3 && filename[j+1+i]; i++)
entry->extension[i] = filename[j+1+i];
if(entry1==entry) /* no dupe found */
break;
- /* use all 8 characters of name */
+ /* use all 8 characters of name */
if(entry->name[7]==' ') {
int j;
for(j=6;j>0 && entry->name[j]==' ';j--)
mapping->end = mapping->begin;
return -1;
}
-
+
i = mapping->info.dir.first_dir_index =
first_cluster == 0 ? 0 : s->directory.next;
- /* actually read the directory, and allocate the mappings */
+ /* actually read the directory, and allocate the mappings */
while((entry=readdir(dir))) {
unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
char* buffer;
if(first_cluster == 0 && (is_dotdot || is_dot))
continue;
-
+
buffer=(char*)malloc(length);
assert(buffer);
snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
memset(array_get(&(s->directory), cur), 0,
(ROOT_ENTRIES - cur) * sizeof(direntry_t));
}
-
+
/* reget the mapping, since s->mapping was possibly realloc()ed */
mapping = (mapping_t*)array_get(&(s->mapping), mapping_index);
first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
direntry = (direntry_t*)array_get(&(s->directory), mapping->dir_index);
set_begin_of_direntry(direntry, mapping->begin);
-
+
return 0;
}
*/
i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
-
+
array_init(&(s->mapping),sizeof(mapping_t));
array_init(&(s->directory),sizeof(direntry_t));
for (i = 0, cluster = 0; i < s->mapping.next; i++) {
int j;
- /* MS-DOS expects the FAT to be 0 for the root directory
+ /* MS-DOS expects the FAT to be 0 for the root directory
* (except for the media byte). */
/* LATER TODO: still true for FAT32? */
int fix_fat = (i != 0);
s->qcow_filename = NULL;
s->fat2 = NULL;
s->downcase_short_names = 1;
-
+
if (!strstart(dirname, "fat:", NULL))
return -1;
assert(index1<=index2);
DLOG(mapping=array_get(&(s->mapping),index1);
assert(mapping->begin<=cluster_num);
- assert(index2 >= s->mapping.next ||
+ assert(index2 >= s->mapping.next ||
((mapping = array_get(&(s->mapping),index2)) &&
mapping->end>cluster_num)));
}
}
#endif
-static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
+static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BDRVVVFATState *s = bs->opaque;
}
/*
- * This function looks at the modified data (qcow).
+ * This function looks at the modified data (qcow).
* It returns 0 upon inconsistency or error, and the number of clusters
* used by the directory, its subdirectories and their files.
*/
} else
/* new directory */
schedule_mkdir(s, cluster_num, strdup(path));
-
+
lfn_init(&lfn);
do {
int i;
}
next_mapping->dir_index = mapping->dir_index;
- next_mapping->first_mapping_index =
+ next_mapping->first_mapping_index =
mapping->first_mapping_index < 0 ?
array_index(&(s->mapping), mapping) :
mapping->first_mapping_index;
mapping = next_mapping;
}
-
+
cluster = c1;
}
return ret;
}
- /* copy FAT (with bdrv_read) */
+ /* copy FAT (with bdrv_read) */
memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
/* recurse direntries from root (using bs->bdrv_read) */
return do_commit(s);
}
-static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
+static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
- BDRVVVFATState *s = bs->opaque;
+ BDRVVVFATState *s = bs->opaque;
int i, ret;
DLOG(checkpoint());
begin = sector_num;
if (end > sector_num + nb_sectors)
end = sector_num + nb_sectors;
- dir_index = mapping->dir_index +
+ dir_index = mapping->dir_index +
0x10 * (begin - mapping->begin * s->sectors_per_cluster);
direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
*n = nb_sectors;
else if (*n < 0)
return 0;
- return 1;
+ return 1;
}
static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
/*
* QEMU System Emulator block driver
- *
+ *
* Copyright (c) 2003 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
int64_t sector_num, const uint8_t *buf, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque);
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
-static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
+static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors);
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
return NULL;
}
-int bdrv_create(BlockDriver *drv,
+int bdrv_create(BlockDriver *drv,
const char *filename, int64_t size_in_sectors,
const char *backing_file, int flags)
{
void get_tmp_filename(char *filename, int size)
{
char temp_dir[MAX_PATH];
-
+
GetTempPath(MAX_PATH, temp_dir);
GetTempFileName(temp_dir, "qem", 0, filename);
}
(filename[0] >= 'A' && filename[0] <= 'Z')) &&
filename[1] == ':');
}
-
+
static int is_windows_drive(const char *filename)
{
- if (is_windows_drive_prefix(filename) &&
+ if (is_windows_drive_prefix(filename) &&
filename[2] == '\0')
return 1;
if (strstart(filename, "\\\\.\\", NULL) ||
memcpy(protocol, filename, len);
protocol[len] = '\0';
for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- if (drv1->protocol_name &&
+ if (drv1->protocol_name &&
!strcmp(drv1->protocol_name, protocol))
return drv1;
}
BlockDriver *drv1, *drv;
uint8_t buf[2048];
BlockDriverState *bs;
-
+
/* detect host devices. By convention, /dev/cdrom[N] is always
recognized as a host CDROM */
if (strstart(filename, "/dev/cdrom", NULL))
#else
{
struct stat st;
- if (stat(filename, &st) >= 0 &&
+ if (stat(filename, &st) >= 0 &&
(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
return &bdrv_host_device;
}
}
#endif
-
+
drv = find_protocol(filename);
/* no need to test disk image formats for vvfat */
if (drv == &bdrv_vvfat)
int ret, open_flags;
char tmp_filename[1024];
char backing_filename[1024];
-
+
bs->read_only = 0;
bs->is_temporary = 0;
bs->encrypted = 0;
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
int64_t total_size;
-
+
/* if snapshot, we create a temporary backing file and open it
instead of opening 'filename' directly */
}
total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
bdrv_delete(bs1);
-
+
get_tmp_filename(tmp_filename, sizeof(tmp_filename));
realpath(filename, backing_filename);
- if (bdrv_create(&bdrv_qcow2, tmp_filename,
+ if (bdrv_create(&bdrv_qcow2, tmp_filename,
total_size, backing_filename, 0) < 0) {
return -1;
}
}
/* return < 0 if error. See bdrv_write() for the return codes */
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
+int bdrv_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
BlockDriver *drv = bs->drv;
}
}
-/* Return < 0 if error. Important errors are:
+/* Return < 0 if error. Important errors are:
-EIO generic I/O error (may happen for all errors)
-ENOMEDIUM No media inserted.
-EINVAL Invalid sector number or nb_sectors
-EACCES Trying to write a read-only device
*/
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
+int bdrv_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
BlockDriver *drv = bs->drv;
if (bs->read_only)
return -EACCES;
if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(bs->boot_sector_data, buf, 512);
+ memcpy(bs->boot_sector_data, buf, 512);
}
if (drv->bdrv_pwrite) {
int ret, len;
}
}
-static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
+static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
uint8_t *buf, int count1)
{
uint8_t tmp_buf[SECTOR_SIZE];
return count1;
}
-static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
+static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
const uint8_t *buf, int count1)
{
uint8_t tmp_buf[SECTOR_SIZE];
}
/**
- * Read with byte offsets (needed only for file protocols)
+ * Read with byte offsets (needed only for file protocols)
*/
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
+int bdrv_pread(BlockDriverState *bs, int64_t offset,
void *buf1, int count1)
{
BlockDriver *drv = bs->drv;
return drv->bdrv_pread(bs, offset, buf1, count1);
}
-/**
- * Write with byte offsets (needed only for file protocols)
+/**
+ * Write with byte offsets (needed only for file protocols)
*/
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
+int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
const void *buf1, int count1)
{
BlockDriver *drv = bs->drv;
memset(bs->boot_sector_data + size, 0, 512 - size);
}
-void bdrv_set_geometry_hint(BlockDriverState *bs,
+void bdrv_set_geometry_hint(BlockDriverState *bs,
int cyls, int heads, int secs)
{
bs->cyls = cyls;
bs->translation = translation;
}
-void bdrv_get_geometry_hint(BlockDriverState *bs,
+void bdrv_get_geometry_hint(BlockDriverState *bs,
int *pcyls, int *pheads, int *psecs)
{
*pcyls = bs->cyls;
}
/* XXX: no longer used */
-void bdrv_set_change_cb(BlockDriverState *bs,
+void bdrv_set_change_cb(BlockDriverState *bs,
void (*change_cb)(void *opaque), void *opaque)
{
bs->change_cb = change_cb;
}
}
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
+void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
void *opaque)
{
BlockDriver *drv;
}
}
-void bdrv_get_backing_filename(BlockDriverState *bs,
+void bdrv_get_backing_filename(BlockDriverState *bs,
char *filename, int filename_size)
{
if (!bs->backing_hd) {
}
}
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
+int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
BlockDriver *drv = bs->drv;
return -ENOTSUP;
return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
}
-
+
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
{
BlockDriver *drv = bs->drv;
/**************************************************************/
/* handling of snapshots */
-int bdrv_snapshot_create(BlockDriverState *bs,
+int bdrv_snapshot_create(BlockDriverState *bs,
QEMUSnapshotInfo *sn_info)
{
BlockDriver *drv = bs->drv;
return drv->bdrv_snapshot_create(bs, sn_info);
}
-int bdrv_snapshot_goto(BlockDriverState *bs,
+int bdrv_snapshot_goto(BlockDriverState *bs,
const char *snapshot_id)
{
BlockDriver *drv = bs->drv;
return drv->bdrv_snapshot_delete(bs, snapshot_id);
}
-int bdrv_snapshot_list(BlockDriverState *bs,
+int bdrv_snapshot_list(BlockDriverState *bs,
QEMUSnapshotInfo **psn_info)
{
BlockDriver *drv = bs->drv;
base = 1024;
for(i = 0; i < NB_SUFFIXES; i++) {
if (size < (10 * base)) {
- snprintf(buf, buf_size, "%0.1f%c",
+ snprintf(buf, buf_size, "%0.1f%c",
(double)size / base,
suffixes[i]);
break;
} else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
- snprintf(buf, buf_size, "%" PRId64 "%c",
+ snprintf(buf, buf_size, "%" PRId64 "%c",
((size + (base >> 1)) / base),
suffixes[i]);
break;
int64_t secs;
if (!sn) {
- snprintf(buf, buf_size,
- "%-10s%-20s%7s%20s%15s",
+ snprintf(buf, buf_size,
+ "%-10s%-20s%7s%20s%15s",
"ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
} else {
ti = sn->date_sec;
"%02d:%02d:%02d.%03d",
(int)(secs / 3600),
(int)((secs / 60) % 60),
- (int)(secs % 60),
+ (int)(secs % 60),
(int)((sn->vm_clock_nsec / 1000000) % 1000));
snprintf(buf, buf_size,
- "%-10s%-20s%7s%20s%15s",
+ "%-10s%-20s%7s%20s%15s",
sn->id_str, sn->name,
get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
date_buf,
if (!drv)
return NULL;
-
+
/* XXX: we assume that nb_sectors == 0 is suppored by the async read */
if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
memcpy(buf, bs->boot_sector_data, 512);
if (bs->read_only)
return NULL;
if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(bs->boot_sector_data, buf, 512);
+ memcpy(bs->boot_sector_data, buf, 512);
}
return drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
#define NOT_DONE 0x7fffffff
-static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
+static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
int async_ret;
async_ret = NOT_DONE;
qemu_aio_wait_start();
- acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
+ acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
bdrv_rw_em_cb, &async_ret);
if (acb == NULL) {
qemu_aio_wait_end();
async_ret = NOT_DONE;
qemu_aio_wait_start();
- acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
+ acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
bdrv_rw_em_cb, &async_ret);
if (acb == NULL) {
qemu_aio_wait_end();
/**
* Return TRUE if the media changed since the last call to this
- * function. It is currently only used for floppy disks
+ * function. It is currently only used for floppy disks
*/
int bdrv_media_changed(BlockDriverState *bs)
{
/*
* QEMU System Emulator block driver
- *
+ *
* Copyright (c) 2003 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
int instance_size;
int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
int (*bdrv_open)(BlockDriverState *bs, const char *filename, int flags);
- int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
+ int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors);
- int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
+ int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
void (*bdrv_close)(BlockDriverState *bs);
- int (*bdrv_create)(const char *filename, int64_t total_sectors,
+ int (*bdrv_create)(const char *filename, int64_t total_sectors,
const char *backing_file, int flags);
void (*bdrv_flush)(BlockDriverState *bs);
int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
int aiocb_size;
const char *protocol_name;
- int (*bdrv_pread)(BlockDriverState *bs, int64_t offset,
+ int (*bdrv_pread)(BlockDriverState *bs, int64_t offset,
uint8_t *buf, int count);
- int (*bdrv_pwrite)(BlockDriverState *bs, int64_t offset,
+ int (*bdrv_pwrite)(BlockDriverState *bs, int64_t offset,
const uint8_t *buf, int count);
int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
int64_t (*bdrv_getlength)(BlockDriverState *bs);
- int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
+ int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
- int (*bdrv_snapshot_create)(BlockDriverState *bs,
+ int (*bdrv_snapshot_create)(BlockDriverState *bs,
QEMUSnapshotInfo *sn_info);
- int (*bdrv_snapshot_goto)(BlockDriverState *bs,
+ int (*bdrv_snapshot_goto)(BlockDriverState *bs,
const char *snapshot_id);
int (*bdrv_snapshot_delete)(BlockDriverState *bs, const char *snapshot_id);
- int (*bdrv_snapshot_list)(BlockDriverState *bs,
+ int (*bdrv_snapshot_list)(BlockDriverState *bs,
QEMUSnapshotInfo **psn_info);
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
int (*bdrv_media_changed)(BlockDriverState *bs);
int (*bdrv_eject)(BlockDriverState *bs, int eject_flag);
int (*bdrv_set_locked)(BlockDriverState *bs, int locked);
-
+
BlockDriverAIOCB *free_aiocb;
struct BlockDriver *next;
};
/* async read/write emulation */
void *sync_aiocb;
-
+
/* NOTE: the following infos are only hints for real hardware
drivers. They are not used by the block driver */
int cyls, heads, secs, translation;
return bswap_16(x);
}
-static inline uint32_t bswap32(uint32_t x)
+static inline uint32_t bswap32(uint32_t x)
{
return bswap_32(x);
}
-static inline uint64_t bswap64(uint64_t x)
+static inline uint64_t bswap64(uint64_t x)
{
return bswap_64(x);
}
/*
* QEMU Cocoa display driver
- *
+ *
* Copyright (c) 2005 Pierre d'Herbemont
* many code/inspiration from SDL 1.2 code (LGPL)
- *
+ *
* 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
* THE SOFTWARE.
*/
/*
- Todo : x miniaturize window
+ Todo : x miniaturize window
x center the window
- save window position
- handle keyboard event
MacSetRectRgn (temp, x, y,
x + w, y + h);
MacUnionRgn (dirty, temp, dirty);
-
+
/* Flush the dirty region */
QDFlushPortBuffer ( [ qd_view qdPort ], dirty );
DisposeRgn (dirty);
static void *screen_pixels;
static int screen_pitch;
NSRect contentRect;
-
+
//printf("resizing to %d %d\n", w, h);
-
+
contentRect = NSMakeRect (0, 0, w, h);
if(window)
{
fprintf(stderr, "(cocoa) can't create window\n");
exit(1);
}
-
+
if(qd_view)
[qd_view release];
-
+
qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
-
+
if(!qd_view)
{
fprintf(stderr, "(cocoa) can't create qd_view\n");
exit(1);
}
-
+
[ window setAcceptsMouseMovedEvents:YES ];
[ window setTitle:@"Qemu" ];
[ window setReleasedWhenClosed:NO ];
-
+
/* Set screen to black */
[ window setBackgroundColor: [NSColor blackColor] ];
-
+
/* set window position */
[ window center ];
-
+
[ qd_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
[ [ window contentView ] addSubview:qd_view ];
[ qd_view release ];
[ window makeKeyAndOrderFront:nil ];
-
+
/* Careful here, the window seems to have to be onscreen to do that */
LockPortBits ( [ qd_view qdPort ] );
screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort ] ) );
screen_pitch = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort ] ) );
UnlockPortBits ( [ qd_view qdPort ] );
- {
- int vOffset = [ window frame ].size.height -
+ {
+ int vOffset = [ window frame ].size.height -
[ qd_view frame ].size.height - [ qd_view frame ].origin.y;
-
+
int hOffset = [ qd_view frame ].origin.x;
-
+
screen_pixels += (vOffset * screen_pitch) + hOffset * (device_bpp/8);
}
ds->data = screen_pixels;
ds->depth = device_bpp;
ds->width = w;
ds->height = h;
-
+
current_ds = *ds;
}
208,// 125 0x7D 0xd0 E0,50 D ARROW QZ_DOWN
200,// 126 0x7E 0xc8 E0,48 U ARROW QZ_UP
/* completed according to http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */
-
+
/* Aditional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */
/*
- 219 // 0xdb e0,5b L GUI
- 220 // 0xdc e0,5c R GUI
- 221 // 0xdd e0,5d APPS
- // E0,2A,E0,37 PRNT SCRN
- // E1,1D,45,E1,9D,C5 PAUSE
- 83 // 0x53 0x53 KP .
-// ACPI Scan Codes
- 222 // 0xde E0, 5E Power
- 223 // 0xdf E0, 5F Sleep
- 227 // 0xe3 E0, 63 Wake
-// Windows Multimedia Scan Codes
- 153 // 0x99 E0, 19 Next Track
- 144 // 0x90 E0, 10 Previous Track
- 164 // 0xa4 E0, 24 Stop
- 162 // 0xa2 E0, 22 Play/Pause
- 160 // 0xa0 E0, 20 Mute
- 176 // 0xb0 E0, 30 Volume Up
- 174 // 0xae E0, 2E Volume Down
- 237 // 0xed E0, 6D Media Select
- 236 // 0xec E0, 6C E-Mail
- 161 // 0xa1 E0, 21 Calculator
- 235 // 0xeb E0, 6B My Computer
- 229 // 0xe5 E0, 65 WWW Search
- 178 // 0xb2 E0, 32 WWW Home
- 234 // 0xea E0, 6A WWW Back
- 233 // 0xe9 E0, 69 WWW Forward
- 232 // 0xe8 E0, 68 WWW Stop
- 231 // 0xe7 E0, 67 WWW Refresh
- 230 // 0xe6 E0, 66 WWW Favorites
+ 219 // 0xdb e0,5b L GUI
+ 220 // 0xdc e0,5c R GUI
+ 221 // 0xdd e0,5d APPS
+ // E0,2A,E0,37 PRNT SCRN
+ // E1,1D,45,E1,9D,C5 PAUSE
+ 83 // 0x53 0x53 KP .
+// ACPI Scan Codes
+ 222 // 0xde E0, 5E Power
+ 223 // 0xdf E0, 5F Sleep
+ 227 // 0xe3 E0, 63 Wake
+// Windows Multimedia Scan Codes
+ 153 // 0x99 E0, 19 Next Track
+ 144 // 0x90 E0, 10 Previous Track
+ 164 // 0xa4 E0, 24 Stop
+ 162 // 0xa2 E0, 22 Play/Pause
+ 160 // 0xa0 E0, 20 Mute
+ 176 // 0xb0 E0, 30 Volume Up
+ 174 // 0xae E0, 2E Volume Down
+ 237 // 0xed E0, 6D Media Select
+ 236 // 0xec E0, 6C E-Mail
+ 161 // 0xa1 E0, 21 Calculator
+ 235 // 0xeb E0, 6B My Computer
+ 229 // 0xe5 E0, 65 WWW Search
+ 178 // 0xb2 E0, 32 WWW Home
+ 234 // 0xea E0, 6A WWW Back
+ 233 // 0xe9 E0, 69 WWW Forward
+ 232 // 0xe8 E0, 68 WWW Stop
+ 231 // 0xe7 E0, 67 WWW Refresh
+ 230 // 0xe6 E0, 66 WWW Favorites
*/
};
NSDate *distantPast;
NSEvent *event;
NSAutoreleasePool *pool;
-
+
pool = [ [ NSAutoreleasePool alloc ] init ];
distantPast = [ NSDate distantPast ];
-
+
vga_hw_update();
do {
case NSKeyDown:
{
- int keycode = cocoa_keycode_to_qemu([event keyCode]);
-
+ int keycode = cocoa_keycode_to_qemu([event keyCode]);
+
/* handle command Key Combos */
if ([event modifierFlags] & NSCommandKeyMask) {
switch ([event keyCode]) {
return;
}
}
-
+
/* handle control + alt Key Combos */
if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
switch (keycode) {
}
}
break;
-
+
case NSKeyUp:
{
- int keycode = cocoa_keycode_to_qemu([event keyCode]);
+ int keycode = cocoa_keycode_to_qemu([event keyCode]);
if (is_graphic_console()) {
if (keycode & 0x80)
kbd_put_keycode(0xe0);
}
}
break;
-
+
case NSMouseMoved:
if (grab) {
int dx = [event deltaX];
kbd_mouse_event(dx, dy, dz, buttons);
}
break;
-
+
case NSLeftMouseDown:
if (grab) {
int buttons = 0;
-
+
/* leftclick+command simulates rightclick */
if ([event modifierFlags] & NSCommandKeyMask) {
buttons |= MOUSE_EVENT_RBUTTON;
[NSApp sendEvent: event];
}
break;
-
+
case NSLeftMouseDragged:
if (grab) {
int dx = [event deltaX];
kbd_mouse_event(dx, dy, dz, buttons);
}
break;
-
+
case NSLeftMouseUp:
if (grab) {
kbd_mouse_event(0, 0, 0, 0);
//[NSApp sendEvent: event];
}
break;
-
+
case NSRightMouseDown:
if (grab) {
int buttons = 0;
-
+
buttons |= MOUSE_EVENT_RBUTTON;
kbd_mouse_event(0, 0, 0, buttons);
} else {
[NSApp sendEvent: event];
}
break;
-
+
case NSRightMouseDragged:
if (grab) {
int dx = [event deltaX];
kbd_mouse_event(dx, dy, dz, buttons);
}
break;
-
+
case NSRightMouseUp:
if (grab) {
kbd_mouse_event(0, 0, 0, 0);
[NSApp sendEvent: event];
}
break;
-
+
case NSOtherMouseDragged:
if (grab) {
int dx = [event deltaX];
kbd_mouse_event(dx, dy, dz, buttons);
}
break;
-
+
case NSOtherMouseDown:
if (grab) {
int buttons = 0;
[NSApp sendEvent:event];
}
break;
-
+
case NSOtherMouseUp:
if (grab) {
kbd_mouse_event(0, 0, 0, 0);
[NSApp sendEvent: event];
}
break;
-
+
case NSScrollWheel:
if (grab) {
int dz = [event deltaY];
kbd_mouse_event(0, 0, -dz, 0);
}
break;
-
+
default: [NSApp sendEvent:event];
}
}
------------------------------------------------------
*/
-static void cocoa_cleanup(void)
+static void cocoa_cleanup(void)
{
}
ds->dpy_update = cocoa_update;
ds->dpy_resize = cocoa_resize;
ds->dpy_refresh = cocoa_refresh;
-
+
cocoa_resize(ds, 640, 400);
-
+
atexit(cocoa_cleanup);
}
------------------------------------------------------
*/
static void QZ_SetPortAlphaOpaque ()
-{
+{
/* Assume 32 bit if( bpp == 32 )*/
if ( 1 ) {
-
+
uint32_t *pixels = (uint32_t*) current_ds.data;
uint32_t rowPixels = current_ds.linesize / 4;
uint32_t i, j;
-
+
for (i = 0; i < current_ds.height; i++)
for (j = 0; j < current_ds.width; j++) {
-
+
pixels[ (i * rowPixels) + j ] |= 0xFF000000;
}
}
@implementation QemuWindow
- (void)miniaturize:(id)sender
{
-
+
/* make the alpha channel opaque so anim won't have holes in it */
QZ_SetPortAlphaOpaque ();
-
+
[ super miniaturize:sender ];
-
+
}
- (void)display
-{
- /*
+{
+ /*
This method fires just before the window deminaturizes from the Dock.
-
+
We'll save the current visible surface, let the window manager redraw any
- UI elements, and restore the SDL surface. This way, no expose event
+ UI elements, and restore the SDL surface. This way, no expose event
is required, and the deminiaturize works perfectly.
*/
-
+
/* make sure pixels are fully opaque */
QZ_SetPortAlphaOpaque ();
-
+
/* save current visible SDL surface */
[ self cacheImageInRect:[ qd_view frame ] ];
-
+
/* let the window manager redraw controls, border, etc */
[ super display ];
-
+
/* restore visible SDL surface */
[ self restoreCachedImage ];
}
if( gArgc <= 1 || strncmp (gArgv[1], "-psn", 4) == 0)
{
NSOpenPanel *op = [[NSOpenPanel alloc] init];
-
+
cocoa_resize(¤t_ds, 640, 400);
-
+
[op setPrompt:@"Boot image"];
-
+
[op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"];
-
+
[op beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObjects:@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil]
modalForWindow:window modalDelegate:self
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
{
exit(0);
}
-
+
if(returnCode == NSOKButton)
{
char *bin = "qemu";
char *img = (char*)[ [ sheet filename ] cString];
-
+
char **argv = (char**)malloc( sizeof(char*)*3 );
-
+
asprintf(&argv[0], "%s", bin);
asprintf(&argv[1], "-hda");
asprintf(&argv[2], "%s", img);
-
+
printf("Using argc %d argv %s -hda %s\n", 3, bin, img);
-
+
[self startEmulationWithArgc:3 argv:(char**)argv];
}
}
NSMenuItem *menuItem;
NSString *title;
NSString *appName;
-
+
appName = @"Qemu";
appleMenu = [[NSMenu alloc] initWithTitle:@""];
-
+
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
title = [@"Quit " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
-
+
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
NSMenuItem *menuItem;
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
-
+
/* "Minimize" item */
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
-
+
/* Put menu into the menubar */
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
[windowMenuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:windowMenuItem];
-
+
/* Tell the application object that this is now the window menu */
[NSApp setWindowsMenu:windowMenu];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QemuCocoaGUIController *gui_controller;
CPSProcessSerNum PSN;
-
+
[NSApplication sharedApplication];
-
+
if (!CPSGetCurrentProcess(&PSN))
if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
if (!CPSSetFrontProcess(&PSN))
[NSApplication sharedApplication];
-
+
/* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]];
setApplicationMenu();
/* Create SDLMain and make it the app delegate */
gui_controller = [[QemuCocoaGUIController alloc] init];
[NSApp setDelegate:gui_controller];
-
+
/* Start the main event loop */
[NSApp run];
-
+
[gui_controller release];
[pool release];
}
fi
fi
-# Check for gcc4, error if pre-gcc4
+# Check for gcc4, error if pre-gcc4
if test "$check_gcc" = "yes" ; then
cat > $TMPC <<EOF
#if __GNUC__ < 4
#
# gcc for solaris 10/fcs in /usr/sfw/bin doesn't compile qemu correctly
# override the check with --disable-gcc-check
- #
+ #
if test "$solarisrev" -eq 10 -a "$check_gcc" = "yes" ; then
solgcc=`which $cc`
if test "$solgcc" = "/usr/sfw/bin/gcc" ; then
fi
exit 1
fi
-fi
+fi
if test -z "$target_list" ; then
/*
* QEMU graphical console
- *
+ *
* 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
return color;
}
-static void vga_fill_rect (DisplayState *ds,
+static void vga_fill_rect (DisplayState *ds,
int posx, int posy, int width, int height, uint32_t color)
{
uint8_t *d, *d1;
int x, y, bpp;
-
+
bpp = (ds->depth + 7) >> 3;
- d1 = ds->data +
+ d1 = ds->data +
ds->linesize * posy + bpp * posx;
for (y = 0; y < height; y++) {
d = d1;
bpp = (ds->depth + 7) >> 3;
wb = w * bpp;
if (yd <= ys) {
- s = ds->data +
+ s = ds->data +
ds->linesize * ys + bpp * xs;
- d = ds->data +
+ d = ds->data +
ds->linesize * yd + bpp * xd;
for (y = 0; y < h; y++) {
memmove(d, s, wb);
s += ds->linesize;
}
} else {
- s = ds->data +
+ s = ds->data +
ds->linesize * (ys + h - 1) + bpp * xs;
- d = ds->data +
+ d = ds->data +
ds->linesize * (yd + h - 1) + bpp * xd;
for (y = 0; y < h; y++) {
memmove(d, s, wb);
}
#endif
-static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
+static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
TextAttributes *t_attrib)
{
uint8_t *d;
}
bpp = (ds->depth + 7) >> 3;
- d = ds->data +
+ d = ds->data +
ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
linesize = ds->linesize;
font_ptr = vgafont16 + FONT_HEIGHT * ch;
y2 += s->total_height;
if (y2 < s->height) {
c = &s->cells[y1 * s->width + x];
- vga_putcharxy(s->ds, x, y2, c->ch,
+ vga_putcharxy(s->ds, x, y2, c->ch,
&(c->t_attrib));
- dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,
+ dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,
FONT_WIDTH, FONT_HEIGHT);
}
}
t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
vga_putcharxy(s->ds, s->x, y, c->ch, &t_attrib);
} else {
- vga_putcharxy(s->ds, s->x, y, c->ch,
+ vga_putcharxy(s->ds, s->x, y, c->ch,
&(c->t_attrib));
}
- dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT,
+ dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT,
FONT_WIDTH, FONT_HEIGHT);
}
}
TextCell *c;
int x, y, y1;
- if (s != active_console)
+ if (s != active_console)
return;
vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
for(y = 0; y < s->height; y++) {
c = s->cells + y1 * s->width;
for(x = 0; x < s->width; x++) {
- vga_putcharxy(s->ds, x, y, c->ch,
+ vga_putcharxy(s->ds, x, y, c->ch,
&(c->t_attrib));
c++;
}
{
TextConsole *s;
int i, y1;
-
+
s = active_console;
if (!s || !s->text_console)
return;
c++;
}
if (s == active_console && s->y_displayed == s->y_base) {
- vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
- s->width * FONT_WIDTH,
+ vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
+ s->width * FONT_WIDTH,
(s->height - 1) * FONT_HEIGHT);
vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
- s->width * FONT_WIDTH, FONT_HEIGHT,
+ s->width * FONT_WIDTH, FONT_HEIGHT,
color_table[0][s->t_attrib_default.bgcol]);
- dpy_update(s->ds, 0, 0,
+ dpy_update(s->ds, 0, 0,
s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
}
}
console_put_lf(s);
break;
case '\b': /* backspace */
- if (s->x > 0)
+ if (s->x > 0)
s->x--;
break;
case '\t': /* tabspace */
case TTY_STATE_CSI: /* handle escape sequence parameters */
if (ch >= '0' && ch <= '9') {
if (s->nb_esc_params < MAX_ESC_PARAMS) {
- s->esc_params[s->nb_esc_params] =
+ s->esc_params[s->nb_esc_params] =
s->esc_params[s->nb_esc_params] * 10 + ch - '0';
}
} else {
TextConsole *s = opaque;
int len;
uint8_t buf[16];
-
+
len = qemu_chr_can_read(s->chr);
if (len > s->out_fifo.count)
len = s->out_fifo.count;
return !active_console->text_console;
}
-void set_color_table(DisplayState *ds)
+void set_color_table(DisplayState *ds)
{
int i, j;
for(j = 0; j < 2; j++) {
s->out_fifo.buf = s->out_fifo_buf;
s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
-
+
if (!color_inited) {
color_inited = 1;
set_color_table(ds);
/*
* defines common to all virtual CPUs
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
#define WORDS_ALIGNED
#endif
-/* some important defines:
- *
+/* some important defines:
+ *
* WORDS_ALIGNED : if defined, the host cpu can only make word aligned
* memory accesses.
- *
+ *
* WORDS_BIGENDIAN : if defined, the host cpu is big endian and
* otherwise little endian.
- *
+ *
* (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
- *
+ *
* TARGET_WORDS_BIGENDIAN : same for target cpu
*/
* type is:
* (empty): integer access
* f : float access
- *
+ *
* sign is:
* (empty): for floats or 32 bit size
* u : unsigned
* w: 16 bits
* l: 32 bits
* q: 64 bits
- *
+ *
* endian is:
* (empty): target cpu endianness or 8 bit access
* r : reversed target cpu endianness (not implemented yet)
#define stfq_raw(p, v) stfq_p(saddr((p)), v)
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
/* if user mode, no other memory access functions */
#define ldub(p) ldub_raw(p)
#define PAGE_VALID 0x0008
/* original state of the write flag (used when tracking self-modifying
code */
-#define PAGE_WRITE_ORG 0x0010
+#define PAGE_WRITE_ORG 0x0010
void page_dump(FILE *f);
int page_get_flags(target_ulong address);
#endif /* SINGLE_CPU_DEFINES */
-void cpu_dump_state(CPUState *env, FILE *f,
+void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags);
if no page found. */
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
-#define CPU_LOG_TB_OUT_ASM (1 << 0)
+#define CPU_LOG_TB_OUT_ASM (1 << 0)
#define CPU_LOG_TB_IN_ASM (1 << 1)
#define CPU_LOG_TB_OP (1 << 2)
#define CPU_LOG_TB_OP_OPT (1 << 3)
typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
+void cpu_register_physical_memory(target_phys_addr_t start_addr,
unsigned long size,
unsigned long phys_offset);
uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr);
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write);
-static inline void cpu_physical_memory_read(target_phys_addr_t addr,
+static inline void cpu_physical_memory_read(target_phys_addr_t addr,
uint8_t *buf, int len)
{
cpu_physical_memory_rw(addr, buf, len, 0);
}
-static inline void cpu_physical_memory_write(target_phys_addr_t addr,
+static inline void cpu_physical_memory_write(target_phys_addr_t addr,
const uint8_t *buf, int len)
{
cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
void stl_phys(target_phys_addr_t addr, uint32_t val);
void stq_phys(target_phys_addr_t addr, uint64_t val);
-void cpu_physical_memory_write_rom(target_phys_addr_t addr,
+void cpu_physical_memory_write_rom(target_phys_addr_t addr,
const uint8_t *buf, int len);
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
uint8_t *buf, int len, int is_write);
#define VGA_DIRTY_FLAG 0x01
return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
}
-static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
+static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
int dirty_flags)
{
return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
#if defined(__powerpc__)
-static inline uint32_t get_tbl(void)
+static inline uint32_t get_tbl(void)
{
uint32_t tbl;
asm volatile("mftb %0" : "=r" (tbl));
return tbl;
}
-static inline uint32_t get_tbu(void)
+static inline uint32_t get_tbu(void)
{
uint32_t tbl;
asm volatile("mftbu %0" : "=r" (tbl));
/*
* common defines for all CPUs
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
#error TARGET_LONG_BITS must be defined before including this header
#endif
-#ifndef TARGET_PHYS_ADDR_BITS
+#ifndef TARGET_PHYS_ADDR_BITS
#if TARGET_LONG_BITS >= HOST_LONG_BITS
#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
#else
#define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
typedef struct CPUTLBEntry {
- /* bit 31 to TARGET_PAGE_BITS : virtual address
+ /* bit 31 to TARGET_PAGE_BITS : virtual address
bit TARGET_PAGE_BITS-1..IO_MEM_SHIFT : if non zero, memory io
zone number
bit 3 : indicates that the entry is invalid
bit 2..0 : zero
*/
- target_ulong addr_read;
- target_ulong addr_write;
- target_ulong addr_code;
+ target_ulong addr_read;
+ target_ulong addr_write;
+ target_ulong addr_code;
/* addend to virtual address to get physical address */
- target_phys_addr_t addend;
+ target_phys_addr_t addend;
} CPUTLBEntry;
#define CPU_COMMON \
/*
* i386 emulator main execution loop
- *
+ *
* Copyright (c) 2003-2005 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
/* exit the current TB from a signal handler. The host registers are
restored in a state compatible with the CPU emulator
*/
-void cpu_resume_from_signal(CPUState *env1, void *puc)
+void cpu_resume_from_signal(CPUState *env1, void *puc)
{
#if !defined(CONFIG_SOFTMMU)
struct ucontext *uc = puc;
unsigned int h;
target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
uint8_t *tc_ptr;
-
+
spin_lock(&tb_lock);
tb_invalidated_flag = 0;
-
+
regs_to_env(); /* XXX: do it just before cpu_gen_code() */
-
+
/* find translated block using physical mappings */
phys_pc = get_phys_addr_code(env, pc);
phys_page1 = phys_pc & TARGET_PAGE_MASK;
tb = *ptb1;
if (!tb)
goto not_found;
- if (tb->pc == pc &&
+ if (tb->pc == pc &&
tb->page_addr[0] == phys_page1 &&
- tb->cs_base == cs_base &&
+ tb->cs_base == cs_base &&
tb->flags == flags) {
/* check next page if needed */
if (tb->page_addr[1] != -1) {
- virt_page2 = (pc & TARGET_PAGE_MASK) +
+ virt_page2 = (pc & TARGET_PAGE_MASK) +
TARGET_PAGE_SIZE;
phys_page2 = get_phys_addr_code(env, virt_page2);
if (tb->page_addr[1] == phys_page2)
tb->flags = flags;
cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
-
+
/* check next page if needed */
virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
phys_page2 = -1;
phys_page2 = get_phys_addr_code(env, virt_page2);
}
tb_link_phys(tb, phys_pc, phys_page2);
-
+
found:
/* we add the TB in the virtual pc hash table */
env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
}
#elif defined(TARGET_PPC)
if (env1->halted) {
- if (env1->msr[MSR_EE] &&
- (env1->interrupt_request &
+ if (env1->msr[MSR_EE] &&
+ (env1->interrupt_request &
(CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) {
env1->halted = 0;
} else {
}
#endif
- cpu_single_env = env1;
+ cpu_single_env = env1;
/* first we save global registers */
#define SAVE_HOST_REGS 1
which will be handled outside the cpu execution
loop */
#if defined(TARGET_I386)
- do_interrupt_user(env->exception_index,
- env->exception_is_int,
- env->error_code,
+ do_interrupt_user(env->exception_index,
+ env->exception_is_int,
+ env->error_code,
env->exception_next_eip);
#endif
ret = env->exception_index;
/* simulate a real cpu exception. On i386, it can
trigger new exceptions, but we do not handle
double or triple faults yet. */
- do_interrupt(env->exception_index,
- env->exception_is_int,
- env->error_code,
+ do_interrupt(env->exception_index,
+ env->exception_is_int,
+ env->error_code,
env->exception_next_eip, 0);
#elif defined(TARGET_PPC)
do_interrupt(env);
#endif
}
env->exception_index = -1;
- }
+ }
#ifdef USE_KQEMU
if (kqemu_is_ok(env) && env->interrupt_request == 0) {
int ret;
T0 = 0; /* force lookup of first TB */
for(;;) {
#if defined(__sparc__) && !defined(HOST_SOLARIS)
- /* g1 can be modified by some libc? functions */
+ /* g1 can be modified by some libc? functions */
tmp_T0 = T0;
-#endif
+#endif
interrupt_request = env->interrupt_request;
if (__builtin_expect(interrupt_request, 0)) {
#if defined(TARGET_I386)
T0 = 0;
#endif
} else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->eflags & IF_MASK) &&
+ (env->eflags & IF_MASK) &&
!(env->hflags & HF_INHIBIT_IRQ_MASK)) {
int intno;
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
#elif defined(TARGET_SH4)
cpu_dump_state(env, logfile, fprintf, 0);
#else
-#error unsupported target CPU
+#error unsupported target CPU
#endif
}
#endif
#endif
#if defined(__sparc__) && !defined(HOST_SOLARIS)
T0 = tmp_T0;
-#endif
+#endif
/* see if we can patch the calling TB. When the TB
spans two pages, we cannot safely do a direct
jump. */
#endif
tb->page_addr[1] == -1
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
- && (tb->cflags & CF_CODE_COPY) ==
+ && (tb->cflags & CF_CODE_COPY) ==
(((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY)
#endif
) {
tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb);
#if defined(USE_CODE_COPY)
/* propagates the FP use info */
- ((TranslationBlock *)(T0 & ~3))->cflags |=
+ ((TranslationBlock *)(T0 & ~3))->cflags |=
(tb->cflags & CF_FP_USED);
#endif
spin_unlock(&tb_lock);
__asm__ __volatile__("call %0\n\t"
"mov %%o7,%%i0"
: /* no outputs */
- : "r" (gen_func)
+ : "r" (gen_func)
: "i0", "i1", "i2", "i3", "i4", "i5",
"l0", "l1", "l2", "l3", "l4", "l5",
"l6", "l7");
#include "hostregs_helper.h"
/* fail safe : never use cpu_single_env outside cpu_exec() */
- cpu_single_env = NULL;
+ cpu_single_env = NULL;
return ret;
}
env = s;
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
selector &= 0xffff;
- cpu_x86_load_seg_cache(env, seg_reg, selector,
+ cpu_x86_load_seg_cache(env, seg_reg, selector,
(selector << 4), 0xffff, 0);
} else {
load_seg(seg_reg, selector);
saved_env = env;
env = s;
-
+
helper_fsave((target_ulong)ptr, data32);
env = saved_env;
saved_env = env;
env = s;
-
+
helper_frstor((target_ulong)ptr, data32);
env = saved_env;
write caused the exception and otherwise 0'. 'old_set' is the
signal set which should be restored */
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
+ int is_write, sigset_t *old_set,
void *puc)
{
TranslationBlock *tb;
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
- qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+ qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
}
/* see if it is an MMU fault */
- ret = cpu_x86_handle_mmu_fault(env, address, is_write,
+ ret = cpu_x86_handle_mmu_fault(env, address, is_write,
((env->hflags & HF_CPL_MASK) == 3), 0);
if (ret < 0)
return 0; /* not an MMU fault */
}
if (ret == 1) {
#if 0
- printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
+ printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
env->eip, env->cr[2], env->error_code);
#endif
/* we restore the process signal mask as the sigreturn should
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+ printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+ printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+ printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
}
if (ret == 1) {
#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
+ printf("PF exception: NIP=0x%08x error=0x%x %p\n",
env->nip, env->error_code, tb);
#endif
/* we restore the process signal mask as the sigreturn should
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+ printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+ printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
}
if (ret == 1) {
#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
+ printf("PF exception: NIP=0x%08x error=0x%x %p\n",
env->nip, env->error_code, tb);
#endif
/* we restore the process signal mask as the sigreturn should
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+ printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
cpu_restore_state(tb, env, pc, puc);
}
#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
+ printf("PF exception: NIP=0x%08x error=0x%x %p\n",
env->nip, env->error_code, tb);
#endif
/* we restore the process signal mask as the sigreturn should
#endif
#if defined(USE_CODE_COPY)
-static void cpu_send_trap(unsigned long pc, int trap,
+static void cpu_send_trap(unsigned long pc, int trap,
struct ucontext *uc)
{
TranslationBlock *tb;
}
#endif
-int cpu_signal_handler(int host_signum, void *pinfo,
+int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
return 1;
} else
#endif
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- trapno == 0xe ?
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ trapno == 0xe ?
(ERROR_sig(uc) >> 1) & 1 : 0,
&uc->uc_sigmask, puc);
}
unsigned long pc;
pc = uc->uc_mcontext.gregs[REG_RIP];
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
(uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
&uc->uc_sigmask, puc);
}
# define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
#endif /* __APPLE__ */
-int cpu_signal_handler(int host_signum, void *pinfo,
+int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
is_write = 1;
#endif
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write, &uc->uc_sigmask, puc);
}
#elif defined(__alpha__)
-int cpu_signal_handler(int host_signum, void *pinfo,
+int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
is_write = 1;
}
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write, &uc->uc_sigmask, puc);
}
#elif defined(__sparc__)
-int cpu_signal_handler(int host_signum, void *pinfo,
+int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
unsigned long pc;
int is_write;
uint32_t insn;
-
+
/* XXX: is there a standard glibc define ? */
pc = regs[1];
/* XXX: need kernel patch to get write flag faster */
break;
}
}
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write, sigmask, NULL);
}
#elif defined(__arm__)
-int cpu_signal_handler(int host_signum, void *pinfo,
+int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.gregs[R15];
/* XXX: compute is_write */
is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write,
&uc->uc_sigmask, puc);
}
#elif defined(__mc68000)
-int cpu_signal_handler(int host_signum, void *pinfo,
+int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.gregs[16];
/* XXX: compute is_write */
is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write,
&uc->uc_sigmask, puc);
}
#elif defined(__s390__)
-int cpu_signal_handler(int host_signum, void *pinfo,
+int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.psw.addr;
/* XXX: compute is_write */
is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
+ return handle_cpu_signal(pc, (unsigned long)info->si_addr,
is_write,
&uc->uc_sigmask, puc);
}
/*
* Simple C functions to supplement the C library
- *
+ *
* Copyright (c) 2006 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
{
int len;
len = strlen(buf);
- if (len < buf_size)
+ if (len < buf_size)
pstrcpy(buf + len, buf_size - len, s);
return buf;
}
if(!(sysctl = sysctl->childs))
break;
}
-
+
if(ret->childs)
qerror("we shouldn't have a directory element\n");
//bswap_syctl(name, namelen, newp, newlen);
tswap32s((uint32_t*)oldlenp);
}
-
+
if(name) /* Sometimes sysctl is called with no arg1, ignore */
ret = get_errno(sysctl(name, namelen, oldp, oldlenp, newp, newlen));
enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
-enum bfd_architecture
+enum bfd_architecture
{
bfd_arch_unknown, /* File arch not known */
bfd_arch_obscure, /* Arch known, not one of these */
#define bfd_mach_mcf5249 16
#define bfd_mach_mcf547x 17
#define bfd_mach_mcf548x 18
- bfd_arch_vax, /* DEC Vax */
+ bfd_arch_vax, /* DEC Vax */
bfd_arch_i960, /* Intel 960 */
/* The order of the following is important.
- lower number indicates a machine type that
+ lower number indicates a machine type that
only accepts a subset of the instructions
available to machines with higher numbers.
The exception is the "ca", which is
- incompatible with all other machines except
+ incompatible with all other machines except
"core". */
#define bfd_mach_i960_core 1
dis_dref2 /* Two data references in instruction */
};
-/* This struct is passed into the instruction decoding routine,
+/* This struct is passed into the instruction decoding routine,
and is passed back out into each callback. The various fields are used
for conveying information from your main routine into your callbacks,
for passing information into the instruction decoders (such as the
/* Disassemble this for me please... (debugging). 'flags' has the following
values:
i386 - nonzero means 16 bit code
- arm - nonzero means thumb code
+ arm - nonzero means thumb code
ppc - nonzero means little endian
other targets - unused
*/
#if defined(TARGET_I386)
if (flags == 2)
disasm_info.mach = bfd_mach_x86_64;
- else if (flags == 1)
+ else if (flags == 1)
disasm_info.mach = bfd_mach_i386_i8086;
else
disasm_info.mach = bfd_mach_i386_i386;
print_insn = print_insn_sparc;
#ifdef TARGET_SPARC64
disasm_info.mach = bfd_mach_sparc_v9b;
-#endif
+#endif
#elif defined(TARGET_PPC)
if (flags)
disasm_info.endian = BFD_ENDIAN_LITTLE;
print_insn = print_insn_alpha;
#elif defined(__sparc__)
print_insn = print_insn_sparc;
-#elif defined(__arm__)
+#elif defined(__arm__)
print_insn = print_insn_arm;
#elif defined(__MIPSEB__)
print_insn = print_insn_big_mips;
Elf32_Sym *sym;
struct syminfo *s;
target_ulong addr;
-
+
for (s = syminfos; s; s = s->next) {
sym = s->disas_symtab;
for (i = 0; i < s->disas_num_syms; i++) {
#if defined(TARGET_I386)
if (flags == 2)
disasm_info.mach = bfd_mach_x86_64;
- else if (flags == 1)
+ else if (flags == 1)
disasm_info.mach = bfd_mach_i386_i8086;
else
disasm_info.mach = bfd_mach_i386_i386;
/* the symbols are considered non exported so a br immediate is generated */
#define __hidden __attribute__((visibility("hidden")))
#else
-#define __hidden
+#define __hidden
#endif
#if defined(__alpha__)
/*
* Generic Dynamic compiler generator
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* The COFF object format support was extracted from Kazu's QEMU port
struct nlist_extended
{
union {
- char *n_name;
- long n_strx;
+ char *n_name;
+ long n_strx;
} n_un;
- unsigned char n_type;
- unsigned char n_sect;
+ unsigned char n_type;
+ unsigned char n_sect;
short st_desc;
unsigned long st_value;
unsigned long st_size;
} swaptest;
swaptest.i = 1;
- return (h->e_ident[EI_DATA] == ELFDATA2MSB) !=
+ return (h->e_ident[EI_DATA] == ELFDATA2MSB) !=
(swaptest.b[0] == 0);
}
-
+
void elf_swap_ehdr(struct elfhdr *h)
{
swab16s(&h->e_type); /* Object file type */
#endif
}
-struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
+struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
const char *name)
{
int i;
for(i = 0; i < ehdr.e_shnum; i++) {
sec = &shdr[i];
- if (sec->sh_type == SHT_RELOC && sec->sh_info == sh_index)
+ if (sec->sh_type == SHT_RELOC && sec->sh_info == sh_index)
return i;
}
return 0;
ElfW(Sym) *sym;
char *shstr;
ELF_RELOC *rel;
-
+
fd = open(filename, O_RDONLY);
- if (fd < 0)
+ if (fd < 0)
error("can't open file '%s'", filename);
-
+
/* Read ELF header. */
if (read(fd, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
error("unable to read file header");
/* read all section data */
sdata = malloc(sizeof(void *) * ehdr.e_shnum);
memset(sdata, 0, sizeof(void *) * ehdr.e_shnum);
-
+
for(i = 0;i < ehdr.e_shnum; i++) {
sec = &shdr[i];
if (sec->sh_type != SHT_NOBITS)
symtab = (ElfW(Sym) *)sdata[symtab_sec - shdr];
strtab = (char *)sdata[symtab_sec->sh_link];
-
+
nb_syms = symtab_sec->sh_size / sizeof(ElfW(Sym));
if (do_swap) {
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
{
char *q;
int c, i, len;
-
+
if (ext_sym->e.e.e_zeroes != 0) {
q = sym->st_name;
for(i = 0; i < 8; i++) {
if (sym->st_syment->e_scnum == data_shndx &&
text_data >= sym->st_value &&
text_data < sym->st_value + sym->st_size) {
-
+
return sym->st_name;
}
uint32_t *n_strtab;
EXE_SYM *sym;
EXE_RELOC *rel;
-
- fd = open(filename, O_RDONLY
+
+ fd = open(filename, O_RDONLY
#ifdef _WIN32
| O_BINARY
#endif
);
- if (fd < 0)
+ if (fd < 0)
error("can't open file '%s'", filename);
-
+
/* Read COFF header. */
if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr))
error("unable to read file header");
/* read section headers */
shdr = load_data(fd, sizeof(struct external_filehdr) + fhdr.f_opthdr, fhdr.f_nscns * sizeof(struct external_scnhdr));
-
+
/* read all section data */
sdata = malloc(sizeof(void *) * fhdr.f_nscns);
memset(sdata, 0, sizeof(void *) * fhdr.f_nscns);
-
+
const char *p;
for(i = 0;i < fhdr.f_nscns; i++) {
sec = &shdr[i];
if (!data_sec)
error("could not find .data section");
coff_data_shndx = data_sec - shdr;
-
+
coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ);
for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
for(i=0;i<8;i++)
n_strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), STRTAB_SIZE);
- strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), *n_strtab);
-
+ strtab = load_data(fd, (fhdr.f_symptr + fhdr.f_nsyms*SYMESZ), *n_strtab);
+
nb_syms = fhdr.f_nsyms;
for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
} else {
sym->st_size = 0;
}
-
+
sym->st_type = ext_sym->e_type;
sym->st_shndx = ext_sym->e_scnum;
}
-
+
/* find text relocations, if any */
sec = &shdr[coff_text_shndx];
coff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc*RELSZ);
/* set coff relocation */
relocs = malloc(sizeof(struct coff_rel) * nb_relocs);
- for (i = 0, ext_rel = coff_relocs, rel = relocs; i < nb_relocs;
+ for (i = 0, ext_rel = coff_relocs, rel = relocs; i < nb_relocs;
i++, ext_rel++, rel++) {
memset(rel, 0, sizeof(*rel));
rel->r_reloc = ext_rel;
/* relocs */
struct relocation_info *relocs;
-
+
/* symbols */
EXE_SYM *symtab;
struct nlist *symtab_std;
static char *get_sym_name(EXE_SYM *sym)
{
char *name = find_str_by_index(sym->n_un.n_strx);
-
+
if ( sym->n_type & N_STAB ) /* Debug symbols are ignored */
return "debug";
-
+
if(!name)
return name;
if(name[0]=='_')
}
/* find a section index given its segname, sectname */
-static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,
+static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,
const char *sectname)
{
int i;
}
/* find a section header given its segname, sectname */
-struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,
+struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,
const char *sectname)
{
int index = find_mach_sec_index(section_hdr, shnum, segname, sectname);
static inline void fetch_next_pair_value(struct relocation_info * rel, unsigned int *value)
{
struct scattered_relocation_info * scarel;
-
+
if(R_SCATTERED & rel->r_address) {
scarel = (struct scattered_relocation_info*)rel;
if(scarel->r_type != PPC_RELOC_PAIR)
static const char * find_sym_with_value_and_sec_number( int value, int sectnum, int * offset )
{
int i, ret = -1;
-
+
for( i = 0 ; i < nb_syms; i++ )
{
if( !(symtab[i].n_type & N_STAB) && (symtab[i].n_type & N_SECT) &&
}
}
-/*
- * Find symbol name given a (virtual) address, and a section which is of type
+/*
+ * Find symbol name given a (virtual) address, and a section which is of type
* S_NON_LAZY_SYMBOL_POINTERS or S_LAZY_SYMBOL_POINTERS or S_SYMBOL_STUBS
*/
static const char * find_reloc_name_in_sec_ptr(int address, struct section * sec_hdr)
{
unsigned int tocindex, symindex, size;
const char *name = 0;
-
+
/* Sanity check */
if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + sec_hdr->size) ) )
return (char*)0;
-
+
if( sec_hdr->flags & S_SYMBOL_STUBS ){
size = sec_hdr->reserved2;
if(size == 0)
error("size = 0");
-
+
}
else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||
sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)
size = sizeof(unsigned long);
else
return 0;
-
+
/* Compute our index in toc */
tocindex = (address - sec_hdr->addr)/size;
symindex = tocdylib[sec_hdr->reserved1 + tocindex];
-
+
name = get_sym_name(&symtab[symindex]);
return name;
int sectnum = rel->r_symbolnum;
int sectoffset;
int other_half=0;
-
+
/* init the slide value */
*sslide = 0;
-
+
if(R_SCATTERED & rel->r_address)
return (char *)find_reloc_name_given_its_address(sca_rel->r_value);
if(rel->r_extern)
{
/* ignore debug sym */
- if ( symtab[rel->r_symbolnum].n_type & N_STAB )
+ if ( symtab[rel->r_symbolnum].n_type & N_STAB )
return 0;
return get_sym_name(&symtab[rel->r_symbolnum]);
}
/* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */
sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;
-
+
if(sectnum==0xffffff)
return 0;
if(rel->r_pcrel)
sectoffset += rel->r_address;
-
+
if (rel->r_type == PPC_RELOC_BR24)
name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, §ion_hdr[sectnum-1]);
/* search it in the full symbol list, if not found */
if(!name)
name = (char *)find_sym_with_value_and_sec_number(sectoffset, sectnum, sslide);
-
+
return name;
}
unsigned int i, j;
EXE_SYM *sym;
struct nlist *syment;
-
+
fd = open(filename, O_RDONLY);
- if (fd < 0)
+ if (fd < 0)
error("can't open file '%s'", filename);
-
+
/* Read Mach header. */
if (read(fd, &mach_hdr, sizeof (mach_hdr)) != sizeof (mach_hdr))
error("unable to read file header");
if (!check_mach_header(mach_hdr)) {
error("bad Mach header");
}
-
+
if (mach_hdr.cputype != CPU_TYPE_POWERPC)
error("Unsupported CPU");
-
+
if (mach_hdr.filetype != MH_OBJECT)
error("Unsupported Mach Object");
-
+
/* read segment headers */
for(i=0, j=sizeof(mach_hdr); i<mach_hdr.ncmds ; i++)
{
/* read all section data */
sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);
memset(sdata, 0, sizeof(void *) * segment->nsects);
-
+
/* Load the data in section data */
for(i = 0; i < segment->nsects; i++) {
sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);
}
-
+
/* text section */
text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
if (i == -1 || !text_sec_hdr)
error("could not find __TEXT,__text section");
text = sdata[i];
-
+
/* Make sure dysym was loaded */
if(!(int)dysymtabcmd)
error("could not find __DYSYMTAB segment");
-
+
/* read the table of content of the indirect sym */
tocdylib = load_data( fd, dysymtabcmd->indirectsymoff, dysymtabcmd->nindirectsyms * sizeof(uint32_t) );
-
+
/* Make sure symtab was loaded */
if(!(int)symtabcmd)
error("could not find __SYMTAB segment");
symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct nlist));
strtab = load_data(fd, symtabcmd->stroff, symtabcmd->strsize);
-
+
symtab = malloc(sizeof(EXE_SYM) * nb_syms);
-
+
/* Now transform the symtab, to an extended version, with the sym size, and the C name */
for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
struct nlist *sym_follow, *sym_next = 0;
unsigned int j;
memset(sym, 0, sizeof(*sym));
-
+
if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
continue;
-
+
memcpy(sym, syment, sizeof(*syment));
-
+
/* Find the following symbol in order to get the current symbol size */
for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {
if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))
else
sym->st_size = text_sec_hdr->size - sym->st_value;
}
-
+
/* Find Reloc */
relocs = load_data(fd, text_sec_hdr->reloff, text_sec_hdr->nreloc * sizeof(struct relocation_info));
nb_relocs = text_sec_hdr->nreloc;
uint8_t data_allocated[1024];
unsigned int data_index;
int type;
-
+
memset(data_allocated, 0, sizeof(data_allocated));
-
+
p = p_start;
min_offset = p_end - p_start;
spare = 0x7fffffff;
if (spare > max_pool - offset)
spare = max_pool - offset;
if ((offset & 3) !=0)
- error("%s:%04x: pc offset must be 32 bit aligned",
+ error("%s:%04x: pc offset must be 32 bit aligned",
name, start_offset + p - p_start);
if (offset < 0)
error("%s:%04x: Embedded literal value",
name, start_offset + p - p_start);
pc_offset = p - p_start + offset + 8;
- if (pc_offset <= (p - p_start) ||
+ if (pc_offset <= (p - p_start) ||
pc_offset >= (p_end - p_start))
- error("%s:%04x: pc offset must point inside the function code",
+ error("%s:%04x: pc offset must point inside the function code",
name, start_offset + p - p_start);
if (pc_offset < min_offset)
min_offset = pc_offset;
if (outfile) {
/* The intruction position */
- fprintf(outfile, " arm_ldr_ptr->ptr = gen_code_ptr + %d;\n",
+ fprintf(outfile, " arm_ldr_ptr->ptr = gen_code_ptr + %d;\n",
p - p_start);
/* The position of the constant pool data. */
data_index = ((p_end - p_start) - pc_offset) >> 2;
- fprintf(outfile, " arm_ldr_ptr->data_ptr = arm_data_ptr - %d;\n",
+ fprintf(outfile, " arm_ldr_ptr->data_ptr = arm_data_ptr - %d;\n",
data_index);
fprintf(outfile, " arm_ldr_ptr->type = %d;\n", type);
fprintf(outfile, " arm_ldr_ptr++;\n");
#define MAX_ARGS 3
/* generate op code */
-void gen_code(const char *name, host_ulong offset, host_ulong size,
+void gen_code(const char *name, host_ulong offset, host_ulong size,
FILE *outfile, int gen_switch)
{
int copy_size = 0;
}
copy_size = len;
}
-#endif
+#endif
#elif defined(HOST_PPC)
{
uint8_t *p;
#endif
if (get32((uint32_t *)p) != 0x6bfa8001)
error("ret expected at the end of %s", name);
- copy_size = p - p_start;
+ copy_size = p - p_start;
}
#elif defined(HOST_IA64)
{
} else {
error("No save at the beginning of %s", name);
}
-
+
/* Skip a preceeding nop, if present. */
if (p > p_start) {
skip_insn = get32((uint32_t *)(p - 0x4));
if (skip_insn == 0x01000000)
p -= 4;
}
-
+
copy_size = p - p_start;
}
#elif defined(HOST_ARM)
p_start -= 4;
start_offset -= 4;
}
- copy_size = arm_emit_ldr_info(name, start_offset, NULL, p_start, p_end,
+ copy_size = arm_emit_ldr_info(name, start_offset, NULL, p_start, p_end,
relocs, nb_relocs);
}
#elif defined(HOST_M68K)
error("empty code for %s", name);
// remove NOP's, probably added for alignment
while ((get16((uint16_t *)p) == 0x4e71) &&
- (p>p_start))
+ (p>p_start))
p -= 2;
if (get16((uint16_t *)p) != 0x4e75)
error("rts expected at the end of %s", name);
}
}
}
-
+
nb_args = 0;
while (nb_args < MAX_ARGS && args_present[nb_args])
nb_args++;
sym_name = get_rel_sym_name(rel);
if(!sym_name)
continue;
- if (*sym_name &&
+ if (*sym_name &&
!strstart(sym_name, "__op_param", NULL) &&
!strstart(sym_name, "__op_jmp", NULL) &&
!strstart(sym_name, "__op_gen_label", NULL)) {
if (strstart(sym_name, "__op_label", &p)) {
uint8_t *ptr;
unsigned long offset;
-
+
/* test if the variable refers to a label inside
the code we are generating */
#ifdef CONFIG_FORMAT_COFF
/* try to find a matching relocation */
reloc_shndx = find_reloc(sym->st_shndx);
if (reloc_shndx) {
- nb_relocs1 = shdr[reloc_shndx].sh_size /
+ nb_relocs1 = shdr[reloc_shndx].sh_size /
shdr[reloc_shndx].sh_entsize;
rel = (ELF_RELOC *)sdata[reloc_shndx];
for(j = 0; j < nb_relocs1; j++) {
}
}
}
-#endif
+#endif
if (val >= start_offset && val <= start_offset + copy_size) {
n = strtol(p, NULL, 10);
fprintf(outfile, " label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset));
type = ELF32_R_TYPE(rel->r_info);
switch(type) {
case R_386_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, name, addend);
break;
case R_386_PC32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
reloc_offset, name, reloc_offset, addend);
break;
default:
type = rel->r_type;
switch(type) {
case DIR32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, name, addend);
break;
case DISP32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",
reloc_offset, name, reloc_offset, addend);
break;
default:
reloc_offset = rel->r_offset - start_offset;
switch(type) {
case R_X86_64_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
reloc_offset, name, addend);
break;
case R_X86_64_32S:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
reloc_offset, name, addend);
break;
case R_X86_64_PC32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
reloc_offset, name, reloc_offset, addend);
break;
default:
n, reloc_offset);
continue;
}
-
+
get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = rel->r_addend;
switch(type) {
case R_PPC_ADDR32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, name, addend);
break;
case R_PPC_ADDR16_LO:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
reloc_offset, name, addend);
break;
case R_PPC_ADDR16_HI:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
reloc_offset, name, addend);
break;
case R_PPC_ADDR16_HA:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
reloc_offset, name, addend);
break;
case R_PPC_REL24:
/* warning: must be at 32 MB distancy */
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
reloc_offset, reloc_offset, name, reloc_offset, addend);
break;
default:
const char *p;
int slide, sslide;
int i;
-
+
for(i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
unsigned int offset, length, value = 0;
unsigned int type, pcrel, isym = 0;
unsigned int usesym = 0;
-
+
if(R_SCATTERED & rel->r_address) {
scarel = (struct scattered_relocation_info*)rel;
offset = (unsigned int)scarel->r_address;
pcrel = rel->r_pcrel;
type = rel->r_type;
}
-
+
slide = offset - start_offset;
-
- if (!(offset >= start_offset && offset < start_offset + size))
+
+ if (!(offset >= start_offset && offset < start_offset + size))
continue; /* not in our range */
sym_name = get_reloc_name(rel, &sslide);
-
+
if(usesym && symtab[isym].n_type & N_STAB)
continue; /* don't handle STAB (debug sym) */
-
+
if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
int n;
n = strtol(p, NULL, 10);
n, slide);
continue; /* Nothing more to do */
}
-
+
if(!sym_name)
{
fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
continue; /* dunno how to handle without final_sym_name */
}
-
- get_reloc_expr(final_sym_name, sizeof(final_sym_name),
+
+ get_reloc_expr(final_sym_name, sizeof(final_sym_name),
sym_name);
switch(type) {
case PPC_RELOC_BR24:
if (!strstart(sym_name,"__op_gen_label",&p)) {
fprintf(outfile, "{\n");
fprintf(outfile, " uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n",
slide, slide, name, sslide );
fprintf(outfile, "}\n");
} else {
}
break;
case PPC_RELOC_HI16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n",
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n",
slide, final_sym_name, sslide);
break;
case PPC_RELOC_LO16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d);\n",
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d);\n",
slide, final_sym_name, sslide);
break;
case PPC_RELOC_HA16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d + 0x8000) >> 16;\n",
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d + 0x8000) >> 16;\n",
slide, final_sym_name, sslide);
break;
default:
reloc_offset = rel->r_offset - start_offset;
switch(type) {
case R_390_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, name, addend);
break;
case R_390_16:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, name, addend);
break;
case R_390_8:
- fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, name, addend);
break;
default:
reloc_offset = rel->r_offset - start_offset;
switch(type) {
case R_SPARC_32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, name, addend);
break;
case R_SPARC_HI22:
reloc_offset = rel->r_offset - start_offset;
switch(type) {
case R_ARM_ABS32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
reloc_offset, name, addend);
break;
case R_ARM_PC24:
case R_ARM_JUMP24:
case R_ARM_CALL:
- fprintf(outfile, " arm_reloc_pc24((uint32_t *)(gen_code_ptr + %d), 0x%x, %s);\n",
+ fprintf(outfile, " arm_reloc_pc24((uint32_t *)(gen_code_ptr + %d), 0x%x, %s);\n",
reloc_offset, addend, name);
break;
default:
switch(type) {
case R_68K_32:
fprintf(outfile, " /* R_68K_32 RELOC, offset %x */\n", rel->r_offset) ;
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %#x;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %#x;\n",
reloc_offset, name, addend );
break;
case R_68K_PC32:
fprintf(outfile, " /* R_68K_PC32 RELOC, offset %x */\n", rel->r_offset);
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %#x) + %#x;\n",
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %#x) + %#x;\n",
reloc_offset, name, reloc_offset, /*sym->st_value+*/ addend);
break;
default:
gen_code(name, sym->st_value, sym->st_size, outfile, 0);
}
}
-
+
} else {
/* generate big code generation switch */
eliminating the neeed to jump around the pool.
We currently generate:
-
+
[ For this example we assume merging would move op1_pool out of range.
In practice we should be able to combine many ops before the offset
limits are reached. ]
" opc_ptr = opc_buf;\n"
" opparam_ptr = opparam_buf;\n");
- /* Generate prologue, if needed. */
+ /* Generate prologue, if needed. */
fprintf(outfile,
" for(;;) {\n");
name = get_sym_name(sym);
if (strstart(name, OP_PREFIX, NULL)) {
#if 0
- printf("%4d: %s pos=0x%08x len=%d\n",
+ printf("%4d: %s pos=0x%08x len=%d\n",
i, name, sym->st_value, sym->st_size);
#endif
#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
"plt_target, plt_offset);\n }\n");
#endif
-/* generate some code patching */
+/* generate some code patching */
#ifdef HOST_ARM
fprintf(outfile,
"if (arm_data_ptr != arm_data_table + ARM_LDR_TABLE_SIZE)\n"
/*
* dyngen helpers
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
start &= ~(MIN_CACHE_LINE_SIZE - 1);
stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
+
for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
}
}
static uint8_t *arm_flush_ldr(uint8_t *gen_code_ptr,
- LDREntry *ldr_start, LDREntry *ldr_end,
- uint32_t *data_start, uint32_t *data_end,
+ LDREntry *ldr_start, LDREntry *ldr_end,
+ uint32_t *data_start, uint32_t *data_end,
int gen_jmp)
{
LDREntry *le;
uint8_t *data_ptr;
uint32_t insn;
uint32_t mask;
-
+
data_size = (data_end - data_start) << 2;
if (gen_jmp) {
arm_reloc_pc24((uint32_t *)gen_code_ptr, 0xeafffffe, target);
gen_code_ptr += 4;
}
-
+
/* copy the data */
data_ptr = gen_code_ptr;
memcpy(gen_code_ptr, data_start, data_size);
gen_code_ptr += data_size;
-
+
/* patch the ldr to point to the data */
for(le = ldr_start; le < ldr_end; le++) {
ptr = (uint32_t *)le->ptr;
- offset = ((unsigned long)(le->data_ptr) - (unsigned long)data_start) +
- (unsigned long)data_ptr -
+ offset = ((unsigned long)(le->data_ptr) - (unsigned long)data_start) +
+ (unsigned long)data_ptr -
(unsigned long)ptr - 8;
if (offset < 0) {
fprintf(stderr, "Negative constant pool offset\n");
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
#define SHN_MIPS_ACCOMON 0xff00
-
+
typedef struct elf32_shdr {
Elf32_Word sh_name;
Elf32_Word sh_type;
bswap16s(&sym->st_shndx);
}
-static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table,
+static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table,
int n, int type)
{
int i;
int nsyms, i;
char *str = NULL;
- shdr_table = load_at(fd, ehdr->e_shoff,
+ shdr_table = load_at(fd, ehdr->e_shoff,
sizeof(struct elf_shdr) * ehdr->e_shnum);
if (!shdr_table)
return -1;
-
+
if (must_swab) {
for (i = 0; i < ehdr->e_shnum; i++) {
glue(bswap_shdr, SZ)(shdr_table + i);
}
}
-
+
symtab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_SYMTAB);
if (!symtab)
goto fail;
glue(bswap_phdr, SZ)(ph);
}
}
-
+
total_size = 0;
for(i = 0; i < ehdr.e_phnum; i++) {
ph = &phdr[i];
/*
* internal execution defines for qemu
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
typedef void (GenOpFunc1)(long);
typedef void (GenOpFunc2)(long, long);
typedef void (GenOpFunc3)(long, long, long);
-
+
#if defined(TARGET_I386)
void optimize_flags_init(void);
void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);
int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
int max_code_size, int *gen_code_size_ptr);
-int cpu_restore_state(struct TranslationBlock *tb,
+int cpu_restore_state(struct TranslationBlock *tb,
CPUState *env, unsigned long searched_pc,
void *puc);
int cpu_gen_code_copy(CPUState *env, struct TranslationBlock *tb,
int max_code_size, int *gen_code_size_ptr);
-int cpu_restore_state_copy(struct TranslationBlock *tb,
+int cpu_restore_state_copy(struct TranslationBlock *tb,
CPUState *env, unsigned long searched_pc,
void *puc);
void cpu_resume_from_signal(CPUState *env1, void *puc);
void cpu_exec_init(CPUState *env);
int page_unprotect(target_ulong address, unsigned long pc, void *puc);
-void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
+void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
int is_cpu_write_access);
void tb_invalidate_page_range(target_ulong start, target_ulong end);
void tlb_flush_page(CPUState *env, target_ulong addr);
void tlb_flush(CPUState *env, int flush_global);
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
+int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
+ target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu);
-static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
+static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
+ target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu)
{
if (prot & PAGE_READ)
#define CODE_GEN_MAX_BLOCKS (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE)
-#if defined(__powerpc__)
+#if defined(__powerpc__)
#define USE_DIRECT_JUMP
#endif
#if defined(__i386__) && !defined(_WIN32)
uint8_t *tc_ptr; /* pointer to the translated code */
/* next matching tb for physical address. */
- struct TranslationBlock *phys_hash_next;
+ struct TranslationBlock *phys_hash_next;
/* first and second physical page containing code. The lower bit
of the pointer tells the index in page_next[] */
- struct TranslationBlock *page_next[2];
- target_ulong page_addr[2];
+ struct TranslationBlock *page_next[2];
+ target_ulong page_addr[2];
/* the following data are used to directly call another TB from
the code of this one. */
the two least significant bits of the pointers to tell what is
the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 =
jmp_first */
- struct TranslationBlock *jmp_next[2];
+ struct TranslationBlock *jmp_next[2];
struct TranslationBlock *jmp_first;
} TranslationBlock;
TranslationBlock *tb_alloc(target_ulong pc);
void tb_flush(CPUState *env);
-void tb_link_phys(TranslationBlock *tb,
+void tb_link_phys(TranslationBlock *tb,
target_ulong phys_pc, target_ulong phys_page2);
extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
}
#endif
-static inline void tb_set_jmp_target(TranslationBlock *tb,
+static inline void tb_set_jmp_target(TranslationBlock *tb,
int n, unsigned long addr)
{
unsigned long offset;
#else
/* set the jump target */
-static inline void tb_set_jmp_target(TranslationBlock *tb,
+static inline void tb_set_jmp_target(TranslationBlock *tb,
int n, unsigned long addr)
{
tb->tb_next[n] = addr;
#endif
-static inline void tb_add_jump(TranslationBlock *tb, int n,
+static inline void tb_add_jump(TranslationBlock *tb, int n,
TranslationBlock *tb_next)
{
/* NOTE: this test is only needed for thread safety */
if (!tb->jmp_next[n]) {
/* patch the native jump address */
tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
-
+
/* add in TB jmp circular list */
tb->jmp_next[n] = tb_next->jmp_first;
tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
static inline int testandset (int *p)
{
long int readval = 0;
-
+
__asm__ __volatile__ ("lock; cmpxchgl %2, %0"
: "+m" (*p), "+a" (readval)
: "r" (1)
static inline int testandset (int *p)
{
long int readval = 0;
-
+
__asm__ __volatile__ ("lock; cmpxchgl %2, %0"
: "+m" (*p), "+a" (readval)
: "r" (1)
__asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
" jl 0b"
: "=&d" (ret)
- : "r" (1), "a" (p), "0" (*p)
+ : "r" (1), "a" (p), "0" (*p)
: "cc", "memory" );
return ret;
}
__asm__ __volatile__("swp %0, %1, [%2]"
: "=r"(ret)
: "0"(1), "r"(spinlock));
-
+
return ret;
}
#endif
#if !defined(CONFIG_USER_ONLY)
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+void tlb_fill(target_ulong addr, int is_write, int is_user,
void *retaddr);
#define ACCESS_TYPE 3
#else
#error unimplemented CPU
#endif
- if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
+ if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
(addr & TARGET_PAGE_MASK), 0)) {
ldub_code(addr);
}
static inline int kqemu_is_ok(CPUState *env)
{
return(env->kqemu_enabled &&
- (env->cr[0] & CR0_PE_MASK) &&
+ (env->cr[0] & CR0_PE_MASK) &&
!(env->hflags & HF_INHIBIT_IRQ_MASK) &&
(env->eflags & IF_MASK) &&
!(env->eflags & VM_MASK) &&
- (env->kqemu_enabled == 2 ||
+ (env->kqemu_enabled == 2 ||
((env->hflags & HF_CPL_MASK) == 3 &&
(env->eflags & IOPL_MASK) != IOPL_MASK)));
}
/*
* virtual page mapping and translated block handling
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
//#define DEBUG_UNASSIGNED
/* make various TB consistency checks */
-//#define DEBUG_TB_CHECK
-//#define DEBUG_TLB_CHECK
+//#define DEBUG_TB_CHECK
+//#define DEBUG_TLB_CHECK
#if !defined(CONFIG_USER_ONLY)
/* TB consistency checks only implemented for usermode emulation. */
CPUState *first_cpu;
/* current CPU in the current thread. It is only valid inside
cpu_exec() */
-CPUState *cpu_single_env;
+CPUState *cpu_single_env;
typedef struct PageDesc {
/* list of TBs intersecting this ram page */
{
SYSTEM_INFO system_info;
DWORD old_protect;
-
+
GetSystemInfo(&system_info);
qemu_real_host_page_size = system_info.dwPageSize;
-
+
VirtualProtect(code_gen_buffer, sizeof(code_gen_buffer),
PAGE_EXECUTE_READWRITE, &old_protect);
}
start = (unsigned long)code_gen_buffer;
start &= ~(qemu_real_host_page_size - 1);
-
+
end = (unsigned long)code_gen_buffer + sizeof(code_gen_buffer);
end += qemu_real_host_page_size - 1;
end &= ~(qemu_real_host_page_size - 1);
-
- mprotect((void *)start, end - start,
+
+ mprotect((void *)start, end - start,
PROT_READ | PROT_WRITE | PROT_EXEC);
}
#endif
#if !defined(CONFIG_USER_ONLY)
static void tlb_protect_code(ram_addr_t ram_addr);
-static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
+static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
target_ulong vaddr);
#endif
{
CPUState *env;
#if defined(DEBUG_FLUSH)
- printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n",
- code_gen_ptr - code_gen_buffer,
- nb_tbs,
+ printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n",
+ code_gen_ptr - code_gen_buffer,
+ nb_tbs,
nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0);
#endif
nb_tbs = 0;
-
+
for(env = first_cpu; env != NULL; env = env->next_cpu) {
memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
}
{
TranslationBlock *tb;
int i, flags1, flags2;
-
+
for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
flags1 = page_get_flags(tb->pc);
unsigned int h, n1;
target_ulong phys_pc;
TranslationBlock *tb1, *tb2;
-
+
/* remove the TB from the hash list */
phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
h = tb_phys_hash_func(phys_pc);
- tb_remove(&tb_phys_hash[h], tb,
+ tb_remove(&tb_phys_hash[h], tb,
offsetof(TranslationBlock, phys_hash_next));
/* remove the TB from the page list */
{
int n, tb_start, tb_end;
TranslationBlock *tb;
-
+
p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8);
if (!p->code_bitmap)
return;
#ifdef TARGET_HAS_PRECISE_SMC
-static void tb_gen_code(CPUState *env,
+static void tb_gen_code(CPUState *env,
target_ulong pc, target_ulong cs_base, int flags,
int cflags)
{
tb->cflags = cflags;
cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
-
+
/* check next page if needed */
virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
phys_page2 = -1;
tb_link_phys(tb, phys_pc, phys_page2);
}
#endif
-
+
/* invalidate all TBs which intersect with the target physical page
starting in range [start;end[. NOTE: start and end must refer to
the same physical page. 'is_cpu_write_access' should be true if called
from a real cpu write access: the virtual CPU will exit the current
TB if code is modified inside this TB. */
-void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
+void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
int is_cpu_write_access)
{
int n, current_tb_modified, current_tb_not_found, current_flags;
target_ulong current_pc, current_cs_base;
p = page_find(start >> TARGET_PAGE_BITS);
- if (!p)
+ if (!p)
return;
- if (!p->code_bitmap &&
+ if (!p->code_bitmap &&
++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD &&
is_cpu_write_access) {
/* build code bitmap */
that the modification is after the current PC, but it
would require a specialized function to partially
restore the CPU state */
-
+
current_tb_modified = 1;
- cpu_restore_state(current_tb, env,
+ cpu_restore_state(current_tb, env,
env->mem_write_pc, NULL);
#if defined(TARGET_I386)
current_flags = env->hflags;
modifying the memory. It will ensure that it cannot modify
itself */
env->current_tb = NULL;
- tb_gen_code(env, current_pc, current_cs_base, current_flags,
+ tb_gen_code(env, current_pc, current_cs_base, current_flags,
CF_SINGLE_INSN);
cpu_resume_from_signal(env, NULL);
}
#if 0
if (1) {
if (loglevel) {
- fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
- cpu_single_env->mem_write_vaddr, len,
- cpu_single_env->eip,
+ fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
+ cpu_single_env->mem_write_vaddr, len,
+ cpu_single_env->eip,
cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
}
}
#endif
p = page_find(start >> TARGET_PAGE_BITS);
- if (!p)
+ if (!p)
return;
if (p->code_bitmap) {
offset = start & ~TARGET_PAGE_MASK;
}
#if !defined(CONFIG_SOFTMMU)
-static void tb_invalidate_phys_page(target_ulong addr,
+static void tb_invalidate_phys_page(target_ulong addr,
unsigned long pc, void *puc)
{
int n, current_flags, current_tb_modified;
addr &= TARGET_PAGE_MASK;
p = page_find(addr >> TARGET_PAGE_BITS);
- if (!p)
+ if (!p)
return;
tb = p->first_tb;
current_tb_modified = 0;
that the modification is after the current PC, but it
would require a specialized function to partially
restore the CPU state */
-
+
current_tb_modified = 1;
cpu_restore_state(current_tb, env, pc, puc);
#if defined(TARGET_I386)
modifying the memory. It will ensure that it cannot modify
itself */
env->current_tb = NULL;
- tb_gen_code(env, current_pc, current_cs_base, current_flags,
+ tb_gen_code(env, current_pc, current_cs_base, current_flags,
CF_SINGLE_INSN);
cpu_resume_from_signal(env, puc);
}
#endif
/* add the tb in the target page and protect it if necessary */
-static inline void tb_alloc_page(TranslationBlock *tb,
+static inline void tb_alloc_page(TranslationBlock *tb,
unsigned int n, target_ulong page_addr)
{
PageDesc *p;
p2->flags &= ~PAGE_WRITE;
page_get_flags(addr);
}
- mprotect(g2h(page_addr), qemu_host_page_size,
+ mprotect(g2h(page_addr), qemu_host_page_size,
(prot & PAGE_BITS) & ~PAGE_WRITE);
#ifdef DEBUG_TB_INVALIDATE
- printf("protecting code page: 0x%08lx\n",
+ printf("protecting code page: 0x%08lx\n",
page_addr);
#endif
}
{
TranslationBlock *tb;
- if (nb_tbs >= CODE_GEN_MAX_BLOCKS ||
+ if (nb_tbs >= CODE_GEN_MAX_BLOCKS ||
(code_gen_ptr - code_gen_buffer) >= CODE_GEN_BUFFER_MAX_SIZE)
return NULL;
tb = &tbs[nb_tbs++];
/* add a new TB and link it to the physical page tables. phys_page2 is
(-1) to indicate that only one page contains the TB. */
-void tb_link_phys(TranslationBlock *tb,
+void tb_link_phys(TranslationBlock *tb,
target_ulong phys_pc, target_ulong phys_page2)
{
unsigned int h;
} else {
m_min = m + 1;
}
- }
+ }
return &tbs[m_max];
}
}
*ptb = tb->jmp_next[n];
tb->jmp_next[n] = NULL;
-
+
/* suppress the jump to next tb in generated code */
tb_reset_jump(tb, n);
{
#if defined(TARGET_HAS_ICE)
int i;
-
+
for(i = 0; i < env->nb_breakpoints; i++) {
if (env->breakpoints[i] == pc)
return 0;
if (env->nb_breakpoints >= MAX_BREAKPOINTS)
return -1;
env->breakpoints[env->nb_breakpoints++] = pc;
-
+
breakpoint_invalidate(env, pc);
return 0;
#else
}
CPULogItem cpu_log_items[] = {
- { CPU_LOG_TB_OUT_ASM, "out_asm",
+ { CPU_LOG_TB_OUT_ASM, "out_asm",
"show generated host assembly code for each compiled TB" },
{ CPU_LOG_TB_IN_ASM, "in_asm",
"show target assembly code for each compiled TB" },
- { CPU_LOG_TB_OP, "op",
+ { CPU_LOG_TB_OP, "op",
"show micro ops for each compiled TB (only usable if 'in_asm' used)" },
#ifdef TARGET_I386
{ CPU_LOG_TB_OP_OPT, "op_opt",
return 0;
return memcmp(s1, s2, n) == 0;
}
-
+
/* takes a comma separated list of log masks. Return 0 if error. */
int cpu_str_to_log_mask(const char *str)
{
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
{
- if (addr == (tlb_entry->addr_read &
+ if (addr == (tlb_entry->addr_read &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
- addr == (tlb_entry->addr_write &
+ addr == (tlb_entry->addr_write &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
- addr == (tlb_entry->addr_code &
+ addr == (tlb_entry->addr_code &
(TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
tlb_entry->addr_read = -1;
tlb_entry->addr_write = -1;
can be detected */
static void tlb_protect_code(ram_addr_t ram_addr)
{
- cpu_physical_memory_reset_dirty(ram_addr,
+ cpu_physical_memory_reset_dirty(ram_addr,
ram_addr + TARGET_PAGE_SIZE,
CODE_DIRTY_FLAG);
}
/* update the TLB so that writes in physical page 'phys_addr' are no longer
tested for self modifying code */
-static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
+static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
target_ulong vaddr)
{
phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] |= CODE_DIRTY_FLAG;
}
-static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
+static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
unsigned long start, unsigned long length)
{
unsigned long addr;
p->phys_addr >= start && p->phys_addr < end &&
(p->prot & PROT_WRITE)) {
if (addr < MMAP_AREA_END) {
- mprotect((void *)addr, TARGET_PAGE_SIZE,
+ mprotect((void *)addr, TARGET_PAGE_SIZE,
p->prot & ~PROT_WRITE);
}
}
ram_addr_t ram_addr;
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
- ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
+ ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
tlb_entry->addend - (unsigned long)phys_ram_base;
if (!cpu_physical_memory_is_dirty(ram_addr)) {
tlb_entry->addr_write |= IO_MEM_NOTDIRTY;
tlb_update_dirty(&env->tlb_table[1][i]);
}
-static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
+static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
unsigned long start)
{
unsigned long addr;
is permitted. Return 0 if OK or 2 if the page could not be mapped
(can only happen in non SOFTMMU mode for I/O pages or pages
conflicting with the host address space). */
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
+int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
+ target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu)
{
PhysPageDesc *p;
ret = 0;
#if !defined(CONFIG_SOFTMMU)
- if (is_softmmu)
+ if (is_softmmu)
#endif
{
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
address = vaddr;
addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
}
-
+
index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
addend -= vaddr;
te = &env->tlb_table[is_user][index];
te->addr_code = -1;
}
if (prot & PAGE_WRITE) {
- if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
+ if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
(pd & IO_MEM_ROMD)) {
/* write access calls the I/O callback */
- te->addr_write = vaddr |
+ te->addr_write = vaddr |
(pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
- } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
+ } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
!cpu_physical_memory_is_dirty(pd)) {
te->addr_write = vaddr | IO_MEM_NOTDIRTY;
} else {
ret = 2;
} else {
if (prot & PROT_WRITE) {
- if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
+ if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
#if defined(TARGET_HAS_SMC) || 1
first_tb ||
#endif
- ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
+ ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
!cpu_physical_memory_is_dirty(pd))) {
/* ROM: we do as if code was inside */
/* if code is present, we only map as read only and save the
original mapping */
VirtPageDesc *vp;
-
+
vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1);
vp->phys_addr = pd;
vp->prot = prot;
prot &= ~PAGE_WRITE;
}
}
- map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot,
+ map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot,
MAP_SHARED | MAP_FIXED, phys_ram_fd, (pd & TARGET_PAGE_MASK));
if (map_addr == MAP_FAILED) {
cpu_abort(env, "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
if (!(vp->prot & PAGE_WRITE))
return 0;
#if defined(DEBUG_TLB)
- printf("page_unprotect: addr=0x%08x phys_addr=0x%08x prot=%x\n",
+ printf("page_unprotect: addr=0x%08x phys_addr=0x%08x prot=%x\n",
addr, vp->phys_addr, vp->prot);
#endif
if (mprotect((void *)addr, TARGET_PAGE_SIZE, vp->prot) < 0)
{
}
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
+int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
+ target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu)
{
return 0;
end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
if (start != -1) {
fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
- start, end, end - start,
+ start, end, end - start,
prot & PAGE_READ ? 'r' : '-',
prot & PAGE_WRITE ? 'w' : '-',
prot & PAGE_EXEC ? 'x' : '-');
p = page_find_alloc(addr >> TARGET_PAGE_BITS);
/* if the write protection is set, then we invalidate the code
inside */
- if (!(p->flags & PAGE_WRITE) &&
+ if (!(p->flags & PAGE_WRITE) &&
(flags & PAGE_WRITE) &&
p->first_tb) {
tb_invalidate_phys_page(addr, 0, NULL);
if (prot & PAGE_WRITE_ORG) {
pindex = (address - host_start) >> TARGET_PAGE_BITS;
if (!(p1[pindex].flags & PAGE_WRITE)) {
- mprotect((void *)g2h(host_start), qemu_host_page_size,
+ mprotect((void *)g2h(host_start), qemu_host_page_size,
(prot & PAGE_BITS) | PAGE_WRITE);
p1[pindex].flags |= PAGE_WRITE;
/* and since the content will be modified, we must invalidate
/* register physical memory. 'size' must be a multiple of the target
page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
+void cpu_register_physical_memory(target_phys_addr_t start_addr,
unsigned long size,
unsigned long phys_offset)
{
(phys_offset & IO_MEM_ROMD))
phys_offset += TARGET_PAGE_SIZE;
}
-
+
/* since each CPU stores ram addresses in its TLB cache, we must
reset the modified entries */
/* XXX: slow ! */
/* physical memory access (slow version, mainly for debug) */
#if defined(CONFIG_USER_ONLY)
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write)
{
int l, flags;
}
#else
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write)
{
int l, io_index;
target_phys_addr_t page;
unsigned long pd;
PhysPageDesc *p;
-
+
while (len > 0) {
page = addr & TARGET_PAGE_MASK;
l = (page + TARGET_PAGE_SIZE) - addr;
} else {
pd = p->phys_offset;
}
-
+
if (is_write) {
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
/* set dirty bit */
- phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
+ phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
(0xff & ~CODE_DIRTY_FLAG);
}
}
} else {
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
+ if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
!(pd & IO_MEM_ROMD)) {
/* I/O case */
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
}
} else {
/* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+ ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
memcpy(buf, ptr, l);
}
}
/* used for ROM loading : can write in RAM and ROM */
-void cpu_physical_memory_write_rom(target_phys_addr_t addr,
+void cpu_physical_memory_write_rom(target_phys_addr_t addr,
const uint8_t *buf, int len)
{
int l;
target_phys_addr_t page;
unsigned long pd;
PhysPageDesc *p;
-
+
while (len > 0) {
page = addr & TARGET_PAGE_MASK;
l = (page + TARGET_PAGE_SIZE) - addr;
} else {
pd = p->phys_offset;
}
-
+
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
(pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM &&
!(pd & IO_MEM_ROMD)) {
} else {
pd = p->phys_offset;
}
-
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
+
+ if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
!(pd & IO_MEM_ROMD)) {
/* I/O case */
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
} else {
/* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+ ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
val = ldl_p(ptr);
}
} else {
pd = p->phys_offset;
}
-
+
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
!(pd & IO_MEM_ROMD)) {
/* I/O case */
#endif
} else {
/* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+ ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
val = ldq_p(ptr);
}
} else {
pd = p->phys_offset;
}
-
+
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
} else {
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
+ ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
stl_p(ptr, val);
}
} else {
pd = p->phys_offset;
}
-
+
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
#endif
/* virtual memory access for debug */
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
uint8_t *buf, int len, int is_write)
{
int l;
l = (page + TARGET_PAGE_SIZE) - addr;
if (l > len)
l = len;
- cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
+ cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
buf, l, is_write);
len -= l;
buf += l;
int i, target_code_size, max_target_code_size;
int direct_jmp_count, direct_jmp2_count, cross_page;
TranslationBlock *tb;
-
+
target_code_size = 0;
max_target_code_size = 0;
cross_page = 0;
}
/* XXX: avoid using doubles ? */
cpu_fprintf(f, "TB count %d\n", nb_tbs);
- cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
+ cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
nb_tbs ? target_code_size / nb_tbs : 0,
max_target_code_size);
- cpu_fprintf(f, "TB avg host size %d bytes (expansion ratio: %0.1f)\n",
+ cpu_fprintf(f, "TB avg host size %d bytes (expansion ratio: %0.1f)\n",
nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
- cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
- cross_page,
+ cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
+ cross_page,
nb_tbs ? (cross_page * 100) / nb_tbs : 0);
cpu_fprintf(f, "direct jump count %d (%d%%) (2 jumps=%d %d%%)\n",
- direct_jmp_count,
+ direct_jmp_count,
nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0,
direct_jmp2_count,
nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0);
cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count);
}
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
#define MMUSUFFIX _cmmu
#define GETPC() NULL
double y = 4503599627370496.0;
if (fabs(x) >= y)
return x;
- if (x < 0)
+ if (x < 0)
y = -y;
y = (x + y) - y;
if (y == 0.0)
#else
static inline int long_to_int32(long a)
{
- if (a != (int32_t)a)
+ if (a != (int32_t)a)
a = 0x80000000;
return a;
}
/*
* gdb server stub
- *
+ *
* Copyright (c) 2003-2005 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
registers[41] = 0; /* foseg */
registers[42] = 0; /* fooff */
registers[43] = 0; /* fop */
-
+
for(i = 0; i < 16; i++)
tswapls(®isters[i]);
for(i = 36; i < 44; i++)
/* F0-F7. The 68881/68040 have 12-bit extended precision registers.
ColdFire has 8-bit double precision registers. */
for (i = 0; i < 8; i++) {
- u.l.upper = tswap32(*(uint32_t *)ptr);
+ u.l.upper = tswap32(*(uint32_t *)ptr);
u.l.lower = tswap32(*(uint32_t *)ptr);
env->fregs[i] = u.d;
}
uint8_t mem_buf[2000];
uint32_t *registers;
target_ulong addr, len;
-
+
#ifdef DEBUG_GDB
printf("command='%s'\n", line_buf);
#endif
/* when the CPU is running, we cannot do anything except stop
it when receiving a char */
vm_stop(EXCP_INTERRUPT);
- } else
+ } else
#endif
{
switch(s->state) {
/* set short latency */
val = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
-
+
s = &gdbserver_state;
memset (s, 0, sizeof (GDBState));
s->env = first_cpu; /* XXX: allow to change CPU */
snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
"tcp::%d,nowait,nodelay,server", port);
chr = qemu_chr_open(gdbstub_port_name);
- if (!chr)
+ if (!chr)
return -EIO;
return gdbserver_start(chr);
}
/*
* ACPI implementation
- *
+ *
* Copyright (c) 2006 Fabrice Bellard
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2 as published by the Free Software Foundation.
{
int sci_level, pmsts;
int64_t expire_time;
-
+
pmsts = get_pmsts(s);
- sci_level = (((pmsts & s->pmen) &
+ sci_level = (((pmsts & s->pmen) &
(RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
pci_set_irq(&s->dev, 0, sci_level);
/* schedule a timer interruption if needed */
{
PIIX4PMState *s = opaque;
uint32_t val;
-
+
addr &= 1;
if (addr == 0) {
val = s->apmc;
}
}
-static void pm_write_config(PCIDevice *d,
+static void pm_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len)
{
pci_default_write_config(d, address, val, len);
pci_conf[0x0b] = 0x06; // bridge device
pci_conf[0x0e] = 0x00; // header_type
pci_conf[0x3d] = 0x01; // interrupt pin 1
-
+
pci_conf[0x40] = 0x01; /* PM io base read only bit */
-
+
register_ioport_write(0xb2, 2, 1, pm_smi_writeb, s);
register_ioport_read(0xb2, 2, 1, pm_smi_readb, s);
/*
* QEMU ADB support
- *
+ *
* 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
return olen;
}
-ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
- ADBDeviceRequest *devreq,
- ADBDeviceReset *devreset,
+ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
+ ADBDeviceRequest *devreq,
+ ADBDeviceReset *devreset,
void *opaque)
{
ADBDevice *d;
if (s->last_buttons_state == s->buttons_state &&
s->dx == 0 && s->dy == 0)
return 0;
-
+
dx = s->dx;
if (dx < -63)
dx = -63;
else if (dx > 63)
dx = 63;
-
+
dy = s->dy;
if (dy < -63)
dy = -63;
else if (dy > 63)
dy = 63;
-
+
s->dx -= dx;
s->dy -= dy;
s->last_buttons_state = s->buttons_state;
-
+
dx &= 0x7f;
dy &= 0x7f;
-
+
if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
dy |= 0x80;
if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
dx |= 0x80;
-
+
obuf[0] = dy;
obuf[1] = dx;
return 2;
{
MouseState *s = d->opaque;
int cmd, reg, olen;
-
+
if ((buf[0] & 0x0f) == ADB_FLUSH) {
/* flush mouse fifo */
s->buttons_state = s->last_buttons_state;
* QEMU Ultrasparc APB PCI host
*
* 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
cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
- d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
+ d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
0, NULL, NULL);
d->config[0x00] = 0x8e; // vendor_id : Sun
d->config[0x01] = 0x10;
/*
* APIC support
- *
+ *
* Copyright (c) 2004-2005 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
}\
}
-static void apic_bus_deliver(const uint32_t *deliver_bitmask,
+static void apic_bus_deliver(const uint32_t *deliver_bitmask,
uint8_t delivery_mode,
uint8_t vector_num, uint8_t polarity,
uint8_t trigger_mode)
case APIC_DM_INIT:
/* normal INIT IPI sent to processors */
- foreach_apic(apic_iter, deliver_bitmask,
+ foreach_apic(apic_iter, deliver_bitmask,
apic_init_ipi(apic_iter) );
return;
-
+
case APIC_DM_EXTINT:
/* handled in I/O APIC code */
break;
return;
}
- foreach_apic(apic_iter, deliver_bitmask,
+ foreach_apic(apic_iter, deliver_bitmask,
apic_set_irq(apic_iter, vector_num, trigger_mode) );
}
#ifdef DEBUG_APIC
printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
#endif
- s->apicbase = (val & 0xfffff000) |
+ s->apicbase = (val & 0xfffff000) |
(s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
/* if disabled, cannot be enabled again */
if (!(val & MSR_IA32_APICBASE_ENABLE)) {
if (!(env->hflags & HF_HALTED_MASK))
return;
env->eip = 0;
- cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
+ cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
0xffff, 0);
env->hflags &= ~HF_HALTED_MASK;
}
int trig_mode = (s->icr[0] >> 15) & 1;
int level = (s->icr[0] >> 14) & 1;
if (level == 0 && trig_mode == 1) {
- foreach_apic(apic_iter, deliver_bitmask,
+ foreach_apic(apic_iter, deliver_bitmask,
apic_iter->arb_id = apic_iter->id );
return;
}
break;
case APIC_DM_SIPI:
- foreach_apic(apic_iter, deliver_bitmask,
+ foreach_apic(apic_iter, deliver_bitmask,
apic_startup(apic_iter, vector_num) );
return;
}
return -1;
if (!(s->spurious_vec & APIC_SV_ENABLE))
return -1;
-
+
/* XXX: spurious IRQ handling */
intno = get_highest_priority_int(s->irr);
if (intno < 0)
{
int64_t d;
uint32_t val;
- d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
+ d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
s->count_shift;
if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
/* periodic */
static void apic_timer_update(APICState *s, int64_t current_time)
{
int64_t next_time, d;
-
+
if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
- d = (current_time - s->initial_count_load_time) >>
+ d = (current_time - s->initial_count_load_time) >>
s->count_shift;
if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
apic_init_ipi(s);
s->id = last_apic_id++;
s->cpu_env = env;
- s->apicbase = 0xfee00000 |
+ s->apicbase = 0xfee00000 |
(s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
/* XXX: mapping more APICs at the same memory location */
if (apic_io_memory == 0) {
/* NOTE: the APIC is directly connected to the CPU - it is not
on the global memory bus. */
- apic_io_memory = cpu_register_io_memory(0, apic_mem_read,
+ apic_io_memory = cpu_register_io_memory(0, apic_mem_read,
apic_mem_write, NULL);
cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
apic_io_memory);
register_savevm("apic", 0, 2, apic_save, apic_load, s);
qemu_register_reset(apic_reset, s);
-
+
local_apics[s->id] = s;
return 0;
}
vector = pic_read_irq(isa_pic);
else
vector = entry & 0xff;
-
+
apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
- apic_bus_deliver(deliver_bitmask, delivery_mode,
+ apic_bus_deliver(deliver_bitmask, delivery_mode,
vector, polarity, trig_mode);
}
}
ioapic_reset(s);
s->id = last_apic_id++;
- io_memory = cpu_register_io_memory(0, ioapic_mem_read,
+ io_memory = cpu_register_io_memory(0, ioapic_mem_read,
ioapic_mem_write, s);
cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
qemu_register_reset(ioapic_reset, s);
-
+
return s;
}
-/*
+/*
* ARM kernel loader.
*
* Copyright (c) 2006 CodeSourcery.
-/*
+/*
* ARM AMBA Generic/Distributed Interrupt Controller
*
* Copyright (c) 2006 CodeSourcery.
gic_state *s = (gic_state *)opaque;
/* The first external input line is internal interrupt 32. */
irq += 32;
- if (level == GIC_TEST_LEVEL(irq))
+ if (level == GIC_TEST_LEVEL(irq))
return;
if (level) {
-/*
+/*
* Generic ARM Programmable Interrupt Controller support.
*
* Copyright (c) 2006 CodeSourcery.
void *arm_pic_init_cpu(CPUState *env)
{
arm_pic_cpu_state *s;
-
+
s = (arm_pic_cpu_state *)malloc(sizeof(arm_pic_cpu_state));
s->handler = arm_pic_cpu_handler;
s->cpu_env = env;
-/*
+/*
* Generic ARM Programmable Interrupt Controller support.
*
* Copyright (c) 2006 CodeSourcery.
-/*
+/*
* Status and system control registers for ARM RealView/Versatile boards.
*
* Copyright (c) 2006 CodeSourcery.
-/*
+/*
* ARM PrimeCell Timer modules.
*
* Copyright (c) 2005-2006 CodeSourcery.
/*
* 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
{
uint8_t *q;
int len;
-
+
if (start_track > 1 && start_track != 0xaa)
return -1;
q = buf + 2;
{
uint8_t *q;
int len;
-
+
q = buf + 2;
*q++ = 1; /* first session */
*q++ = 1; /* last session */
*q++ = 1; /* first track */
*q++ = 0x00; /* disk type */
*q++ = 0x00;
-
+
*q++ = 1; /* session number */
*q++ = 0x14; /* data track */
*q++ = 0; /* track number */
*q++ = 1; /* last track */
*q++ = 0x00;
*q++ = 0x00;
-
+
*q++ = 1; /* session number */
*q++ = 0x14; /* data track */
*q++ = 0; /* track number */
*q++ = 0; /* sec */
*q++ = 0; /* frame */
if (msf) {
- *q++ = 0;
+ *q++ = 0;
lba_to_msf(q, 0);
q += 3;
} else {
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
+ *q++ = 0;
+ *q++ = 0;
+ *q++ = 0;
+ *q++ = 0;
}
len = q - buf;
/*
* QEMU Cirrus CLGD 54xx VGA Emulator.
- *
+ *
* Copyright (c) 2004 Fabrice Bellard
* Copyright (c) 2004 Makoto Suzuki (suzu)
- *
+ *
* 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
} PCICirrusVGAState;
static uint8_t rop_to_index[256];
-
+
void *shared_vram;
/***************************************
s->cirrus_blt_fgcol = le16_to_cpu(color);
break;
case 3:
- s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
+ s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
(s->gr[0x11] << 8) | (s->gr[0x13] << 16);
break;
default:
s->cirrus_blt_bgcol = le16_to_cpu(color);
break;
case 3:
- s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
+ s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
(s->gr[0x10] << 8) | (s->gr[0x12] << 16);
break;
default:
dst = s->vram_ptr + s->cirrus_blt_dstaddr;
(*s->cirrus_rop) (s, dst, src,
- s->cirrus_blt_dstpitch, 0,
+ s->cirrus_blt_dstpitch, 0,
s->cirrus_blt_width, s->cirrus_blt_height);
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
s->cirrus_blt_dstpitch, s->cirrus_blt_width,
cirrus_fill_t rop_func;
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr,
+ rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr,
s->cirrus_blt_dstpitch,
s->cirrus_blt_width, s->cirrus_blt_height);
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
{
return cirrus_bitblt_common_patterncopy(s,
- s->vram_ptr +
+ s->vram_ptr +
(s->cirrus_blt_srcaddr & ~7));
}
{
int copy_count;
uint8_t *end_ptr;
-
+
if (s->cirrus_srccounter > 0) {
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
} else {
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
+ if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
s->cirrus_blt_srcpitch = ((w + 31) >> 5);
else
s->cirrus_blt_srcpitch = ((w + 7) >> 3);
#ifdef DEBUG_BITBLT
printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
- blt_rop,
+ blt_rop,
s->cirrus_blt_mode,
s->cirrus_blt_modeext,
s->cirrus_blt_width,
}
if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
- (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
+ (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
CIRRUS_BLTMODE_TRANSPARENTCOMP |
- CIRRUS_BLTMODE_PATTERNCOPY |
- CIRRUS_BLTMODE_COLOREXPAND)) ==
+ CIRRUS_BLTMODE_PATTERNCOPY |
+ CIRRUS_BLTMODE_COLOREXPAND)) ==
(CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
cirrus_bitblt_fgcol(s);
cirrus_bitblt_solidfill(s, blt_rop);
} else {
- if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
- CIRRUS_BLTMODE_PATTERNCOPY)) ==
+ if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
+ CIRRUS_BLTMODE_PATTERNCOPY)) ==
CIRRUS_BLTMODE_COLOREXPAND) {
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
*
***************************************/
-static void cirrus_get_offsets(VGAState *s1,
+static void cirrus_get_offsets(VGAState *s1,
uint32_t *pline_offset,
uint32_t *pstart_addr,
uint32_t *pline_compare)
| ((s->cr[0x1d] & 0x80) << 12);
*pstart_addr = start_addr;
- line_compare = s->cr[0x18] |
+ line_compare = s->cr[0x18] |
((s->cr[0x07] & 0x10) << 4) |
((s->cr[0x09] & 0x40) << 3);
*pline_compare = line_compare;
static void cirrus_get_resolution(VGAState *s, int *pwidth, int *pheight)
{
int width, height;
-
+
width = (s->cr[0x01] + 1) * 8;
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
+ height = s->cr[0x12] |
+ ((s->cr[0x07] & 0x02) << 7) |
((s->cr[0x07] & 0x40) << 3);
height = (height + 1);
/* interlace support */
return v;
}
-static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
+static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
uint32_t mem_value)
{
CirrusVGAState *s = opaque;
static inline void invalidate_cursor1(CirrusVGAState *s)
{
if (s->last_hw_cursor_size) {
- vga_invalidate_scanlines((VGAState *)s,
+ vga_invalidate_scanlines((VGAState *)s,
s->last_hw_cursor_y + s->last_hw_cursor_y_start,
s->last_hw_cursor_y + s->last_hw_cursor_y_end);
}
s->last_hw_cursor_y != s->hw_cursor_y) {
invalidate_cursor1(s);
-
+
s->last_hw_cursor_size = size;
s->last_hw_cursor_x = s->hw_cursor_x;
s->last_hw_cursor_y = s->hw_cursor_y;
unsigned int color0, color1;
const uint8_t *palette, *src;
uint32_t content;
-
- if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW))
+
+ if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW))
return;
/* fast test to see if the cursor intersects with the scan line */
if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
if (scr_y < s->hw_cursor_y ||
scr_y >= (s->hw_cursor_y + h))
return;
-
+
src = s->vram_ptr + s->real_vram_size - 16 * 1024;
if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
src += (s->sr[0x13] & 0x3c) * 256;
x2 = s->last_scr_width;
w = x2 - x1;
palette = s->cirrus_hidden_palette;
- color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
- c6_to_8(palette[0x0 * 3 + 1]),
+ color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
+ c6_to_8(palette[0x0 * 3 + 1]),
c6_to_8(palette[0x0 * 3 + 2]));
- color1 = s->rgb_to_pixel(c6_to_8(palette[0xf * 3]),
- c6_to_8(palette[0xf * 3 + 1]),
+ color1 = s->rgb_to_pixel(c6_to_8(palette[0xf * 3]),
+ c6_to_8(palette[0xf * 3 + 1]),
c6_to_8(palette[0xf * 3 + 2]));
bpp = ((s->ds->depth + 7) >> 3);
d1 += x1 * bpp;
addr &= s->cirrus_addr_mask;
- if (((s->sr[0x17] & 0x44) == 0x44) &&
+ if (((s->sr[0x17] & 0x44) == 0x44) &&
((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
/* memory-mapped I/O */
ret = cirrus_mmio_blt_read(s, addr & 0xff);
unsigned mode;
addr &= s->cirrus_addr_mask;
-
- if (((s->sr[0x17] & 0x44) == 0x44) &&
+
+ if (((s->sr[0x17] & 0x44) == 0x44) &&
((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
/* memory-mapped I/O */
cirrus_mmio_blt_write(s, addr & 0xff, val);
return vram_pointer;
}
-static int unset_vram_mapping(unsigned long begin, unsigned long end,
+static int unset_vram_mapping(unsigned long begin, unsigned long end,
void *mapping)
{
xen_pfn_t *extent_start = NULL;
} else if (s->gr[0x0B] & 0x02) {
goto generic_io;
}
-
+
mode = s->gr[0x05] & 0x7;
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
if (s->lfb_addr && s->lfb_end && !s->map_addr) {
old_vram = vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
unset_vram_mapping(s->lfb_addr,
- s->lfb_end,
+ s->lfb_end,
old_vram);
s->map_addr = s->map_end = 0;
qemu_put_8s(f, &vga_acc);
qemu_put_be64s(f, (uint64_t*)&s->lfb_addr);
qemu_put_be64s(f, (uint64_t*)&s->lfb_end);
- qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
+ qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
}
static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_8s(f, &vga_acc);
qemu_get_be64s(f, (uint64_t*)&s->lfb_addr);
qemu_get_be64s(f, (uint64_t*)&s->lfb_end);
- qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
+ qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
if (vga_acc){
cirrus_restart_acc(s);
}
register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
- vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
+ vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
cirrus_vga_mem_write, s);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
+ cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
vga_io_memory);
s->sr[0x06] = 0x0f;
} else {
s->sr[0x1F] = 0x22; // MemClock
s->sr[0x0F] = CIRRUS_MEMSIZE_2M;
- if (is_pci)
+ if (is_pci)
s->sr[0x17] = CIRRUS_BUSTYPE_PCI;
else
s->sr[0x17] = CIRRUS_BUSTYPE_ISA;
*
***************************************/
-void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
+void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size)
{
CirrusVGAState *s;
s = qemu_mallocz(sizeof(CirrusVGAState));
-
- vga_common_init((VGAState *)s,
+
+ vga_common_init((VGAState *)s,
ds, vga_ram_base, vga_ram_offset, vga_ram_size);
cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
/* XXX ISA-LFB support */
s->cirrus_mmio_io_addr);
}
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
+void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size)
{
PCICirrusVGAState *d;
uint8_t *pci_conf;
CirrusVGAState *s;
int device_id;
-
+
device_id = CIRRUS_ID_CLGD5446;
/* setup PCI configuration registers */
- d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA",
- sizeof(PCICirrusVGAState),
+ d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA",
+ sizeof(PCICirrusVGAState),
-1, NULL, NULL);
pci_conf = d->dev.config;
pci_conf[0x00] = (uint8_t) (PCI_VENDOR_CIRRUS & 0xff);
/* setup VGA */
s = &d->cirrus_vga;
- vga_common_init((VGAState *)s,
+ vga_common_init((VGAState *)s,
ds, vga_ram_base, vga_ram_offset, vga_ram_size);
cirrus_init_common(s, device_id, 1);
s->pci_dev = (PCIDevice *)d;
/*
* QEMU Cirrus CLGD 54xx VGA Emulator.
- *
+ *
* 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
/*
* QEMU Cirrus CLGD 54xx VGA Emulator.
- *
+ *
* 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
#define PUTPIXEL() ROP_OP(((uint32_t *)(dst_base + m(d)))[0], col)
#else
#error unsupported DEPTH
-#endif
+#endif
static void
glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
+ const uint8_t * src_,
+ int dstpitch, int srcpitch,
int bltwidth, int bltheight)
{
uint8_t *dst_base, *src_base;
static void
glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
+ const uint8_t * src_,
+ int dstpitch, int srcpitch,
int bltwidth, int bltheight)
{
uint8_t *dst_base, *src_base;
static void
glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
+ const uint8_t * src_,
+ int dstpitch, int srcpitch,
int bltwidth, int bltheight)
{
uint8_t *dst_base, *src_base;
static void
glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
+ const uint8_t * src_,
+ int dstpitch, int srcpitch,
int bltwidth, int bltheight)
{
uint8_t *dst_base, *src_base;
static void
glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst_,
- const uint8_t * src_,
- int dstpitch, int srcpitch,
+ const uint8_t * src_,
+ int dstpitch, int srcpitch,
int bltwidth, int bltheight)
{
uint8_t *dst_base, *src_base;
}
}
-static void
+static void
glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
(CirrusVGAState *s,
- uint8_t *dst_, int dst_pitch,
+ uint8_t *dst_, int dst_pitch,
int width, int height)
{
uint8_t *dst_base;
/*
* QEMU CUDA support
- *
+ *
* 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
#define RTC_OFFSET 2082844800
typedef struct CUDATimer {
- int index;
+ int index;
uint16_t latch;
uint16_t counter_value; /* counter value at load time */
int64_t load_time;
uint8_t anh; /* A-side data, no handshake */
CUDATimer timers[2];
-
+
uint8_t last_b; /* last value of B register */
uint8_t last_acr; /* last value of B register */
-
+
int data_in_size;
int data_in_index;
int data_out_index;
ADBBusState adb_bus;
static void cuda_update(CUDAState *s);
-static void cuda_receive_packet_from_host(CUDAState *s,
+static void cuda_receive_packet_from_host(CUDAState *s,
const uint8_t *data, int len);
-static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
+static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
int64_t current_time);
static void cuda_update_irq(CUDAState *s)
int64_t d;
unsigned int counter;
- d = muldiv64(qemu_get_clock(vm_clock) - s->load_time,
+ d = muldiv64(qemu_get_clock(vm_clock) - s->load_time,
CUDA_TIMER_FREQ, ticks_per_sec);
if (s->index == 0) {
/* the timer goes down from latch to -1 (period of latch + 2) */
counter = (s->counter_value - d) & 0xffff;
} else {
counter = (d - (s->counter_value + 1)) % (s->latch + 2);
- counter = (s->latch - counter) & 0xffff;
+ counter = (s->latch - counter) & 0xffff;
}
} else {
counter = (s->counter_value - d) & 0xffff;
unsigned int counter;
/* current counter value */
- d = muldiv64(current_time - s->load_time,
+ d = muldiv64(current_time - s->load_time,
CUDA_TIMER_FREQ, ticks_per_sec);
/* the timer goes down from latch to -1 (period of latch + 2) */
if (d <= (s->counter_value + 1)) {
counter = (s->counter_value - d) & 0xffff;
} else {
counter = (d - (s->counter_value + 1)) % (s->latch + 2);
- counter = (s->latch - counter) & 0xffff;
+ counter = (s->latch - counter) & 0xffff;
}
-
+
/* Note: we consider the irq is raised on 0 */
if (counter == 0xffff) {
next_time = d + s->latch + 1;
}
#if 0
#ifdef DEBUG_CUDA
- printf("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n",
+ printf("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n",
s->latch, d, next_time - d);
#endif
#endif
- next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) +
+ next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) +
s->load_time;
if (next_time <= current_time)
next_time = current_time + 1;
return next_time;
}
-static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
+static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
int64_t current_time)
{
if (!ti->timer)
break;
case 13:
val = s->ifr;
- if (s->ifr & s->ier)
+ if (s->ifr & s->ier)
val |= 0x80;
break;
case 14:
static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
CUDAState *s = opaque;
-
+
addr = (addr >> 9) & 0xf;
#ifdef DEBUG_CUDA
printf("cuda: write: reg=0x%x val=%02x\n", addr, val);
}
}
-static void cuda_send_packet_to_host(CUDAState *s,
+static void cuda_send_packet_to_host(CUDAState *s,
const uint8_t *data, int len)
{
#ifdef DEBUG_CUDA_PACKET
obuf[1] = 0x40; /* polled data */
cuda_send_packet_to_host(s, obuf, olen + 2);
}
- qemu_mod_timer(s->adb_poll_timer,
- qemu_get_clock(vm_clock) +
+ qemu_mod_timer(s->adb_poll_timer,
+ qemu_get_clock(vm_clock) +
(ticks_per_sec / CUDA_ADB_POLL_FREQ));
}
-static void cuda_receive_packet(CUDAState *s,
+static void cuda_receive_packet(CUDAState *s,
const uint8_t *data, int len)
{
uint8_t obuf[16];
if (autopoll != s->autopoll) {
s->autopoll = autopoll;
if (autopoll) {
- qemu_mod_timer(s->adb_poll_timer,
- qemu_get_clock(vm_clock) +
+ qemu_mod_timer(s->adb_poll_timer,
+ qemu_get_clock(vm_clock) +
(ticks_per_sec / CUDA_ADB_POLL_FREQ));
} else {
qemu_del_timer(s->adb_poll_timer);
}
}
-static void cuda_receive_packet_from_host(CUDAState *s,
+static void cuda_receive_packet_from_host(CUDAState *s,
const uint8_t *data, int len)
{
#ifdef DEBUG_CUDA_PACKET
/*
* QEMU ESP/NCR53C9x emulation
- *
+ *
* Copyright (c) 2005-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
static int esp_load(QEMUFile *f, void *opaque, int version_id)
{
ESPState *s = opaque;
-
+
if (version_id != 2)
return -EINVAL; // Cannot emulate 1
/*
* QEMU Floppy disk emulator (Intel 82078)
- *
+ *
* Copyright (c) 2003 Jocelyn Mayer
- *
+ *
* 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
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 0, "180 kB 5\"1/4", },
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1, "410 kB 5\"1/4", },
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1, "420 kB 5\"1/4", },
- /* 320 kB 5"1/4 floppy disks */
+ /* 320 kB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 1, "320 kB 5\"1/4", },
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 0, "160 kB 5\"1/4", },
/* 360 kB must match 5"1/4 better than 3"1/2... */
return fdctrl_read(opaque, reg);
}
-static void fdctrl_write_mem (void *opaque,
+static void fdctrl_write_mem (void *opaque,
target_phys_addr_t reg, uint32_t value)
{
fdctrl_write(opaque, reg, value);
fdctrl_write_mem,
};
-fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
+fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
uint32_t io_base,
BlockDriverState **fds)
{
fdctrl = qemu_mallocz(sizeof(fdctrl_t));
if (!fdctrl)
return NULL;
- fdctrl->result_timer = qemu_new_timer(vm_clock,
+ fdctrl->result_timer = qemu_new_timer(vm_clock,
fdctrl_result_timer, fdctrl);
fdctrl->version = 0x90; /* Intel 82078 controller */
static int fdctrl_media_changed(fdrive_t *drv)
{
int ret;
- if (!drv->bs)
+ if (!drv->bs)
return 0;
ret = bdrv_media_changed(drv->bs);
if (ret) {
cur_drv->sect = 1;
if (FD_MULTI_TRACK(fdctrl->data_state)) {
if (cur_drv->head == 0 &&
- (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
+ (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
cur_drv->head = 1;
} else {
cur_drv->head = 0;
FLOPPY_DPRINTF("treat READ_ID command\n");
/* XXX: should set main status register to busy */
cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
- qemu_mod_timer(fdctrl->result_timer,
+ qemu_mod_timer(fdctrl->result_timer,
qemu_get_clock(vm_clock) + (ticks_per_sec / 50));
break;
case 0x4C:
* QEMU Grackle (heathrow PPC) PCI host
*
* 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
s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq,
pic, 0, 0);
- pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
+ pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
pci_grackle_config_write, s);
pci_mem_data = cpu_register_io_memory(0, pci_grackle_read,
pci_grackle_write, s);
cpu_register_physical_memory(base, 0x1000, pci_mem_config);
cpu_register_physical_memory(base + 0x00200000, 0x1000, pci_mem_data);
- d = pci_register_device(s->bus, "Grackle host bridge", sizeof(PCIDevice),
+ d = pci_register_device(s->bus, "Grackle host bridge", sizeof(PCIDevice),
0, NULL, NULL);
d->config[0x00] = 0x57; // vendor_id
d->config[0x01] = 0x10;
d->config[0x1a] = 0x00; // subordinate_bus
d->config[0x1c] = 0x00;
d->config[0x1d] = 0x00;
-
+
d->config[0x20] = 0x00; // memory_base
d->config[0x21] = 0x00;
d->config[0x22] = 0x01; // memory_limit
d->config[0x23] = 0x00;
-
+
d->config[0x24] = 0x00; // prefetchable_memory_base
d->config[0x25] = 0x00;
d->config[0x26] = 0x00; // prefetchable_memory_limit
d->config[0x1a] = 0x1; // subordinate_bus
d->config[0x1c] = 0x10; // io_base
d->config[0x1d] = 0x20; // io_limit
-
+
d->config[0x20] = 0x80; // memory_base
d->config[0x21] = 0x80;
d->config[0x22] = 0x90; // memory_limit
d->config[0x23] = 0x80;
-
+
d->config[0x24] = 0x00; // prefetchable_memory_base
d->config[0x25] = 0x84;
d->config[0x26] = 0x00; // prefetchable_memory_limit
* QEMU GT64120 PCI host
*
* Copyright (c) 2006,2007 Aurelien Jarno
- *
+ *
* 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
static void gt64120_pci_mapping(GT64120State *s)
{
- target_phys_addr_t start, length;
+ target_phys_addr_t start, length;
/* Update IO mapping */
if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD])
case GT_CPUERR_DATAHI:
case GT_CPUERR_PARITY:
/* Emulated memory has no error, always return the initial
- values */
+ values */
val = s->regs[saddr];
break;
/* Reading those register should empty all FIFO on the PCI
bus, which are not emulated. The return value should be
a random value that should be ignored. */
- val = 0xc000ffee;
+ val = 0xc000ffee;
break;
/* ECC */
case GT_ECC_CALC:
case GT_ECC_ERRADDR:
/* Emulated memory has no error, always return the initial
- values */
+ values */
val = s->regs[saddr];
break;
val = s->regs[saddr];
break;
case GT_PCI0_IACK:
- /* Read the IRQ number */
+ /* Read the IRQ number */
val = pic_read_irq(isa_pic);
break;
s->regs[GT_ECC_ERRADDR] = 0x00000000;
/* SDRAM Parameters */
- s->regs[GT_SDRAM_B0] = 0x00000005;
- s->regs[GT_SDRAM_B1] = 0x00000005;
- s->regs[GT_SDRAM_B2] = 0x00000005;
- s->regs[GT_SDRAM_B3] = 0x00000005;
+ s->regs[GT_SDRAM_B0] = 0x00000005;
+ s->regs[GT_SDRAM_B1] = 0x00000005;
+ s->regs[GT_SDRAM_B2] = 0x00000005;
+ s->regs[GT_SDRAM_B3] = 0x00000005;
/* PCI Internal FIXME: not complete*/
#ifdef TARGET_WORDS_BIGENDIAN
/*
* Heathrow PIC support (standard PowerMac PIC)
- *
+ *
* 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
HeathrowPIC *pic;
unsigned int n;
uint32_t value;
-
+
n = ((addr & 0xfff) - 0x10) >> 4;
if (n >= 2) {
value = 0;
HeathrowPICS *heathrow_pic_init(int *pmem_index)
{
HeathrowPICS *s;
-
+
s = qemu_mallocz(sizeof(HeathrowPICS));
s->pics[0].level_triggered = 0;
s->pics[1].level_triggered = 0x1ff00000;
/*
* QEMU 8253/8254 interval timer emulation
- *
+ *
* Copyright (c) 2003-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
}
/* return -1 if no transition will occur. */
-static int64_t pit_get_next_transition_time(PITChannelState *s,
+static int64_t pit_get_next_transition_time(PITChannelState *s,
int64_t current_time)
{
uint64_t d, next_time, base;
case 3:
base = (d / s->count) * s->count;
period2 = ((s->count + 1) >> 1);
- if ((d - base) < period2)
+ if ((d - base) < period2)
next_time = base + period2;
else
next_time = base + s->count;
PITState *pit = opaque;
int ret, count;
PITChannelState *s;
-
+
addr &= 3;
s = &pit->channels[addr];
if (s->status_latched) {
pic_set_irq(s->irq, irq_level);
#ifdef DEBUG_PIT
printf("irq_level=%d next_delay=%f\n",
- irq_level,
+ irq_level,
(double)(expire_time - current_time) / ticks_per_sec);
#endif
s->next_transition_time = expire_time;
PITState *pit = opaque;
PITChannelState *s;
int i;
-
+
for(i = 0; i < 3; i++) {
s = &pit->channels[i];
qemu_put_be32s(f, &s->count);
PITState *pit = opaque;
PITChannelState *s;
int i;
-
+
if (version_id != 1)
return -EINVAL;
/*
* QEMU 8259 interrupt controller emulation
- *
+ *
* Copyright (c) 2003-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
{
int i;
for(i = 0; i < 2; i++) {
- printf("pic%d: imr=%x irr=%x padd=%d\n",
- i, s->pics[i].imr, s->pics[i].irr,
+ printf("pic%d: imr=%x irr=%x padd=%d\n",
+ i, s->pics[i].imr, s->pics[i].irr,
s->pics[i].priority_add);
-
+
}
}
printf("pic: cpu_interrupt\n");
intno = s->pics[0].irq_base + irq;
}
pic_update_irq(s);
-
+
#ifdef DEBUG_IRQ_LATENCY
- printf("IRQ%d latency=%0.3fus\n",
- irq,
+ printf("IRQ%d latency=%0.3fus\n",
+ irq,
(double)(qemu_get_clock(vm_clock) - irq_time[irq]) * 1000000.0 / ticks_per_sec);
#endif
#if defined(DEBUG_PIC)
ret = pic_poll_read(&s->pics[1], 0x80) + 8;
/* Prepare for ISR read */
s->pics[0].read_reg_select = 1;
-
+
return ret;
}
static void pic_save(QEMUFile *f, void *opaque)
{
PicState *s = opaque;
-
+
qemu_put_8s(f, &s->last_irr);
qemu_put_8s(f, &s->irr);
qemu_put_8s(f, &s->imr);
static int pic_load(QEMUFile *f, void *opaque, int version_id)
{
PicState *s = opaque;
-
+
if (version_id != 1)
return -EINVAL;
{
int i;
PicState *s;
-
+
if (!isa_pic)
return;
for(i=0;i<2;i++) {
s = &isa_pic->pics[i];
term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
- i, s->irr, s->imr, s->isr, s->priority_add,
- s->irq_base, s->read_reg_select, s->elcr,
+ i, s->irr, s->imr, s->isr, s->priority_add,
+ s->irq_base, s->read_reg_select, s->elcr,
s->special_fully_nested_mode);
}
}
/*
* QEMU IDE disk and CD-ROM Emulator
- *
+ *
* Copyright (c) 2003 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
#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */
#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */
#define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */
-#define WIN_GETMEDIASTATUS 0xDA
+#define WIN_GETMEDIASTATUS 0xDA
#define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */
#define WIN_POSTBOOT 0xDC
#define WIN_PREBOOT 0xDD
#define GPCMD_VERIFY_10 0x2f
#define GPCMD_WRITE_10 0x2a
#define GPCMD_WRITE_AND_VERIFY_10 0x2e
-/* This is listed as optional in ATAPI 2.6, but is (curiously)
+/* This is listed as optional in ATAPI 2.6, but is (curiously)
* missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
* Table 377 as an MMC command for SCSi devices though... Most ATAPI
* drives support it. */
#define GPCMD_SET_SPEED 0xbb
-/* This seems to be a SCSI specific CD-ROM opcode
+/* This seems to be a SCSI specific CD-ROM opcode
* to play data at track/index */
#define GPCMD_PLAYAUDIO_TI 0x48
/*
/* set for lba48 access */
uint8_t lba48;
/* depends on bit 4 in select, only meaningful for drive 0 */
- struct IDEState *cur_drive;
+ struct IDEState *cur_drive;
BlockDriverState *bs;
/* ATAPI specific */
uint8_t sense_key;
uint8_t cmd;
uint8_t status;
uint32_t addr;
-
+
struct PCIIDEState *pci_dev;
/* current transfer state */
uint32_t cur_addr;
memset(s->io_buffer, 0, 512);
p = (uint16_t *)s->io_buffer;
put_le16(p + 0, 0x0040);
- put_le16(p + 1, s->cylinders);
+ put_le16(p + 1, s->cylinders);
put_le16(p + 3, s->heads);
put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
put_le16(p + 5, 512); /* XXX: retired, remove ? */
- put_le16(p + 6, s->sectors);
+ put_le16(p + 6, s->sectors);
snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
put_le16(p + 20, 3); /* XXX: retired, remove ? */
put_le16(p + 22, 4); /* ecc bytes */
padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
-#if MAX_MULT_SECTORS > 1
+#if MAX_MULT_SECTORS > 1
put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
#endif
put_le16(p + 48, 1); /* dword I/O */
}
/* prepare data transfer and tell what to do after */
-static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
+static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
EndTransferFunc *end_transfer_func)
{
s->end_transfer_func = end_transfer_func;
for(;;) {
l = s->io_buffer_size - s->io_buffer_index;
- if (l <= 0)
+ if (l <= 0)
break;
if (bm->cur_prd_len == 0) {
/* end of table (with a fail safe of one page) */
l = bm->cur_prd_len;
if (l > 0) {
if (is_write) {
- cpu_physical_memory_write(bm->cur_prd_addr,
+ cpu_physical_memory_write(bm->cur_prd_addr,
s->io_buffer + s->io_buffer_index, l);
} else {
- cpu_physical_memory_read(bm->cur_prd_addr,
+ cpu_physical_memory_read(bm->cur_prd_addr,
s->io_buffer + s->io_buffer_index, l);
}
bm->cur_prd_addr += l;
#ifdef DEBUG_AIO
printf("aio_read: sector_num=%lld n=%d\n", sector_num, n);
#endif
- bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n,
+ bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n,
ide_read_dma_cb, bm);
}
ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
}
ide_set_sector(s, sector_num + n);
-
+
#ifdef TARGET_I386
if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
/* It seems there is a bug in the Windows 2000 installer HDD
that at the expense of slower write performances. Use this
option _only_ to install Windows 2000. You must disable it
for normal use. */
- qemu_mod_timer(s->sector_write_timer,
+ qemu_mod_timer(s->sector_write_timer,
qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
- } else
+ } else
#endif
{
ide_set_irq(s);
#ifdef DEBUG_AIO
printf("aio_write: sector_num=%lld n=%d\n", sector_num, n);
#endif
- bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
+ bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
ide_write_dma_cb, bm);
}
memset(buf, 0, 288);
}
-static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
+static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
int sector_size)
{
int ret;
{
/* XXX: handle more errors */
if (ret == -ENOMEDIUM) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT);
} else {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
ASC_LOGICAL_BLOCK_OOR);
}
}
{
int byte_count_limit, size, ret;
#ifdef DEBUG_IDE_ATAPI
- printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
+ printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
s->packet_transfer_size,
s->elementary_transfer_size,
s->io_buffer_index);
size = s->cd_sector_size - s->io_buffer_index;
if (size > s->elementary_transfer_size)
size = s->elementary_transfer_size;
- ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
+ ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
size, ide_atapi_cmd_reply_end);
s->packet_transfer_size -= size;
s->elementary_transfer_size -= size;
if (size > (s->cd_sector_size - s->io_buffer_index))
size = (s->cd_sector_size - s->io_buffer_index);
}
- ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
+ ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
size, ide_atapi_cmd_reply_end);
s->packet_transfer_size -= size;
s->elementary_transfer_size -= size;
bm->aiocb = NULL;
return;
}
-
+
s->io_buffer_index = 0;
if (s->cd_sector_size == 2352) {
n = 1;
#ifdef DEBUG_AIO
printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
#endif
- bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
- s->io_buffer + data_offset, n * 4,
+ bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
+ s->io_buffer + data_offset, n * 4,
ide_atapi_cmd_read_dma_cb, bm);
if (!bm->aiocb) {
/* Note: media not present is the most likely case */
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT);
goto eot;
}
ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
}
-static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
+static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
int sector_size)
{
#ifdef DEBUG_IDE_ATAPI
if (bdrv_is_inserted(s->bs)) {
ide_atapi_cmd_ok(s);
} else {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT);
}
break;
buf[9] = 0x12;
buf[10] = 0x00;
buf[11] = 0x00;
-
+
buf[12] = 0x70;
buf[13] = 3 << 5;
buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
goto error_cmd;
default:
case 3: /* saved values */
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
break;
}
bdrv_set_locked(s->bs, packet[4] & 1);
ide_atapi_cmd_ok(s);
} else {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT);
}
break;
ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
break;
default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
ASC_INV_FIELD_IN_CMD_PACKET);
break;
}
bdrv_get_geometry(s->bs, &total_sectors);
total_sectors >>= 2;
if (total_sectors <= 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT);
break;
}
lba = ube32_to_cpu(packet + 2);
if (lba >= total_sectors) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
ASC_LOGICAL_BLOCK_OOR);
break;
}
int start, eject;
start = packet[4] & 1;
eject = (packet[4] >> 1) & 1;
-
+
if (eject && !start) {
/* eject the disk */
bdrv_eject(s->bs, 1);
bdrv_get_geometry(s->bs, &total_sectors);
total_sectors >>= 2;
if (total_sectors <= 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT);
break;
}
break;
default:
error_cmd:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
ASC_INV_FIELD_IN_CMD_PACKET);
break;
}
bdrv_get_geometry(s->bs, &total_sectors);
total_sectors >>= 2;
if (total_sectors <= 0) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT);
break;
}
ide_atapi_cmd_reply(s, 36, max_len);
break;
default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
ASC_ILLEGAL_OPCODE);
break;
}
#endif
s = ide_if->cur_drive;
/* ignore commands to non existant slave */
- if (s != ide_if && !s->bs)
+ if (s != ide_if && !s->bs)
break;
switch(val) {
ide_set_irq(s);
break;
case WIN_SETMULT:
- if (s->nsector > MAX_MULT_SECTORS ||
+ if (s->nsector > MAX_MULT_SECTORS ||
s->nsector == 0 ||
(s->nsector & (s->nsector - 1)) != 0) {
ide_abort_command(s);
lba48 = 1;
case WIN_READ:
case WIN_READ_ONCE:
- if (!s->bs)
+ if (!s->bs)
goto abort_cmd;
ide_cmd_lba48_transform(s, lba48);
s->req_nb_sectors = 1;
lba48 = 1;
case WIN_READDMA:
case WIN_READDMA_ONCE:
- if (!s->bs)
+ if (!s->bs)
goto abort_cmd;
ide_cmd_lba48_transform(s, lba48);
ide_sector_read_dma(s);
lba48 = 1;
case WIN_WRITEDMA:
case WIN_WRITEDMA_ONCE:
- if (!s->bs)
+ if (!s->bs)
goto abort_cmd;
ide_cmd_lba48_transform(s, lba48);
ide_sector_write_dma(s);
goto abort_cmd;
s->atapi_dma = s->feature & 1;
s->nsector = 1;
- ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
+ ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
ide_atapi_cmd);
break;
default:
IDEState *s = ((IDEState *)opaque)->cur_drive;
uint8_t *p;
int ret;
-
+
p = s->data_ptr;
ret = cpu_to_le32(*(uint32_t *)p);
p += 4;
} __attribute__((packed));
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
-static int guess_disk_lchs(IDEState *s,
+static int guess_disk_lchs(IDEState *s,
int *pcylinders, int *pheads, int *psectors)
{
uint8_t buf[512];
*psectors = sectors;
*pcylinders = cylinders;
#if 0
- printf("guessed geometry: LCHS=%d %d %d\n",
+ printf("guessed geometry: LCHS=%d %d %d\n",
cylinders, heads, sectors);
#endif
return 0;
s->set_irq = set_irq;
s->irq_opaque = irq_opaque;
s->irq = irq;
- s->sector_write_timer = qemu_new_timer(vm_clock,
+ s->sector_write_timer = qemu_new_timer(vm_clock,
ide_sector_write_timer_cb, s);
ide_reset(s);
}
register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
}
-
+
/* data ports */
register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
ide_state = qemu_mallocz(sizeof(IDEState) * 2);
if (!ide_state)
return;
-
+
ide_init2(ide_state, hd0, hd1, pic_set_irq_new, isa_pic, irq);
ide_init_ioport(ide_state, iobase, iobase2);
}
static void cmd646_update_irq(PCIIDEState *d);
-static void ide_map(PCIDevice *pci_dev, int region_num,
+static void ide_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
PCIIDEState *d = (PCIIDEState *)pci_dev;
BMDMAState *bm = opaque;
PCIIDEState *pci_dev;
uint32_t val;
-
+
switch(addr & 3) {
- case 0:
+ case 0:
val = bm->cmd;
break;
case 1:
case 1:
pci_dev = bm->pci_dev;
if (pci_dev->type == IDE_TYPE_CMD646) {
- pci_dev->dev.config[MRDMODE] =
+ pci_dev->dev.config[MRDMODE] =
(pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
cmd646_update_irq(pci_dev);
}
bm->cur_addr = bm->addr;
}
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
+static void bmdma_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
PCIIDEState *d = (PCIIDEState *)pci_dev;
uint8_t *pci_conf;
int i;
- d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
+ d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
sizeof(PCIIDEState),
- -1,
+ -1,
NULL, NULL);
d->type = IDE_TYPE_CMD646;
pci_conf = d->dev.config;
pci_conf[0x03] = 0x06;
pci_conf[0x08] = 0x07; // IDE controller revision
- pci_conf[0x09] = 0x8f;
+ pci_conf[0x09] = 0x8f;
pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
pci_conf[0x0e] = 0x00; // header_type
-
+
if (secondary_ide_enabled) {
/* XXX: if not enabled, really disable the seconday IDE controller */
pci_conf[0x51] = 0x80; /* enable IDE1 */
}
- pci_register_io_region((PCIDevice *)d, 0, 0x8,
+ pci_register_io_region((PCIDevice *)d, 0, 0x8,
PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 1, 0x4,
+ pci_register_io_region((PCIDevice *)d, 1, 0x4,
PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 2, 0x8,
+ pci_register_io_region((PCIDevice *)d, 2, 0x8,
PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 3, 0x4,
+ pci_register_io_region((PCIDevice *)d, 3, 0x4,
PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
+ pci_register_io_region((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map);
pci_conf[0x3d] = 0x01; // interrupt on pin 1
-
+
for(i = 0; i < 4; i++)
d->ide_if[i].pci_dev = (PCIDevice *)d;
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
{
PCIIDEState *d;
uint8_t *pci_conf;
-
+
/* register a function 1 of PIIX */
- d = (PCIIDEState *)pci_register_device(bus, "PIIX IDE",
+ d = (PCIIDEState *)pci_register_device(bus, "PIIX IDE",
sizeof(PCIIDEState),
devfn,
NULL, NULL);
piix3_reset(d);
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
+ pci_register_io_region((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map);
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
{
PCIIDEState *d;
uint8_t *pci_conf;
-
+
/* register a function 1 of PIIX3 */
- d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
+ d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
sizeof(PCIIDEState),
devfn,
NULL, NULL);
piix3_reset(d);
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
+ pci_register_io_region((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map);
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
static void pmac_ide_writeb (void *opaque,
target_phys_addr_t addr, uint32_t val)
{
- addr = (addr & 0xFFF) >> 4;
+ addr = (addr & 0xFFF) >> 4;
switch (addr) {
case 1 ... 7:
ide_ioport_write(opaque, addr, val);
static void pmac_ide_writew (void *opaque,
target_phys_addr_t addr, uint32_t val)
{
- addr = (addr & 0xFFF) >> 4;
+ addr = (addr & 0xFFF) >> 4;
#ifdef TARGET_WORDS_BIGENDIAN
val = bswap16(val);
#endif
{
uint16_t retval;
- addr = (addr & 0xFFF) >> 4;
+ addr = (addr & 0xFFF) >> 4;
if (addr == 0) {
retval = ide_data_readw(opaque, 0);
} else {
static void pmac_ide_writel (void *opaque,
target_phys_addr_t addr, uint32_t val)
{
- addr = (addr & 0xFFF) >> 4;
+ addr = (addr & 0xFFF) >> 4;
#ifdef TARGET_WORDS_BIGENDIAN
val = bswap32(val);
#endif
{
uint32_t retval;
- addr = (addr & 0xFFF) >> 4;
+ addr = (addr & 0xFFF) >> 4;
if (addr == 0) {
retval = ide_data_readl(opaque, 0);
} else {
ide_if = qemu_mallocz(sizeof(IDEState) * 2);
ide_init2(&ide_if[0], hd_table[0], hd_table[1],
set_irq, irq_opaque, irq);
-
+
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
pmac_ide_write, &ide_if[0]);
return pmac_ide_memory;
-/*
+/*
* ARM Integrator CP System emulation.
*
* Copyright (c) 2005-2006 CodeSourcery.
* QEMU SPARC iommu emulation
*
* Copyright (c) 2003-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
{
IOMMUState *s = opaque;
int i;
-
+
qemu_put_be32s(f, &s->addr);
for (i = 0; i < IOMMU_NREGS; i++)
qemu_put_be32s(f, &s->regs[i]);
{
IOMMUState *s = opaque;
int i;
-
+
if (version_id != 1)
return -EINVAL;
iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, iommu_mem_write, s);
cpu_register_physical_memory(addr, IOMMU_NREGS * 4, iommu_io_memory);
-
+
register_savevm("iommu", addr, 1, iommu_save, iommu_load, s);
qemu_register_reset(iommu_reset, s);
return s;
* Memory mapped access to ISA IO space.
*
* 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
-/*
+/*
* QEMU LSI53C895A SCSI Host Bus Adapter emulation
*
* Copyright (c) 2006 CodeSourcery.
lsi_reg_writeb(s, addr + 2, (val >> 24) & 0xff);
}
-static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num,
+static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
LSIState *s = (LSIState *)pci_dev;
register_ioport_read(addr, 256, 4, lsi_io_readl, s);
}
-static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,
+static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
LSIState *s = (LSIState *)pci_dev;
cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr);
}
-static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
+static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
LSIState *s = (LSIState *)pci_dev;
/*
* QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
- *
+ *
* 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
static void set_time (m48t59_t *NVRAM, struct tm *tm)
{
time_t now, new_time;
-
+
new_time = mktime(tm);
now = time(NULL);
NVRAM->time_offset = new_time - now;
m48t59_t *NVRAM = opaque;
pic_set_irq(NVRAM->IRQ, 1);
- if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
+ if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF2] & 0x80) == 0) {
if (addr > 0x1FF8 && addr < 0x2000)
NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
- if (NVRAM->type == 8 &&
+ if (NVRAM->type == 8 &&
(addr >= 0x1ff0 && addr <= 0x1ff7))
goto do_write;
switch (addr) {
struct tm tm;
uint32_t retval = 0xFF;
- if (NVRAM->type == 8 &&
+ if (NVRAM->type == 8 &&
(addr >= 0x1ff0 && addr <= 0x1ff7))
goto do_read;
switch (addr) {
case 0x1FFF:
/* year */
get_time(NVRAM, &tm);
- if (NVRAM->type == 8)
+ if (NVRAM->type == 8)
retval = toBCD(tm.tm_year - 68); // Base year is 1968
else
retval = toBCD(tm.tm_year);
static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
{
m48t59_t *NVRAM = opaque;
-
+
addr -= NVRAM->mem_base;
m48t59_write(NVRAM, addr, value & 0xff);
}
static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
{
m48t59_t *NVRAM = opaque;
-
+
addr -= NVRAM->mem_base;
m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
m48t59_write(NVRAM, addr + 1, value & 0xff);
static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
{
m48t59_t *NVRAM = opaque;
-
+
addr -= NVRAM->mem_base;
m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
{
m48t59_t *NVRAM = opaque;
uint32_t retval;
-
+
addr -= NVRAM->mem_base;
retval = m48t59_read(NVRAM, addr);
return retval;
{
m48t59_t *NVRAM = opaque;
uint32_t retval;
-
+
addr -= NVRAM->mem_base;
retval = m48t59_read(NVRAM, addr) << 8;
retval |= m48t59_read(NVRAM, addr + 1);
/*
* QEMU MC146818 RTC emulation
- *
+ *
* Copyright (c) 2003-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
int64_t cur_clock, next_irq_clock;
period_code = s->cmos_data[RTC_REG_A] & 0x0f;
- if (period_code != 0 &&
+ if (period_code != 0 &&
(s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
if (period_code <= 2)
period_code += 7;
#ifdef DEBUG_CMOS
printf("cmos: write index=0x%02x val=0x%02x\n",
s->cmos_index, data);
-#endif
+#endif
switch(s->cmos_index) {
case RTC_SECONDS_ALARM:
case RTC_MINUTES_ALARM:
/* month is between 0 and 11. */
static int get_days_in_month(int month, int year)
{
- static const int days_tab[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ static const int days_tab[12] = {
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
int d;
if ((unsigned )month >= 12)
tm->tm_wday++;
if ((unsigned)tm->tm_wday >= 7)
tm->tm_wday = 0;
- days_in_month = get_days_in_month(tm->tm_mon,
+ days_in_month = get_days_in_month(tm->tm_mon,
tm->tm_year + 1900);
tm->tm_mday++;
if (tm->tm_mday < 1) {
qemu_mod_timer(s->second_timer, s->next_second_time);
} else {
rtc_next_second(&s->current_tm);
-
+
if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
/* update in progress bit */
s->cmos_data[RTC_REG_A] |= REG_A_UIP;
delay = (ticks_per_sec * 1) / 100;
if (delay < 1)
delay = 1;
- qemu_mod_timer(s->second_timer2,
+ qemu_mod_timer(s->second_timer2,
s->next_second_time + delay);
}
}
((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
- s->cmos_data[RTC_REG_C] |= 0xa0;
+ s->cmos_data[RTC_REG_C] |= 0xa0;
pic_set_irq(s->irq, 1);
}
}
/* update ended interrupt */
if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
- s->cmos_data[RTC_REG_C] |= 0x90;
+ s->cmos_data[RTC_REG_C] |= 0x90;
pic_set_irq(s->irq, 1);
}
case RTC_REG_C:
ret = s->cmos_data[s->cmos_index];
pic_set_irq(s->irq, 0);
- s->cmos_data[RTC_REG_C] = 0x00;
+ s->cmos_data[RTC_REG_C] = 0x00;
break;
default:
ret = s->cmos_data[s->cmos_index];
qemu_put_buffer(f, s->cmos_data, 128);
qemu_put_8s(f, &s->cmos_index);
-
+
qemu_put_be32s(f, &s->current_tm.tm_sec);
qemu_put_be32s(f, &s->current_tm.tm_min);
qemu_put_be32s(f, &s->current_tm.tm_hour);
rtc_set_date_from_host(s);
- s->periodic_timer = qemu_new_timer(vm_clock,
+ s->periodic_timer = qemu_new_timer(vm_clock,
rtc_periodic_timer, s);
- s->second_timer = qemu_new_timer(vm_clock,
+ s->second_timer = qemu_new_timer(vm_clock,
rtc_update_second, s);
- s->second_timer2 = qemu_new_timer(vm_clock,
+ s->second_timer2 = qemu_new_timer(vm_clock,
rtc_update_second2, s);
s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
void cpu_mips_irq_request(void *opaque, int irq, int level)
{
CPUState *env = first_cpu;
-
+
uint32_t mask;
if (irq >= 16)
}
}
- isa_vga_init(ds, phys_ram_base + ram_size, ram_size,
+ isa_vga_init(ds, phys_ram_base + ram_size, ram_size,
vga_ram_size);
if (nd_table[0].vlan) {
/*
* QEMU NE2000 emulation
- *
+ *
* Copyright (c) 2003-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
static int ne2000_can_receive(void *opaque)
{
NE2000State *s = opaque;
-
+
if (s->cmd & E8390_STOP)
return 1;
return !ne2000_buffer_full(s);
uint8_t *p;
int total_len, next, avail, len, index, mcast_idx;
uint8_t buf1[60];
- static const uint8_t broadcast_macaddr[6] =
+ static const uint8_t broadcast_macaddr[6] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
+
#if defined(DEBUG_NE2000)
printf("NE2000: received len=%d\n", size);
#endif
if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
return;
-
+
/* XXX: check this */
if (s->rxcr & 0x10) {
/* promiscuous: receive all */
if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
return;
} else if (s->mem[0] == buf[0] &&
- s->mem[2] == buf[1] &&
- s->mem[4] == buf[2] &&
- s->mem[6] == buf[3] &&
- s->mem[8] == buf[4] &&
+ s->mem[2] == buf[1] &&
+ s->mem[4] == buf[2] &&
+ s->mem[6] == buf[3] &&
+ s->mem[8] == buf[4] &&
s->mem[10] == buf[5]) {
/* match */
} else {
}
if (val & E8390_TRANS) {
index = (s->tpsr << 8);
- /* XXX: next 2 lines are a hack to make netware 3.11 work */
+ /* XXX: next 2 lines are a hack to make netware 3.11 work */
if (index >= NE2000_PMEM_END)
index -= NE2000_PMEM_SIZE;
/* fail safe: check range on the transmitted length */
/* signal end of transfer */
s->tsr = ENTSR_PTX;
s->isr |= ENISR_TX;
- s->cmd &= ~E8390_TRANS;
+ s->cmd &= ~E8390_TRANS;
ne2000_update_irq(s);
}
}
return ret;
}
-static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr,
+static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr,
uint32_t val)
{
- if (addr < 32 ||
+ if (addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
s->mem[addr] = val;
}
}
-static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr,
+static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr,
uint32_t val)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
+ if (addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
*(uint16_t *)(s->mem + addr) = cpu_to_le16(val);
}
}
-static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
+static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
uint32_t val)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
+ if (addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
}
static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr)
{
- if (addr < 32 ||
+ if (addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
return s->mem[addr];
} else {
static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
+ if (addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
return le16_to_cpu(*(uint16_t *)(s->mem + addr));
} else {
static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
+ if (addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
return le32_to_cpupu((uint32_t *)(s->mem + addr));
} else {
void isa_ne2000_init(int base, int irq, NICInfo *nd)
{
NE2000State *s;
-
+
s = qemu_mallocz(sizeof(NE2000State));
if (!s)
return;
-
+
register_ioport_write(base, 16, 1, ne2000_ioport_write, s);
register_ioport_read(base, 16, 1, ne2000_ioport_read, s);
s->macaddr[3],
s->macaddr[4],
s->macaddr[5]);
-
+
register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
}
NE2000State ne2000;
} PCINE2000State;
-static void ne2000_map(PCIDevice *pci_dev, int region_num,
+static void ne2000_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
PCINE2000State *d = (PCINE2000State *)pci_dev;
PCINE2000State *d;
NE2000State *s;
uint8_t *pci_conf;
-
+
d = (PCINE2000State *)pci_register_device(bus,
"NE2000", sizeof(PCINE2000State),
- devfn,
+ devfn,
NULL, NULL);
pci_conf = d->dev.config;
pci_conf[0x00] = 0xec; // Realtek 8029
pci_conf[0x01] = 0x10;
pci_conf[0x02] = 0x29;
pci_conf[0x03] = 0x80;
- pci_conf[0x0a] = 0x00; // ethernet network controller
+ pci_conf[0x0a] = 0x00; // ethernet network controller
pci_conf[0x0b] = 0x02;
pci_conf[0x0e] = 0x00; // header_type
pci_conf[0x3d] = 1; // interrupt pin 0
-
- pci_register_io_region(&d->dev, 0, 0x100,
+
+ pci_register_io_region(&d->dev, 0, 0x100,
PCI_ADDRESS_SPACE_IO, ne2000_map);
s = &d->ne2000;
s->irq = 16; // PCI interrupt
s->macaddr[3],
s->macaddr[4],
s->macaddr[5]);
-
+
/* XXX: instance number ? */
register_savevm("ne2000", 0, 3, ne2000_save, ne2000_load, s);
}
/*
* OpenPIC emulation
- *
+ *
* Copyright (c) 2004 Jocelyn Mayer
- *
+ *
* 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
* - Motorola Harrier programmer manuel
*
* Serial interrupts, as implemented in Raven chipset are not supported yet.
- *
+ *
*/
#include "vl.h"
priority = -1;
for (i = 0; i < MAX_IRQ; i++) {
if (IRQ_testbit(q, i)) {
- DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
+ DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
i, IPVP_PRIORITY(opp->src[i].ipvp), priority);
if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) {
next = i;
IRQ_src_t *src;
src = &opp->src[n_IRQ];
- DPRINTF("openpic: set irq %d = %d ipvp=%08x\n",
+ DPRINTF("openpic: set irq %d = %d ipvp=%08x\n",
n_IRQ, level, src->ipvp);
if (test_bit(&src->ipvp, IPVP_SENSE)) {
/* level-sensitive irq */
/* NOTE: not fully accurate for special IRQs, but simple and
sufficient */
/* ACTIVITY bit is read-only */
- opp->src[n_IRQ].ipvp =
+ opp->src[n_IRQ].ipvp =
(opp->src[n_IRQ].ipvp & 0x40000000) |
(val & 0x800F00FF);
openpic_update_irq(opp, n_IRQ);
- DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n",
+ DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n",
n_IRQ, val, opp->src[n_IRQ].ipvp);
break;
case IRQ_IDE:
return retval;
}
-
+
static void write_doorbell_register (penpic_t *opp, int n_dbl,
uint32_t offset, uint32_t value)
{
IRQ_dst_t *dst;
uint32_t retval;
int idx, n_IRQ;
-
+
DPRINTF("%s: addr %08x\n", __func__, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
&openpic_readl,
};
-static void openpic_map(PCIDevice *pci_dev, int region_num,
+static void openpic_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
openpic_t *opp;
openpic_t *opp;
uint8_t *pci_conf;
int i, m;
-
+
/* XXX: for now, only one CPU is supported */
if (nb_cpus != 1)
return NULL;
pci_conf[0x0b] = 0x08;
pci_conf[0x0e] = 0x00; // header_type
pci_conf[0x3d] = 0x00; // no interrupt pin
-
+
/* Register I/O spaces */
pci_register_io_region((PCIDevice *)opp, 0, 0x40000,
PCI_ADDRESS_SPACE_MEM, &openpic_map);
opp->mem_index = cpu_register_io_memory(0, openpic_read,
openpic_write, opp);
-
+
// isu_base &= 0xFFFC0000;
opp->nb_cpus = nb_cpus;
/* Set IRQ types */
/*
* QEMU Parallel PORT emulation
- *
+ *
* Copyright (c) 2003-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
static void parallel_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
ParallelState *s = opaque;
-
+
addr &= 7;
#ifdef DEBUG_PARALLEL
printf("parallel: write addr=0x%02x val=0x%02x\n", addr, val);
case 0:
if (s->hw_driver) {
qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &s->data);
- }
- ret = s->data;
+ }
+ ret = s->data;
break;
case 1:
if (s->hw_driver) {
qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &s->status);
- ret = s->status;
+ ret = s->status;
} else {
ret = s->status;
s->irq_pending = 0;
/*
* QEMU PC System Emulator
- *
+ *
* Copyright (c) 2003-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
#if USE_KQEMU
if (env->kqemu_enabled) {
return cpu_get_real_ticks();
- } else
+ } else
#endif
{
return cpu_get_ticks();
if (intno >= 0) {
/* set irq request if a PIC irq is still pending */
/* XXX: improve that */
- pic_update_irq(isa_pic);
+ pic_update_irq(isa_pic);
return intno;
}
/* read the irq from the PIC */
return val;
}
-static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
+static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
{
RTCState *s = rtc_state;
int cylinders, heads, sectors;
val = 65535;
rtc_set_memory(s, 0x34, val);
rtc_set_memory(s, 0x35, val >> 8);
-
+
switch(boot_device) {
case 'a':
case 'b':
val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1);
rtc_set_memory(s, 0x10, val);
-
+
val = 0;
nb = 0;
if (fd0 < 3)
rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
if (hd_table[0])
cmos_init_hd(0x19, 0x1b, hd_table[0]);
- if (hd_table[1])
+ if (hd_table[1])
cmos_init_hd(0x1a, 0x24, hd_table[1]);
val = 0;
{
static const char shutdown_str[8] = "Shutdown";
static int shutdown_index = 0;
-
+
switch(addr) {
/* Bochs BIOS messages */
case 0x400:
}
-int load_kernel(const char *filename, uint8_t *addr,
+int load_kernel(const char *filename, uint8_t *addr,
uint8_t *real_addr)
{
int fd, size;
setup_sects = real_addr[0x1F1];
if (!setup_sects)
setup_sects = 4;
- if (read(fd, real_addr + 512, setup_sects * 512) !=
+ if (read(fd, real_addr + 512, setup_sects * 512) !=
setup_sects * 512)
goto fail;
-
+
/* load 32 bit code */
size = read(fd, addr, 16 * 1024 * 1024);
if (size < 0)
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
bios_size = get_image_size(buf);
- if (bios_size <= 0 ||
+ if (bios_size <= 0 ||
(bios_size % 65536) != 0 ||
bios_size > (256 * 1024)) {
goto bios_error;
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
}
ret = load_image(buf, phys_ram_base + vga_bios_offset);
-
+
/* setup basic memory access */
- cpu_register_physical_memory(0xc0000, 0x10000,
+ cpu_register_physical_memory(0xc0000, 0x10000,
vga_bios_offset | IO_MEM_ROM);
/* map the last 128KB of the BIOS in ISA space */
isa_bios_size = bios_size;
if (isa_bios_size > (128 * 1024))
isa_bios_size = 128 * 1024;
- cpu_register_physical_memory(0xd0000, (192 * 1024) - isa_bios_size,
+ cpu_register_physical_memory(0xd0000, (192 * 1024) - isa_bios_size,
IO_MEM_UNASSIGNED);
- cpu_register_physical_memory(0x100000 - isa_bios_size,
- isa_bios_size,
+ cpu_register_physical_memory(0x100000 - isa_bios_size,
+ isa_bios_size,
(bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
option_rom_offset = 0;
}
/* map all the bios at the top of memory */
- cpu_register_physical_memory((uint32_t)(-bios_size),
+ cpu_register_physical_memory((uint32_t)(-bios_size),
bios_size, bios_offset | IO_MEM_ROM);
-
+
bochs_bios_init();
if (linux_boot) {
bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
/* now we can load the kernel */
- ret = load_kernel(kernel_filename,
+ ret = load_kernel(kernel_filename,
phys_ram_base + KERNEL_LOAD_ADDR,
phys_ram_base + KERNEL_PARAMS_ADDR);
if (ret < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
kernel_filename);
exit(1);
}
-
+
/* load initrd */
initrd_size = 0;
if (initrd_filename) {
initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+ fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
initrd_filename);
exit(1);
}
if (cirrus_vga_enabled) {
if (pci_enabled) {
- pci_cirrus_vga_init(pci_bus,
- ds, phys_ram_base + ram_size, ram_size,
+ pci_cirrus_vga_init(pci_bus,
+ ds, phys_ram_base + ram_size, ram_size,
vga_ram_size);
} else {
- isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size,
+ isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size,
vga_ram_size);
}
} else {
if (pci_enabled) {
- pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
+ pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
vga_ram_size, 0, 0);
} else {
- isa_vga_init(ds, phys_ram_base + ram_size, ram_size,
+ isa_vga_init(ds, phys_ram_base + ram_size, ram_size,
vga_ram_size);
}
}
piix4_smbus_register_device(eeprom, 0x50 + i);
}
}
-
+
if (i440fx_state) {
i440fx_init_memory_mappings(i440fx_state);
}
}
static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
+ DisplayState *ds, const char **fd_filename,
+ int snapshot,
+ const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename)
{
}
static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
- int snapshot,
- const char *kernel_filename,
+ DisplayState *ds, const char **fd_filename,
+ int snapshot,
+ const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename)
{
* 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
}
/* -1 for devfn means auto assign */
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
+PCIDevice *pci_register_device(PCIBus *bus, const char *name,
int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
+ 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])
return pci_dev;
}
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
+void pci_register_io_region(PCIDevice *pci_dev, int region_num,
+ uint32_t size, int type,
PCIMapIORegionFunc *map_func)
{
PCIIORegion *r;
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 (r->size != 0) {
if (r->type & PCI_ADDRESS_SPACE_IO) {
if (cmd & PCI_COMMAND_IO) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
+ 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;
}
} else {
if (cmd & PCI_COMMAND_MEMORY) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
+ 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))
}
} else {
cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
- r->size,
+ r->size,
IO_MEM_UNASSIGNED);
}
}
}
}
-uint32_t pci_default_read_config(PCIDevice *d,
+uint32_t pci_default_read_config(PCIDevice *d,
uint32_t address, int len)
{
uint32_t val;
return val;
}
-void pci_default_write_config(PCIDevice *d,
+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) ||
+ if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
(address >= 0x30 && address < 0x34))) {
PCIIORegion *r;
int reg;
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);
{
PCIBus *bus;
int change;
-
+
change = level - pci_dev->irq_state[irq_num];
if (!change)
return;
const char *desc;
} pci_class_desc;
-static pci_class_desc pci_class_descriptions[] =
+static pci_class_desc pci_class_descriptions[] =
{
{ 0x0100, "SCSI controller"},
{ 0x0101, "IDE controller"},
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",
+ 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",
+ term_printf("32 bit memory at 0x%08x [0x%08x].\n",
r->addr, r->addr + r->size - 1);
}
}
PCIBus *bus = first_bus;
PCIDevice *d;
int devfn;
-
+
while (bus && bus->bus_num != bus_num)
bus = bus->next;
if (bus) {
PCIBus *bus;
} PCIBridge;
-void pci_bridge_write_config(PCIDevice *d,
+void pci_bridge_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len)
{
PCIBridge *s = (PCIBridge *)d;
pci_map_irq_fn map_irq, const char *name)
{
PCIBridge *s;
- s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
+ 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;
* 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
/*
* QEMU PC keyboard emulation
- *
+ *
* Copyright (c) 2003 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
{
int irq12_level, irq1_level;
- irq1_level = 0;
- irq12_level = 0;
+ irq1_level = 0;
+ irq12_level = 0;
s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
if (s->pending) {
s->status |= KBD_STAT_OBF;
if (s->mode & KBD_MODE_MOUSE_INT)
irq12_level = 1;
} else {
- if ((s->mode & KBD_MODE_KBD_INT) &&
+ if ((s->mode & KBD_MODE_KBD_INT) &&
!(s->mode & KBD_MODE_DISABLE_KBD))
irq1_level = 1;
}
static void kbd_save(QEMUFile* f, void* opaque)
{
KBDState *s = (KBDState*)opaque;
-
+
qemu_put_8s(f, &s->write_cmd);
qemu_put_8s(f, &s->status);
qemu_put_8s(f, &s->mode);
static int kbd_load(QEMUFile* f, void* opaque, int version_id)
{
KBDState *s = (KBDState*)opaque;
-
+
if (version_id != 3)
return -EINVAL;
qemu_get_8s(f, &s->write_cmd);
void kbd_init(void)
{
KBDState *s = &kbd_state;
-
+
kbd_reset(s);
register_savevm("pckbd", 0, 3, kbd_save, kbd_load, s);
register_ioport_read(0x60, 1, 1, kbd_read_data, s);
/*
* QEMU AMD PC-Net II (Am79C970A) emulation
- *
+ *
* Copyright (c) 2004 Antony T Curtis
- *
+ *
* 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
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-
+
/* This software was written to be compatible with the specification:
* AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
* AMD Publication# 19436 Rev:E Amendment/0 Issue Date: June 2000
*/
-
+
/*
* On Sparc32, this is the Lance (Am7990) part of chip STP2000 (Master I/O), also
* produced as NCR89C100. See
*/
/* TODO: remove little endian host assumptions */
-
+
#include "vl.h"
//#define PCNET_DEBUG
} tmd2;
struct {
unsigned res:32;
- } tmd3;
+ } tmd3;
};
struct pcnet_RMD {
struct {
unsigned PACKED_FIELD(mcnt:12), PACKED_FIELD(zeros:4);
unsigned PACKED_FIELD(rpc:8), PACKED_FIELD(rcc:8);
- } rmd2;
+ } rmd2;
struct {
unsigned res:32;
- } rmd3;
+ } rmd3;
};
(R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt, \
(R)->rmd2.zeros)
-static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd1,
+static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd1,
target_phys_addr_t addr)
{
uint32_t *tmd = (uint32_t *)tmd1;
if (!BCR_SWSTYLE(s)) {
uint16_t rda[4];
- s->phys_mem_read(s->dma_opaque, addr,
+ s->phys_mem_read(s->dma_opaque, addr,
(void *)&rda[0], sizeof(rda), 0);
le16_to_cpus(&rda[0]);
le16_to_cpus(&rda[1]);
rmd[3] = 0;
} else {
uint32_t rda[4];
- s->phys_mem_read(s->dma_opaque, addr,
+ s->phys_mem_read(s->dma_opaque, addr,
(void *)&rda[0], sizeof(rda), 0);
le32_to_cpus(&rda[0]);
le32_to_cpus(&rda[1]);
}
}
-static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1,
+static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1,
target_phys_addr_t addr)
{
const uint32_t *rmd = (const uint32_t *)rmd1;
static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
{
struct qemu_ether_header *hdr = (void *)buf;
- uint8_t padr[6] = {
+ uint8_t padr[6] = {
s->csr[12] & 0xff, s->csr[12] >> 8,
s->csr[13] & 0xff, s->csr[13] >> 8,
- s->csr[14] & 0xff, s->csr[14] >> 8
+ s->csr[14] & 0xff, s->csr[14] >> 8
};
int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
#ifdef PCNET_DEBUG_MATCH
static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
{
struct qemu_ether_header *hdr = (void *)buf;
- if ((*(hdr->ether_dhost)&0x01) &&
+ if ((*(hdr->ether_dhost)&0x01) &&
((uint64_t *)&s->csr[8])[0] != 0LL) {
- uint8_t ladr[8] = {
+ uint8_t ladr[8] = {
s->csr[8] & 0xff, s->csr[8] >> 8,
s->csr[9] & 0xff, s->csr[9] >> 8,
- s->csr[10] & 0xff, s->csr[10] >> 8,
- s->csr[11] & 0xff, s->csr[11] >> 8
+ s->csr[10] & 0xff, s->csr[10] >> 8,
+ s->csr[11] & 0xff, s->csr[11] >> 8
};
int index = lnc_mchash(hdr->ether_dhost) >> 26;
return !!(ladr[index >> 3] & (1 << (index & 7)));
return 0;
}
-static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
+static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
{
while (idx < 1) idx += CSR_RCVRL(s);
return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
{
- int64_t next_time = current_time +
- muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
+ int64_t next_time = current_time +
+ muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
ticks_per_sec, 33000000L);
if (next_time <= current_time)
next_time = current_time + 1;
s->rdra = 0;
s->tdra = 0;
s->rap = 0;
-
+
s->bcr[BCR_BSBC] &= ~0x0080;
s->csr[0] = 0x0004;
{
int isr = 0;
s->csr[0] &= ~0x0080;
-
+
#if 1
if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
(((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
(!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
#endif
{
-
+
isr = CSR_INEA(s);
s->csr[0] |= 0x0080;
}
-
+
if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
s->csr[4] &= ~0x0080;
s->csr[4] |= 0x0040;
}
#if 1
- if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
+ if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
#else
if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
(!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
#ifdef PCNET_DEBUG
printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
#endif
-
+
if (BCR_SSIZE32(s)) {
struct pcnet_initblk32 initblk;
s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
rdra &= 0x00ffffff;
tdra &= 0x00ffffff;
}
-
+
#if defined(PCNET_DEBUG)
printf("rlen=%d tlen=%d\n",
rlen, tlen);
CSR_XMTRC(s) = CSR_XMTRL(s);
#ifdef PCNET_DEBUG
- printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
+ printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
BCR_SSIZE32(s),
s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
#endif
- s->csr[0] |= 0x0101;
+ s->csr[0] |= 0x0101;
s->csr[0] &= ~0x0004; /* clear STOP bit */
}
if (!CSR_DTX(s))
s->csr[0] |= 0x0010; /* set TXON */
-
+
if (!CSR_DRX(s))
s->csr[0] |= 0x0020; /* set RXON */
target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
#else
- target_phys_addr_t crda = s->rdra +
+ target_phys_addr_t crda = s->rdra +
(CSR_RCVRL(s) - CSR_RCVRC(s)) *
(BCR_SWSTYLE(s) ? 16 : 8 );
int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
- target_phys_addr_t nrda = s->rdra +
+ target_phys_addr_t nrda = s->rdra +
(CSR_RCVRL(s) - nrdc) *
(BCR_SWSTYLE(s) ? 16 : 8 );
int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
- target_phys_addr_t nnrd = s->rdra +
+ target_phys_addr_t nnrd = s->rdra +
(CSR_RCVRL(s) - nnrc) *
(BCR_SWSTYLE(s) ? 16 : 8 );
#endif
#endif
}
}
-
+
if (CSR_CRDA(s)) {
struct pcnet_RMD rmd;
RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
} else {
CSR_CRBC(s) = CSR_CRST(s) = 0;
}
-
+
if (CSR_NRDA(s)) {
struct pcnet_RMD rmd;
RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
{
s->csr[34] = s->csr[35] = 0;
if (s->tdra) {
- target_phys_addr_t cxda = s->tdra +
+ target_phys_addr_t cxda = s->tdra +
(CSR_XMTRL(s) - CSR_XMTRC(s)) *
(BCR_SWSTYLE(s) ? 16 : 8 );
int bad = 0;
if (CSR_CXDA(s)) {
struct pcnet_TMD tmd;
- TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
+ TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
CSR_CXBC(s) = tmd.tmd1.bcnt;
CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
} else {
CSR_CXBC(s) = CSR_CXST(s) = 0;
}
-
+
return !!(CSR_CXST(s) & 0x8000);
}
PCNetState *s = opaque;
if (CSR_STOP(s) || CSR_SPND(s))
return 0;
-
+
if (s->recv_pos > 0)
return 0;
size = MIN_BUF_SIZE;
}
- if (CSR_PROM(s)
- || (is_padr=padr_match(s, buf, size))
+ if (CSR_PROM(s)
+ || (is_padr=padr_match(s, buf, size))
|| (is_bcast=padr_bcast(s, buf, size))
|| (is_ladr=ladr_match(s, buf, size))) {
nrda = s->rdra +
(CSR_RCVRL(s) - rcvrc) *
(BCR_SWSTYLE(s) ? 16 : 8 );
- RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
+ RMDLOAD(&rmd, PHYSADDR(s,nrda));
+ if (rmd.rmd1.own) {
#ifdef PCNET_DEBUG_RMD
- printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
+ printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
rcvrc, CSR_RCVRC(s));
#endif
CSR_RCVRC(s) = rcvrc;
int pktcount = 0;
memcpy(src, buf, size);
-
+
#if 1
/* no need to compute the CRC */
src[size] = 0;
while (size < 46) {
src[size++] = 0;
}
-
+
while (p != &src[size]) {
CRC(fcs, *p++);
}
PCNET_RECV_STORE();
}
}
- }
+ }
}
#undef PCNET_RECV_STORE
s->csr[0] |= 0x0400;
#ifdef PCNET_DEBUG
- printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
+ printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
#endif
#ifdef PCNET_DEBUG_RMD
PRINT_RMD(&rmd);
-#endif
+#endif
while (pktcount--) {
if (CSR_RCVRC(s) <= 1)
CSR_RCVRC(s) = CSR_RCVRL(s);
else
- CSR_RCVRC(s)--;
+ CSR_RCVRC(s)--;
}
-
+
pcnet_rdte_poll(s);
- }
+ }
}
pcnet_poll(s);
- pcnet_update_irq(s);
+ pcnet_update_irq(s);
}
static void pcnet_transmit(PCNetState *s)
target_phys_addr_t xmit_cxda = 0;
int count = CSR_XMTRL(s)-1;
s->xmit_pos = -1;
-
+
if (!CSR_TXON(s)) {
s->csr[0] &= ~0x0008;
return;
if (pcnet_tdte_poll(s)) {
struct pcnet_TMD tmd;
- TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
+ TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
#ifdef PCNET_DEBUG_TMD
printf(" TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
PRINT_TMD(&tmd);
#endif
if (tmd.tmd1.stp) {
- s->xmit_pos = 0;
+ s->xmit_pos = 0;
if (!tmd.tmd1.enp) {
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
- s->buffer, 4096 - tmd.tmd1.bcnt,
+ s->buffer, 4096 - tmd.tmd1.bcnt,
CSR_BSWP(s));
s->xmit_pos += 4096 - tmd.tmd1.bcnt;
- }
+ }
xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
}
if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
- s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt,
+ s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt,
CSR_BSWP(s));
s->xmit_pos += 4096 - tmd.tmd1.bcnt;
#ifdef PCNET_DEBUG
printf("pcnet_transmit size=%d\n", s->xmit_pos);
-#endif
+#endif
if (CSR_LOOP(s))
pcnet_receive(s, s->buffer, s->xmit_pos);
else
if (count--)
goto txagain;
- } else
+ } else
if (s->xmit_pos >= 0) {
struct pcnet_TMD tmd;
- TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
+ TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
tmd.tmd1.own = 0;
TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
pcnet_rdte_poll(s);
}
- if (CSR_TDMD(s) ||
+ if (CSR_TDMD(s) ||
(CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
{
/* prevent recursion */
pcnet_transmit(s);
}
- pcnet_update_irq(s);
+ pcnet_update_irq(s);
if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
uint64_t now = qemu_get_clock(vm_clock) * 33;
} else
CSR_POLL(s) = t;
}
- qemu_mod_timer(s->poll_timer,
+ qemu_mod_timer(s->poll_timer,
pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
}
}
if (!CSR_STRT(s) && (val & 2))
pcnet_start(s);
- if (CSR_TDMD(s))
+ if (CSR_TDMD(s))
pcnet_transmit(s);
return;
case 3:
break;
case 4:
- s->csr[4] &= ~(val & 0x026a);
+ s->csr[4] &= ~(val & 0x026a);
val &= ~0x026a; val |= s->csr[4] & 0x026a;
break;
case 5:
- s->csr[5] &= ~(val & 0x0a90);
+ s->csr[5] &= ~(val & 0x0a90);
val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
break;
case 16:
PCNetState *s = opaque;
#ifdef PCNET_DEBUG
printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
+#endif
/* Check APROMWE bit to enable write access */
if (pcnet_bcr_readw(s,2) & 0x80)
s->prom[addr & 15] = val;
-}
+}
static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
{
pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
#ifdef PCNET_DEBUG_IO
printf("device switched into dword i/o mode\n");
-#endif
+#endif
}
pcnet_update_irq(s);
}
PCNetState *s = opaque;
uint32_t val = -1;
pcnet_poll_timer(s);
- if (BCR_DWIO(s)) {
+ if (BCR_DWIO(s)) {
switch (addr & 0x0f) {
case 0x00: /* RDP */
val = pcnet_csr_readw(s, s->rap);
return val;
}
-static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
+static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
PCNetState *d = (PCNetState *)pci_dev;
register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
-
+
register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
pcnet_aprom_writeb(d, addr & 0x0f, val);
}
-static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
{
PCNetState *d = opaque;
uint32_t val = -1;
}
}
-static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
+static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
{
PCNetState *d = opaque;
uint32_t val = -1;
}
}
-static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
{
PCNetState *d = opaque;
uint32_t val;
d->nd = nd;
- d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
+ d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
pcnet_can_receive, d);
-
+
snprintf(d->vc->info_str, sizeof(d->vc->info_str),
"pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
d->nd->macaddr[0],
(CPUReadMemoryFunc *)&pcnet_mmio_readl
};
-static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
+static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
PCNetState *d = (PCNetState *)pci_dev;
uint8_t *pci_conf;
#if 0
- printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
+ printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
#endif
d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
devfn, NULL, NULL);
-
+
pci_conf = d->dev.config;
-
+
*(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
- *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);
- *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
+ *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);
+ *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
*(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
pci_conf[0x08] = 0x10;
pci_conf[0x09] = 0x00;
- pci_conf[0x0a] = 0x00; // ethernet network controller
+ pci_conf[0x0a] = 0x00; // ethernet network controller
pci_conf[0x0b] = 0x02;
pci_conf[0x0e] = 0x00; // header_type
-
+
*(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
*(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
-
+
pci_conf[0x3d] = 1; // interrupt pin 0
pci_conf[0x3e] = 0x06;
pci_conf[0x3f] = 0xff;
d->mmio_index =
cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
- pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
+ pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
-
- pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
+
+ pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
-
+
d->set_irq_cb = pcnet_pci_set_irq_cb;
d->phys_mem_read = pci_physical_memory_read;
d->phys_mem_write = pci_physical_memory_write;
/*
* CFI parallel flash with AMD command set emulation
- *
+ *
* Copyright (c) 2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
}
/* update flash content on disk */
-static void pflash_update(pflash_t *pfl, int offset,
+static void pflash_update(pflash_t *pfl, int offset,
int size)
{
int offset_end;
/* round to sectors */
offset = offset >> 9;
offset_end = (offset_end + 511) >> 9;
- bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
+ bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
offset_end - offset);
}
}
offset -= (target_ulong)(long)pfl->storage;
else
offset -= pfl->base;
-
+
cmd = value;
DPRINTF("%s: offset %08x %08x %d\n", __func__, offset, value, width);
if (pfl->cmd != 0xA0 && cmd == 0xF0) {
pfl->status = 0x00;
pflash_update(pfl, 0, pfl->total_len);
/* Let's wait 5 seconds before chip erase is done */
- qemu_mod_timer(pfl->timer,
+ qemu_mod_timer(pfl->timer,
qemu_get_clock(vm_clock) + (ticks_per_sec * 5));
break;
case 0x30:
pflash_update(pfl, offset, pfl->sector_len);
pfl->status = 0x00;
/* Let's wait 1/2 second before sector erase is done */
- qemu_mod_timer(pfl->timer,
+ qemu_mod_timer(pfl->timer,
qemu_get_clock(vm_clock) + (ticks_per_sec / 2));
break;
default:
pflash_t *pflash_register (target_ulong base, ram_addr_t off,
BlockDriverState *bs,
target_ulong sector_len, int nb_blocs, int width,
- uint16_t id0, uint16_t id1,
+ uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3)
{
pflash_t *pfl;
* QEMU i440FX/PIIX3 PCI Bridge Emulation
*
* 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
switch(r) {
case 3:
/* RAM */
- cpu_register_physical_memory(start, end - start,
+ cpu_register_physical_memory(start, end - start,
start);
break;
case 1:
/* ROM (XXX: not quite correct) */
- cpu_register_physical_memory(start, end - start,
+ cpu_register_physical_memory(start, end - start,
start | IO_MEM_ROM);
break;
case 2:
case 0:
/* XXX: should distinguish read/write cases */
for(addr = start; addr < end; addr += 4096) {
- cpu_register_physical_memory(addr, 4096,
+ cpu_register_physical_memory(addr, 4096,
isa_page_descs[(addr - 0xa0000) >> 12]);
}
break;
cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000);
} else {
for(addr = 0xa0000; addr < 0xc0000; addr += 4096) {
- cpu_register_physical_memory(addr, 4096,
+ cpu_register_physical_memory(addr, 4096,
isa_page_descs[(addr - 0xa0000) >> 12]);
}
}
}
}
-static void i440fx_write_config(PCIDevice *d,
+static void i440fx_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len)
{
/* XXX: implement SMRAM.D_LOCK */
register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
- d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,
+ d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0,
NULL, i440fx_write_config);
d->config[0x00] = 0x86; // vendor_id
-/*
+/*
* Arm PrimeCell PL011 UART
*
* Copyright (c) 2006 CodeSourcery.
static void pl011_update(pl011_state *s)
{
uint32_t flags;
-
+
flags = s->int_level & s->int_enabled;
pic_set_irq_new(s->pic, s->irq, flags != 0);
}
s->ifl = 0x12;
s->cr = 0x300;
s->flags = 0x90;
- if (chr){
+ if (chr){
qemu_chr_add_handlers(chr, pl011_can_recieve, pl011_recieve,
pl011_event, s);
}
-/*
+/*
* Arm PrimeCell PL050 Keyboard / Mouse Interface
*
* Copyright (c) 2006 CodeSourcery.
-/*
+/*
* Arm PrimeCell PL080/PL081 DMA controller
*
* Copyright (c) 2006 CodeSourcery.
continue;
flow = (ch->conf >> 11) & 7;
if (flow >= 4) {
- cpu_abort(cpu_single_env,
+ cpu_abort(cpu_single_env,
"pl080_run: Peripheral flow control not implemented\n");
}
src_id = (ch->conf >> 1) & 0x1f;
-/*
+/*
* Arm PrimeCell PL110 Color LCD Controller
*
* Copyright (c) 2005-2006 CodeSourcery.
if (!pl110_enabled(s))
return;
-
+
switch (s->ds->depth) {
case 0:
return;
fn = fntable[s->bpp + 12];
else
fn = fntable[s->bpp];
-
+
src_width = s->cols;
switch (s->bpp) {
case BPP_1:
-/*
+/*
* Arm PrimeCell PL110 Color LCD Controller
*
* Copyright (c) 2005 CodeSourcery, LLC.
#define COPY_PIXEL(to, from) *(to++) = from
#elif BITS == 15 || BITS == 16
#define COPY_PIXEL(to, from) *(uint16_t *)to = from; to += 2;
-#elif BITS == 24
+#elif BITS == 24
#define COPY_PIXEL(to, from) \
*(to++) = from; *(to++) = (from) >> 8; *(to++) = (from) >> 16
#elif BITS == 32
-/*
+/*
* Arm PrimeCell PL190 Vector Interrupt Controller
*
* Copyright (c) 2006 CodeSourcery.
/*
* QEMU generic PPC hardware System Emulator
- *
+ *
* Copyright (c) 2003-2004 Jocelyn Mayer
- *
+ *
* 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
/*
* QEMU PPC CHRP/PMAC hardware System Emulator
- *
+ *
* 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
s = qemu_mallocz(sizeof(MacIONVRAMState));
if (!s)
return NULL;
- macio_nvram_mem_index = cpu_register_io_memory(0, macio_nvram_read,
+ macio_nvram_mem_index = cpu_register_io_memory(0, macio_nvram_read,
macio_nvram_write, s);
return s;
}
-static void macio_map(PCIDevice *pci_dev, int region_num,
+static void macio_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
if (heathrow_pic_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x00000, 0x1000,
+ cpu_register_physical_memory(addr + 0x00000, 0x1000,
heathrow_pic_mem_index);
}
cpu_register_physical_memory(addr + 0x08000, 0x1000, dbdma_mem_index);
if (ide1_mem_index >= 0)
cpu_register_physical_memory(addr + 0x20000, 0x1000, ide1_mem_index);
if (openpic_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x40000, 0x40000,
+ cpu_register_physical_memory(addr + 0x40000, 0x40000,
openpic_mem_index);
}
if (macio_nvram_mem_index >= 0)
d->config[0x0e] = 0x00; // header_type
d->config[0x3d] = 0x01; // interrupt on pin 1
-
+
dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
- pci_register_io_region(d, 0, 0x80000,
+ pci_register_io_region(d, 0, 0x80000,
PCI_ADDRESS_SPACE_MEM, macio_map);
}
{
static int vga_vbl_enabled;
int linesize;
-
+
// printf("osi_call R5=%d\n", env->gpr[5]);
/* same handler as PearPC, coming from the original MOL video
break;
}
}
- env->gpr[3] = 0;
+ env->gpr[3] = 0;
env->gpr[4] = (1 << 16) | 1; /* num_vmodes, cur_vmode */
env->gpr[5] = (1 << 16) | 0; /* num_depths, cur_depth_mode */
env->gpr[6] = (graphic_width << 16) | graphic_height; /* w, h */
break;
case 64: /* get color */
/* R6 = index */
- env->gpr[3] = 0;
+ env->gpr[3] = 0;
break;
case 116: /* set hwcursor */
/* R6 = x, R7 = y, R8 = visible, R9 = data */
void pmac_format_nvram_partition(uint8_t *buf, int len)
{
char partition_name[12] = "wwwwwwwwwwww";
-
+
buf[0] = 0x7f; /* free partition magic */
buf[1] = 0; /* checksum */
buf[2] = len >> 8;
buf[3] = len;
memcpy(buf + 4, partition_name, 12);
buf[1] = nvram_chksum(buf, 16);
-}
+}
/* PowerPC CHRP hardware initialisation */
static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
+ DisplayState *ds, const char **fd_filename,
int snapshot,
- const char *kernel_filename,
+ const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
int is_heathrow)
/* Set time-base frequency to 100 Mhz */
cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
-
+
env->osi_call = vga_osi_call;
/* allocate RAM */
exit(1);
}
bios_size = (bios_size + 0xfff) & ~0xfff;
- cpu_register_physical_memory((uint32_t)(-bios_size),
+ cpu_register_physical_memory((uint32_t)(-bios_size),
bios_size, bios_offset | IO_MEM_ROM);
-
+
/* allocate and load VGA BIOS */
vga_bios_offset = bios_offset + bios_size;
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
phys_ram_base[vga_bios_offset + 1] = 'D';
phys_ram_base[vga_bios_offset + 2] = 'R';
phys_ram_base[vga_bios_offset + 3] = 'V';
- cpu_to_be32w((uint32_t *)(phys_ram_base + vga_bios_offset + 4),
+ cpu_to_be32w((uint32_t *)(phys_ram_base + vga_bios_offset + 4),
vga_bios_size);
vga_bios_size += 8;
}
vga_bios_size = (vga_bios_size + 0xfff) & ~0xfff;
-
+
if (linux_boot) {
kernel_base = KERNEL_LOAD_ADDR;
/* now we can load the kernel */
kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
kernel_filename);
exit(1);
}
initrd_size = load_image(initrd_filename,
phys_ram_base + initrd_base);
if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+ fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
initrd_filename);
exit(1);
}
if (is_heathrow) {
isa_mem_base = 0x80000000;
-
+
/* Register 2 MB of ISA IO space */
isa_mmio_init(0xfe000000, 0x00200000);
pic = heathrow_pic_init(&heathrow_pic_mem_index);
set_irq = heathrow_pic_set_irq;
pci_bus = pci_grackle_init(0xfec00000, pic);
- pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
+ pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
ram_size, vga_ram_size,
vga_bios_offset, vga_bios_size);
/* XXX: suppress that */
isa_pic = pic_init(pic_irq_request, NULL);
-
+
/* XXX: use Mac Serial port */
serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
-
+
for(i = 0; i < nb_nics; i++) {
if (!nd_table[i].model)
nd_table[i].model = "ne2k_pci";
pci_nic_init(pci_bus, &nd_table[i], -1);
}
-
+
pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
/* cuda also initialize ADB */
cuda_mem_index = cuda_init(set_irq, pic, 0x12);
-
+
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
-
+
{
MacIONVRAMState *nvr;
nvr = macio_nvram_init();
}
macio_init(pci_bus, 0x0017);
-
+
nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
-
+
arch_name = "HEATHROW";
} else {
isa_mem_base = 0x80000000;
-
+
/* Register 8 MB of ISA IO space */
isa_mmio_init(0xf2000000, 0x00800000);
-
+
/* UniN init */
unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL);
cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
/* XXX: suppress that */
isa_pic = pic_init(pic_irq_request, NULL);
-
+
/* XXX: use Mac Serial port */
serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
-
+
for(i = 0; i < nb_nics; i++) {
pci_ne2000_init(pci_bus, &nd_table[i], -1);
}
-
+
#if 1
ide0_mem_index = pmac_ide_init(&bs_table[0], set_irq, pic, 0x13);
ide1_mem_index = pmac_ide_init(&bs_table[2], set_irq, pic, 0x14);
#endif
/* cuda also initialize ADB */
cuda_mem_index = cuda_init(set_irq, pic, 0x19);
-
+
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
-
+
macio_init(pci_bus, 0x0022);
-
+
nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
-
+
arch_name = "MAC99";
}
}
static void ppc_core99_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
+ DisplayState *ds, const char **fd_filename,
int snapshot,
- const char *kernel_filename,
+ const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename)
{
kernel_filename, kernel_cmdline,
initrd_filename, 0);
}
-
+
static void ppc_heathrow_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename,
+ DisplayState *ds, const char **fd_filename,
int snapshot,
- const char *kernel_filename,
+ const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename)
{
/*
* QEMU PPC PREP hardware System Emulator
- *
+ *
* Copyright (c) 2003-2004 Jocelyn Mayer
- *
+ *
* 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
return;
linux_boot = (kernel_filename != NULL);
-
+
/* init CPUs */
env = cpu_init();
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
-
+
/* Register CPU as a 604 */
/* XXX: CPU model (or PVR) should be provided on command line */
// ppc_find_by_name("604r", &def);
exit(1);
}
bios_size = (bios_size + 0xfff) & ~0xfff;
- cpu_register_physical_memory((uint32_t)(-bios_size),
+ cpu_register_physical_memory((uint32_t)(-bios_size),
bios_size, bios_offset | IO_MEM_ROM);
if (linux_boot) {
/* now we can load the kernel */
kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
kernel_filename);
exit(1);
}
initrd_size = load_image(initrd_filename,
phys_ram_base + initrd_base);
if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+ fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
initrd_filename);
exit(1);
}
cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
/* init basic PC hardware */
- pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
+ pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
vga_ram_size, 0, 0);
rtc_init(0x70, 8);
// openpic = openpic_init(0x00000000, 0xF0000000, 1);
* QEMU PREP PCI host
*
* 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
register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
- PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,
+ PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,
PPC_PCIIO_write, s);
cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
- /* PCI host bridge */
- d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven",
+ /* PCI host bridge */
+ d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven",
sizeof(PCIDevice), 0, NULL, NULL);
d->config[0x00] = 0x57; // vendor_id : Motorola
d->config[0x01] = 0x10;
/*
* QEMU PS/2 keyboard/mouse emulation
- *
+ *
* Copyright (c) 2003 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
PS2State *s = (PS2State *)opaque;
PS2Queue *q;
int val, index;
-
+
q = &s->queue;
if (q->count == 0) {
/* NOTE: if no data left, we return the last keyboard one
s->mouse_dz -= dz1;
}
-static void ps2_mouse_event(void *opaque,
+static void ps2_mouse_event(void *opaque,
int dx, int dy, int dz, int buttons_state)
{
PS2MouseState *s = opaque;
s->mouse_buttons == buttons_state)
return;
s->mouse_buttons = buttons_state;
-
+
if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
(s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
for(;;) {
s->mouse_detect_state = 0;
break;
case 2:
- if (val == 80)
+ if (val == 80)
s->mouse_type = 3; /* IMPS/2 */
s->mouse_detect_state = 0;
break;
case 3:
- if (val == 80)
+ if (val == 80)
s->mouse_type = 4; /* IMEX */
s->mouse_detect_state = 0;
break;
-/*
+/*
* ARM RealView Baseboard System emulation.
*
* Copyright (c) 2006 CodeSourcery.
/**
* QEMU RTL8139 emulation
- *
+ *
* Copyright (c) 2006 Igor Kovalenko
- *
+ *
* 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
* 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.
-
+
* Modifications:
* 2006-Jan-28 Mark Malakanov : TSAD and CSCR implementation (for Windows driver)
- *
+ *
* 2006-Apr-28 Juergen Lock : EEPROM emulation changes for FreeBSD driver
* HW revision ID changes for FreeBSD driver
- *
+ *
* 2006-Jul-01 Igor Kovalenko : Implemented loopback mode for FreeBSD driver
* Corrected packet transfer reassembly routine for 8139C+ mode
* Rearranged debugging print statements
CSCR_LinkDownCmd = 0x0f3c0,
*/
enum CSCRBits {
- CSCR_Testfun = 1<<15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */
+ CSCR_Testfun = 1<<15, /* 1 = Auto-neg speeds up internal timer, WO, def 0 */
CSCR_LD = 1<<9, /* Active low TPI link disable signal. When low, TPI still transmits link pulses and TPI stays in good link state. def 1*/
CSCR_HEART_BIT = 1<<8, /* 1 = HEART BEAT enable, 0 = HEART BEAT disable. HEART BEAT function is only valid in 10Mbps mode. def 1*/
CSCR_JBEN = 1<<7, /* 1 = enable jabber function. 0 = disable jabber function, def 1*/
- CSCR_F_LINK_100 = 1<<6, /* Used to login force good link in 100Mbps for diagnostic purposes. 1 = DISABLE, 0 = ENABLE. def 1*/
+ CSCR_F_LINK_100 = 1<<6, /* Used to login force good link in 100Mbps for diagnostic purposes. 1 = DISABLE, 0 = ENABLE. def 1*/
CSCR_F_Connect = 1<<5, /* Assertion of this bit forces the disconnect function to be bypassed. def 0*/
CSCR_Con_status = 1<<3, /* This bit indicates the status of the connection. 1 = valid connected link detected; 0 = disconnected link detected. RO def 0*/
CSCR_Con_status_En = 1<<2, /* Assertion of this bit configures LED1 pin to indicate connection status. def 0*/
uint32_t packet_header = 0;
uint8_t buf1[60];
- static const uint8_t broadcast_macaddr[6] =
+ static const uint8_t broadcast_macaddr[6] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
DEBUG_PRINT((">>> RTL8139: received len=%d\n", size));
++s->tally_counters.RxOkMul;
} else if (s->phys[0] == buf[0] &&
- s->phys[1] == buf[1] &&
- s->phys[2] == buf[2] &&
- s->phys[3] == buf[3] &&
- s->phys[4] == buf[4] &&
+ s->phys[1] == buf[1] &&
+ s->phys[2] == buf[2] &&
+ s->phys[3] == buf[3] &&
+ s->phys[4] == buf[4] &&
s->phys[5] == buf[5]) {
/* match */
if (!(s->RxConfig & AcceptMyPhys))
s->Config3 = 0x1; /* fast back-to-back compatible */
s->Config5 = 0x0;
- s->CSCR = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD;
+ s->CSCR = CSCR_F_LINK_100 | CSCR_HEART_BIT | CSCR_LD;
s->CpCmd = 0x0; /* reset C+ mode */
|((s->TxStatus[2] & TxUnderrun)?TSAD_TUN2:0)
|((s->TxStatus[1] & TxUnderrun)?TSAD_TUN1:0)
|((s->TxStatus[0] & TxUnderrun)?TSAD_TUN0:0)
-
+
|((s->TxStatus[3] & TxAborted )?TSAD_TABT3:0)
|((s->TxStatus[2] & TxAborted )?TSAD_TABT2:0)
|((s->TxStatus[1] & TxAborted )?TSAD_TABT1:0)
|((s->TxStatus[0] & TxAborted )?TSAD_TABT0:0)
-
+
|((s->TxStatus[3] & TxHostOwns )?TSAD_OWN3:0)
|((s->TxStatus[2] & TxHostOwns )?TSAD_OWN2:0)
|((s->TxStatus[1] & TxHostOwns )?TSAD_OWN1:0)
|((s->TxStatus[0] & TxHostOwns )?TSAD_OWN0:0) ;
-
+
DEBUG_PRINT(("RTL8139: TSAD read val=0x%04x\n", ret));
RTL8139State rtl8139;
} PCIRTL8139State;
-static void rtl8139_mmio_map(PCIDevice *pci_dev, int region_num,
+static void rtl8139_mmio_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
PCIRTL8139State *d = (PCIRTL8139State *)pci_dev;
cpu_register_physical_memory(addr + 0, 0x100, s->rtl8139_mmio_io_addr);
}
-static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
+static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
PCIRTL8139State *d = (PCIRTL8139State *)pci_dev;
static inline int64_t rtl8139_get_next_tctr_time(RTL8139State *s, int64_t current_time)
{
- int64_t next_time = current_time +
+ int64_t next_time = current_time +
muldiv64(1, ticks_per_sec, PCI_FREQUENCY);
if (next_time <= current_time)
next_time = current_time + 1;
rtl8139_update_irq(s);
}
- qemu_mod_timer(s->timer,
+ qemu_mod_timer(s->timer,
rtl8139_get_next_tctr_time(s,curr_time));
}
#endif /* RTL8139_ONBOARD_TIMER */
PCIRTL8139State *d;
RTL8139State *s;
uint8_t *pci_conf;
-
+
d = (PCIRTL8139State *)pci_register_device(bus,
"RTL8139", sizeof(PCIRTL8139State),
- devfn,
+ devfn,
NULL, NULL);
pci_conf = d->dev.config;
pci_conf[0x00] = 0xec; /* Realtek 8139 */
s->rtl8139_mmio_io_addr =
cpu_register_io_memory(0, rtl8139_mmio_read, rtl8139_mmio_write, s);
- pci_register_io_region(&d->dev, 0, 0x100,
+ pci_register_io_region(&d->dev, 0, 0x100,
PCI_ADDRESS_SPACE_IO, rtl8139_ioport_map);
- pci_register_io_region(&d->dev, 1, 0x100,
+ pci_register_io_region(&d->dev, 1, 0x100,
PCI_ADDRESS_SPACE_MEM, rtl8139_mmio_map);
s->irq = 16; /* PCI interrupt */
s->cplus_txbuffer = NULL;
s->cplus_txbuffer_len = 0;
s->cplus_txbuffer_offset = 0;
-
+
/* XXX: instance number ? */
register_savevm("rtl8139", 0, 3, rtl8139_save, rtl8139_load, s);
#if RTL8139_ONBOARD_TIMER
s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
- qemu_mod_timer(s->timer,
+ qemu_mod_timer(s->timer,
rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
#endif /* RTL8139_ONBOARD_TIMER */
}
/*
* QEMU 16450 UART emulation
- *
+ *
* Copyright (c) 2003-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
} else {
parity = 'N';
}
- if (s->lcr & 0x04)
+ if (s->lcr & 0x04)
stop_bits = 2;
else
stop_bits = 1;
ssp.stop_bits = stop_bits;
qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
#if 0
- printf("speed=%d parity=%c data=%d stop=%d\n",
+ printf("speed=%d parity=%c data=%d stop=%d\n",
speed, parity, data_bits, stop_bits);
#endif
}
{
SerialState *s = opaque;
unsigned char ch;
-
+
addr &= 7;
#ifdef DEBUG_SERIAL
printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
break_enable = (val >> 6) & 1;
if (break_enable != s->last_break_enable) {
s->last_break_enable = break_enable;
- qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
+ qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
&break_enable);
}
}
default:
case 0:
if (s->lcr & UART_LCR_DLAB) {
- ret = s->divider & 0xff;
+ ret = s->divider & 0xff;
} else {
ret = s->rbr;
s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
/*
* SH7750 device
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
- *
+ *
* 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
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
- *
+ *
* @(#) sh7750_regs.h,v 1.2.4.1 2003/09/04 18:46:00 joel Exp
*/
#ifndef __SH7750_REGS_H__
#define __SH7750_REGS_H__
-/*
- * All register has 2 addresses: in 0xff000000 - 0xffffffff (P4 address) and
+/*
+ * All register has 2 addresses: in 0xff000000 - 0xffffffff (P4 address) and
* in 0x1f000000 - 0x1fffffff (area 7 address)
*/
-#define SH7750_P4_BASE 0xff000000 /* Accessable only in
+#define SH7750_P4_BASE 0xff000000 /* Accessable only in
priveleged mode */
#define SH7750_A7_BASE 0x1f000000 /* Accessable only using TLB */
#define SH7750_P4_REG32(ofs) (SH7750_P4_BASE + (ofs))
#define SH7750_A7_REG32(ofs) (SH7750_A7_BASE + (ofs))
-/*
- * MMU Registers
+/*
+ * MMU Registers
*/
/* Page Table Entry High register - PTEH */
#define SH7750_PTEL_PR_RWPO 0x00000020 /* read-write in priv mode */
#define SH7750_PTEL_PR_ROPU 0x00000040 /* read-only in priv or user mode */
#define SH7750_PTEL_PR_RWPU 0x00000060 /* read-write in priv or user mode */
-#define SH7750_PTEL_C 0x00000008 /* Cacheability
+#define SH7750_PTEL_C 0x00000008 /* Cacheability
(0 - page not cacheable) */
-#define SH7750_PTEL_D 0x00000004 /* Dirty bit (1 - write has been
+#define SH7750_PTEL_D 0x00000004 /* Dirty bit (1 - write has been
performed to a page) */
#define SH7750_PTEL_SH 0x00000002 /* Share Status bit (1 - page are
shared by processes) */
#define SH7750_CCR_A7 SH7750_A7_REG32(SH7750_CCR_REGOFS)
#define SH7750_CCR_IIX 0x00008000 /* IC index enable bit */
-#define SH7750_CCR_ICI 0x00000800 /* IC invalidation bit:
+#define SH7750_CCR_ICI 0x00000800 /* IC invalidation bit:
set it to clear IC */
#define SH7750_CCR_ICE 0x00000100 /* IC enable bit */
#define SH7750_CCR_OIX 0x00000080 /* OC index enable bit */
-#define SH7750_CCR_ORA 0x00000020 /* OC RAM enable bit
- if you set OCE = 0,
+#define SH7750_CCR_ORA 0x00000020 /* OC RAM enable bit
+ if you set OCE = 0,
you should set ORA = 0 */
#define SH7750_CCR_OCI 0x00000008 /* OC invalidation bit */
#define SH7750_CCR_CB 0x00000004 /* Copy-back bit for P1 area */
/* Peripheral Module Interrupts - Memory Refresh Unit (REF) */
#define SH7750_EVT_REF_RCMI 0x580 /* Compare-match Interrupt */
-#define SH7750_EVT_REF_ROVI 0x5A0 /* Refresh Counter Overflow
+#define SH7750_EVT_REF_ROVI 0x5A0 /* Refresh Counter Overflow
interrupt */
/* Peripheral Module Interrupts - Hitachi User Debug Interface (H-UDI) */
#define SH7750_FRQCR SH7750_P4_REG32(SH7750_FRQCR_REGOFS)
#define SH7750_FRQCR_A7 SH7750_A7_REG32(SH7750_FRQCR_REGOFS)
-#define SH7750_FRQCR_CKOEN 0x0800 /* Clock Output Enable
+#define SH7750_FRQCR_CKOEN 0x0800 /* Clock Output Enable
0 - CKIO pin goes to HiZ/pullup
1 - Clock is output from CKIO */
#define SH7750_FRQCR_PLL1EN 0x0400 /* PLL circuit 1 enable */
#define SH7750_BCR1_BREQEN 0x00080000 /* BREQ Enable:
0 - External requests are not
accepted
- 1 - External requests are
+ 1 - External requests are
accepted */
#define SH7750_BCR1_PSHR 0x00040000 /* Partial Sharing Bit:
0 - Master Mode
#define SH7750_MCR_TCAS_1 0x00000000 /* 1 */
#define SH7750_MCR_TCAS_2 0x00800000 /* 2 */
-#define SH7750_MCR_TPC 0x00380000 /* DRAM: RAS Precharge Period
+#define SH7750_MCR_TPC 0x00380000 /* DRAM: RAS Precharge Period
SDRAM: minimum number of cycles
until the next bank active cmd
is output after precharging */
#define SH7750_CHCR_DSA_AMEM16 0x0E000000 /* 16-bit attribute memory space */
#define SH7750_CHCR_DTC 0x01000000 /* Destination Address Wait Control
- Select, specifies CS5 or CS6
+ Select, specifies CS5 or CS6
space wait control for PCMCIA
access */
Address Mode (External Addr
Space -> External Device) */
#define SH7750_CHCR_RS_ER_SA_ED_TO_EA 0x300 /* External Request, Single
- Address Mode, (External
- Device -> External Addr
+ Address Mode, (External
+ Device -> External Addr
Space) */
#define SH7750_CHCR_RS_AR_EA_TO_EA 0x400 /* Auto-Request (External Addr
Space -> External Addr Space) */
#define SH7750_CHCR_RS_AR_EA_TO_OCP 0x500 /* Auto-Request (External Addr
Space -> On-chip Peripheral
Module) */
-#define SH7750_CHCR_RS_AR_OCP_TO_EA 0x600 /* Auto-Request (On-chip
+#define SH7750_CHCR_RS_AR_OCP_TO_EA 0x600 /* Auto-Request (On-chip
Peripheral Module ->
External Addr Space */
#define SH7750_CHCR_RS_SCITX_EA_TO_SC 0x800 /* SCI Transmit-Data-Empty intr
#define SH7750_IPRC_HUDI_S 0
-/*
+/*
* User Break Controller registers
*/
#define SH7750_BARA 0x200000 /* Break address regiser A */
/*
* SHIX 2.0 board description
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
- *
+ *
* 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
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-/*
+/*
Shix 2.0 board by Alexis Polti, described at
http://perso.enst.fr/~polti/realisations/shix20/
/*
* QEMU Sparc SLAVIO interrupt controller emulation
- *
+ *
* Copyright (c) 2003-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
* http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
*
* There is a system master controller and one for each cpu.
- *
+ *
*/
#define MAX_CPUS 16
}
else
DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled);
-
+
for (i = 0; i < MAX_CPUS; i++) {
max = 0;
env = s->cpu_envs[i];
{
SLAVIO_INTCTLState *s = opaque;
int i;
-
+
for (i = 0; i < MAX_CPUS; i++) {
qemu_put_be32s(f, &s->intreg_pending[i]);
}
/*
* QEMU Sparc SLAVIO aux io port 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
/*
* QEMU Sparc SLAVIO serial port emulation
- *
+ *
* Copyright (c) 2003-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
* This is the serial port, mouse and keyboard part of chip STP2001
* (Slave I/O), also produced as NCR89C105. See
* http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
- *
+ *
* The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
* mouse and keyboard ports don't implement all functions and they are
* only asynchronous. There is no DMA.
ChannelState *s = opaque;
SERIOQueue *q = &s->queue;
int val;
-
+
if (q->count == 0) {
return 0;
} else {
}
}
-static void sunmouse_event(void *opaque,
+static void sunmouse_event(void *opaque,
int dx, int dy, int dz, int buttons_state)
{
ChannelState *s = opaque;
* QEMU Sparc SLAVIO timer controller emulation
*
* Copyright (c) 2003-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
* This is the timer/counter part of chip STP2001 (Slave I/O), also
* produced as NCR89C105. See
* http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
- *
+ *
* The 31-bit counter is incremented every 500ns by bit 9. Bits 8..0
* are zero. Bit 31 is 1 when count has been reached.
*
static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id)
{
SLAVIO_TIMERState *s = opaque;
-
+
if (version_id != 1)
return -EINVAL;
/*
* QEMU SMBus API
- *
+ *
* Copyright (c) 2007 Arastra, Inc.
- *
+ *
* 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
/*
* QEMU SMBus EEPROM device
- *
+ *
* Copyright (c) 2007 Arastra, Inc.
- *
+ *
* 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
-/*
+/*
* SMSC 91C111 Ethernet interface emulation
*
* Copyright (c) 2005 CodeSourcery, LLC.
/* Pad short packets. */
if (size < 64) {
int pad;
-
+
if (size & 1)
*(p++) = buf[size - 1];
pad = 64 - size;
}
/* Note: on sparc, the lance 16 bit bus is swapped */
-void ledma_memory_read(void *opaque, target_phys_addr_t addr,
+void ledma_memory_read(void *opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap)
{
DMAState *s = opaque;
}
}
-void ledma_memory_write(void *opaque, target_phys_addr_t addr,
+void ledma_memory_write(void *opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap)
{
DMAState *s = opaque;
/*
* QEMU Sun4m System Emulator
- *
+ *
* Copyright (c) 2003-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
sparc32_dma_set_reset_data(dma, main_esp, main_lance);
prom_offset = ram_size + vram_size;
- cpu_register_physical_memory(PROM_ADDR,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
+ cpu_register_physical_memory(PROM_ADDR,
+ (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
prom_offset | IO_MEM_ROM);
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
ret = load_elf(buf, 0, NULL);
if (ret < 0) {
- fprintf(stderr, "qemu: could not load prom '%s'\n",
+ fprintf(stderr, "qemu: could not load prom '%s'\n",
buf);
exit(1);
}
if (kernel_size < 0)
kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
kernel_filename);
exit(1);
}
if (initrd_filename) {
initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+ fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
initrd_filename);
exit(1);
}
/*
* QEMU Sun4u System Emulator
- *
+ *
* 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
cpu_register_physical_memory(0, ram_size, 0);
prom_offset = ram_size + vga_ram_size;
- cpu_register_physical_memory(PROM_ADDR,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK,
+ cpu_register_physical_memory(PROM_ADDR,
+ (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK,
prom_offset | IO_MEM_ROM);
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
ret = load_elf(buf, 0, NULL);
if (ret < 0) {
- fprintf(stderr, "qemu: could not load prom '%s'\n",
+ fprintf(stderr, "qemu: could not load prom '%s'\n",
buf);
exit(1);
}
if (kernel_size < 0)
kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
kernel_filename);
exit(1);
}
if (initrd_filename) {
initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+ fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
initrd_filename);
exit(1);
}
/*
* QEMU TCX Frame buffer
- *
+ *
* Copyright (c) 2003-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
}
}
-static void tcx_draw_line32(TCXState *s1, uint8_t *d,
+static void tcx_draw_line32(TCXState *s1, uint8_t *d,
const uint8_t *s, int width)
{
int x;
}
}
-static void tcx_draw_line16(TCXState *s1, uint8_t *d,
+static void tcx_draw_line16(TCXState *s1, uint8_t *d,
const uint8_t *s, int width)
{
int x;
}
}
-static void tcx_draw_line8(TCXState *s1, uint8_t *d,
+static void tcx_draw_line8(TCXState *s1, uint8_t *d,
const uint8_t *s, int width)
{
int x;
case 0:
return;
}
-
+
for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) {
if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
if (y_start < 0)
} else {
if (y_start >= 0) {
/* flush to display */
- dpy_update(ts->ds, 0, y_start,
+ dpy_update(ts->ds, 0, y_start,
ts->width, y - y_start);
y_start = -1;
}
}
if (y_start >= 0) {
/* flush to display */
- dpy_update(ts->ds, 0, y_start,
+ dpy_update(ts->ds, 0, y_start,
ts->width, y - y_start);
}
/* reset modified pages */
static void tcx_save(QEMUFile *f, void *opaque)
{
TCXState *s = opaque;
-
+
qemu_put_be32s(f, (uint32_t *)&s->addr);
qemu_put_be32s(f, (uint32_t *)&s->vram);
qemu_put_be16s(f, (uint16_t *)&s->height);
static int tcx_load(QEMUFile *f, void *opaque, int version_id)
{
TCXState *s = opaque;
-
+
if (version_id != 1)
return -EINVAL;
* QEMU Uninorth PCI host (for all Mac99 and newer machines)
*
* 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
s->bus = pci_register_bus(pci_unin_set_irq, pci_unin_map_irq,
pic, 11 << 3, 4);
- pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
+ pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
pci_unin_main_config_write, s);
pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
pci_unin_main_write, s);
cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
- d = pci_register_device(s->bus, "Uni-north main", sizeof(PCIDevice),
+ d = pci_register_device(s->bus, "Uni-north main", sizeof(PCIDevice),
11 << 3, NULL, NULL);
d->config[0x00] = 0x6b; // vendor_id : Apple
d->config[0x01] = 0x10;
#if 0 // XXX: not needed for now
/* Uninorth AGP bus */
s = &pci_bridge[1];
- pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
+ pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
pci_unin_config_write, s);
pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
pci_unin_write, s);
#if 0 // XXX: not needed for now
/* Uninorth internal bus */
s = &pci_bridge[2];
- pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
+ pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
pci_unin_config_write, s);
pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
pci_unin_write, s);
/*
* QEMU USB HID devices
- *
+ *
* 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
0x01, /* u8 bNumInterfaces; (1) */
0x01, /* u8 bConfigurationValue; */
0x04, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
+ 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
0x01, /* u8 if_bInterfaceSubClass; */
0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
0x05, /* u8 if_iInterface; */
-
+
/* HID descriptor */
0x09, /* u8 bLength; */
0x21, /* u8 bDescriptorType; */
0x01, /* u8 bNumInterfaces; (1) */
0x01, /* u8 bConfigurationValue; */
0x04, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
+ 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
};
static const uint8_t qemu_mouse_hid_report_descriptor[] = {
- 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
+ 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
- 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
+ 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
- 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
+ 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
0xC0, 0xC0,
};
0, "QEMU USB Mouse");
s->mouse_grabbed = 1;
}
-
+
dx = int_clamp(s->dx, -128, 127);
dy = int_clamp(s->dy, -128, 127);
dz = int_clamp(s->dz, -128, 127);
s->dx -= dx;
s->dy -= dy;
s->dz -= dz;
-
+
b = 0;
if (s->buttons_state & MOUSE_EVENT_LBUTTON)
b |= 0x01;
b |= 0x02;
if (s->buttons_state & MOUSE_EVENT_MBUTTON)
b |= 0x04;
-
+
buf[0] = b;
buf[1] = dx;
buf[2] = dy;
1, "QEMU USB Tablet");
s->mouse_grabbed = 1;
}
-
+
dz = int_clamp(s->dz, -128, 127);
s->dz -= dz;
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
switch(value >> 8) {
case USB_DT_DEVICE:
- memcpy(data, qemu_mouse_dev_descriptor,
+ 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,
+ 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,
+ memcpy(data, qemu_tablet_config_descriptor,
sizeof(qemu_tablet_config_descriptor));
ret = sizeof(qemu_tablet_config_descriptor);
- }
+ }
break;
case USB_DT_STRING:
switch(value & 0xff) {
switch(value >> 8) {
case 0x22:
if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_hid_report_descriptor,
+ 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,
+ memcpy(data, qemu_tablet_hid_report_descriptor,
sizeof(qemu_tablet_hid_report_descriptor));
ret = sizeof(qemu_tablet_hid_report_descriptor);
}
* 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
0x01, /* u8 bNumInterfaces; (1) */
0x01, /* u8 bConfigurationValue; */
0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
+ 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
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 */
{
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)
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
switch(value >> 8) {
case USB_DT_DEVICE:
- memcpy(data, qemu_hub_dev_descriptor,
+ 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,
+ memcpy(data, qemu_hub_config_descriptor,
sizeof(qemu_hub_config_descriptor));
/* status change endpoint size based on number
case GetHubDescriptor:
{
unsigned int n, limit, var_hub_size = 0;
- memcpy(data, qemu_hub_hub_descriptor,
+ memcpy(data, qemu_hub_hub_descriptor,
sizeof(qemu_hub_hub_descriptor));
data[2] = s->nb_ports;
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_SETUP ||
+ p->pid == USB_TOKEN_OUT ||
p->pid == USB_TOKEN_IN)) {
/* broadcast the packet to the devices */
return usb_hub_broadcast_packet(s, p);
-/*
+/*
* USB Mass Storage Device emulation
*
* Copyright (c) 2006 CodeSourcery.
0x01, /* u8 bNumInterfaces; (1) */
0x01, /* u8 bConfigurationValue; */
0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
+ 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 */
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 */
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
switch(value >> 8) {
case USB_DT_DEVICE:
- memcpy(data, qemu_msd_dev_descriptor,
+ 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,
+ memcpy(data, qemu_msd_config_descriptor,
sizeof(qemu_msd_config_descriptor));
ret = sizeof(qemu_msd_config_descriptor);
break;
/*
* USB UHCI controller 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
/* For simplicity of implementation we only allow a single pending USB
request. This means all usb traffic on this controller is effectively
suspended until that transfer completes. When the transfer completes
- the next transfer from that queue will be processed. However
+ the next transfer from that queue will be processed. However
other queues will not be processed until the next frame. The solution
is to allow multiple pending requests. */
uint32_t async_qh;
static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
{
UHCIState *s = opaque;
-
+
addr &= 0x1f;
switch(addr) {
case 0x0c:
static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
{
UHCIState *s = opaque;
-
+
addr &= 0x1f;
#ifdef DEBUG
printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
dev = port->port.dev;
if (dev) {
/* port reset */
- if ( (val & UHCI_PORT_RESET) &&
+ if ( (val & UHCI_PORT_RESET) &&
!(port->ctrl & UHCI_PORT_RESET) ) {
usb_send_msg(dev, USB_MSG_RESET);
}
UHCIPort *port;
int n;
n = (addr >> 1) & 7;
- if (n >= NB_PORTS)
+ if (n >= NB_PORTS)
goto read_default;
port = &s->ports[n];
val = port->ctrl;
if (td->ctrl & TD_CTRL_IOC) {
*int_mask |= 0x01;
}
-
+
if (!(td->ctrl & TD_CTRL_ACTIVE))
return 1;
if (ret >= 0) {
td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
td->ctrl &= ~TD_CTRL_ACTIVE;
- if (pid == USB_TOKEN_IN &&
+ if (pid == USB_TOKEN_IN &&
(td->ctrl & TD_CTRL_SPD) &&
len < max_len) {
*int_mask |= 0x02;
uhci_update_irq(s);
}
}
- td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
+ td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
(err << TD_CTRL_ERROR_SHIFT);
return 1;
case USB_RET_NAK:
le32_to_cpus(&qh.el_link);
/* Re-process the queue containing the async packet. */
while (1) {
- cpu_physical_memory_read(qh.el_link & ~0xf,
+ cpu_physical_memory_read(qh.el_link & ~0xf,
(uint8_t *)&td, sizeof(td));
le32_to_cpus(&td.link);
le32_to_cpus(&td.ctrl);
/* update the status bits of the TD */
if (old_td_ctrl != td.ctrl) {
val = cpu_to_le32(td.ctrl);
- cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
- (const uint8_t *)&val,
+ cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
+ (const uint8_t *)&val,
sizeof(val));
}
if (ret < 0)
/* update qh element link */
qh.el_link = td.link;
val = cpu_to_le32(qh.el_link);
- cpu_physical_memory_write((link & ~0xf) + 4,
- (const uint8_t *)&val,
+ cpu_physical_memory_write((link & ~0xf) + 4,
+ (const uint8_t *)&val,
sizeof(val));
if (!(qh.el_link & 4))
break;
/* TD */
if (--cnt == 0)
break;
- cpu_physical_memory_read(qh.el_link & ~0xf,
+ cpu_physical_memory_read(qh.el_link & ~0xf,
(uint8_t *)&td, sizeof(td));
le32_to_cpus(&td.link);
le32_to_cpus(&td.ctrl);
/* update the status bits of the TD */
if (old_td_ctrl != td.ctrl) {
val = cpu_to_le32(td.ctrl);
- cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
- (const uint8_t *)&val,
+ cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
+ (const uint8_t *)&val,
sizeof(val));
}
if (ret < 0)
/* update qh element link */
qh.el_link = td.link;
val = cpu_to_le32(qh.el_link);
- cpu_physical_memory_write((link & ~0xf) + 4,
- (const uint8_t *)&val,
+ cpu_physical_memory_write((link & ~0xf) + 4,
+ (const uint8_t *)&val,
sizeof(val));
if (qh.el_link & 4) {
/* depth first */
/* update the status bits of the TD */
if (old_td_ctrl != td.ctrl) {
val = cpu_to_le32(td.ctrl);
- cpu_physical_memory_write((link & ~0xf) + 4,
- (const uint8_t *)&val,
+ cpu_physical_memory_write((link & ~0xf) + 4,
+ (const uint8_t *)&val,
sizeof(val));
}
if (ret < 0)
s->async_qh = 0;
}
/* prepare the timer for the next frame */
- expire_time = qemu_get_clock(vm_clock) +
+ expire_time = qemu_get_clock(vm_clock) +
(ticks_per_sec / FRAME_TIMER_FREQ);
qemu_mod_timer(s->frame_timer, expire_time);
}
-static void uhci_map(PCIDevice *pci_dev, int region_num,
+static void uhci_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
UHCIState *s = (UHCIState *)pci_dev;
pci_conf[0x0e] = 0x00; // header_type
pci_conf[0x3d] = 4; // interrupt pin 3
pci_conf[0x60] = 0x10; // release number
-
+
for(i = 0; i < NB_PORTS; i++) {
qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
}
/* Use region 4 for consistency with real hardware. BSD guests seem
to rely on this. */
- pci_register_io_region(&s->dev, 4, 0x20,
+ pci_register_io_region(&s->dev, 4, 0x20,
PCI_ADDRESS_SPACE_IO, uhci_map);
}
* QEMU USB 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
/**********************/
/* generic USB device helpers (you are not forced to use them when
writing your USB device driver, but they help handling the
- protocol)
+ protocol)
*/
#define SETUP_STATE_IDLE 0
s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
s->setup_index = 0;
if (s->setup_buf[0] & USB_DIR_IN) {
- ret = s->handle_control(s,
+ ret = s->handle_control(s,
(s->setup_buf[0] << 8) | s->setup_buf[1],
(s->setup_buf[3] << 8) | s->setup_buf[2],
(s->setup_buf[5] << 8) | s->setup_buf[4],
case SETUP_STATE_ACK:
if (!(s->setup_buf[0] & USB_DIR_IN)) {
s->setup_state = SETUP_STATE_IDLE;
- ret = s->handle_control(s,
+ ret = s->handle_control(s,
(s->setup_buf[0] << 8) | s->setup_buf[1],
(s->setup_buf[3] << 8) | s->setup_buf[2],
(s->setup_buf[5] << 8) | s->setup_buf[4],
/*
* 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
#define USB_MSG_DETACH 0x101
#define USB_MSG_RESET 0x102
-#define USB_RET_NODEV (-1)
+#define USB_RET_NODEV (-1)
#define USB_RET_NAK (-2)
#define USB_RET_STALL (-3)
#define USB_RET_BABBLE (-4)
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. */
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];
-/*
+/*
* ARM Versatile/PB PCI host controller
*
* Copyright (c) 2006 CodeSourcery.
-/*
+/*
* ARM Versatile Platform/Application Baseboard System emulation.
*
* Copyright (c) 2005-2006 CodeSourcery.
/*
* QEMU VGA Emulator.
- *
+ *
* Copyright (c) 2003 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
break;
case 0x3c1:
index = s->ar_index & 0x1f;
- if (index < 21)
+ if (index < 21)
val = s->ar[index];
else
val = 0;
val = VBE_DISPI_MAX_BPP;
break;
default:
- val = s->vbe_regs[s->vbe_index];
+ val = s->vbe_regs[s->vbe_index];
break;
}
} else {
- val = s->vbe_regs[s->vbe_index];
+ val = s->vbe_regs[s->vbe_index];
}
} else {
val = 0;
case VBE_DISPI_INDEX_BPP:
if (val == 0)
val = 8;
- if (val == 4 || val == 8 || val == 15 ||
+ if (val == 4 || val == 8 || val == 15 ||
val == 16 || val == 24 || val == 32) {
s->vbe_regs[s->vbe_index] = val;
}
!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
int h, shift_control;
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
+ s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
s->vbe_regs[VBE_DISPI_INDEX_XRES];
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
+ s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
s->vbe_regs[VBE_DISPI_INDEX_YRES];
s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
-
+
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
else
- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
+ s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
s->vbe_start_addr = 0;
/* clear the screen (should be done in BIOS) */
if (!(val & VBE_DISPI_NOCLEARMEM)) {
- memset(s->vram_ptr, 0,
+ memset(s->vram_ptr, 0,
s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
}
-
+
/* we initialize the VGA graphic mode (should be done
in BIOS) */
s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
/* height (only meaningful if < 1024) */
h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
s->cr[0x12] = h;
- s->cr[0x07] = (s->cr[0x07] & ~0x42) |
+ s->cr[0x07] = (s->cr[0x07] & ~0x42) |
((h >> 7) & 0x02) | ((h >> 3) & 0x40);
/* line compare to 1023 */
s->cr[0x18] = 0xff;
s->cr[0x07] |= 0x10;
s->cr[0x09] |= 0x40;
-
+
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
shift_control = 0;
s->sr[0x01] &= ~8; /* no double line */
VGAState *s = opaque;
int memory_map_mode, plane;
uint32_t ret;
-
+
/* convert to VGA memory offset */
memory_map_mode = (s->gr[6] >> 2) & 3;
addr &= 0x1ffff;
return 0xff;
break;
}
-
+
if (s->sr[4] & 0x08) {
/* chain 4 mode : simplest access */
ret = s->vram_ptr[addr];
return;
break;
}
-
+
if (s->sr[4] & 0x08) {
/* chain 4 mode : simplest access */
plane = addr & 3;
mask = s->sr[2];
s->plane_updated |= mask; /* only used to detect font change */
write_mask = mask16[mask];
- ((uint32_t *)s->vram_ptr)[addr] =
- (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
+ ((uint32_t *)s->vram_ptr)[addr] =
+ (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
(val & write_mask);
#ifdef DEBUG_VGA_MEM
- printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
+ printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
addr * 4, write_mask, val);
#endif
cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol);
typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
+ const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol, int dup9);
-typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
+typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
const uint8_t *s, int width);
static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
else
v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f);
v = v * 3;
- col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
+ col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
+ c6_to_8(s->palette[v + 1]),
c6_to_8(s->palette[v + 2]));
if (col != palette[i]) {
full_update = 1;
v = 0;
for(i = 0; i < 256; i++) {
if (s->dac_8bit) {
- col = s->rgb_to_pixel(s->palette[v],
- s->palette[v + 1],
+ col = s->rgb_to_pixel(s->palette[v],
+ s->palette[v + 1],
s->palette[v + 2]);
} else {
- col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
+ col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
+ c6_to_8(s->palette[v + 1]),
c6_to_8(s->palette[v + 2]));
}
if (col != palette[i]) {
return full_update;
}
-static void vga_get_offsets(VGAState *s,
- uint32_t *pline_offset,
+static void vga_get_offsets(VGAState *s,
+ uint32_t *pline_offset,
uint32_t *pstart_addr,
uint32_t *pline_compare)
{
line_compare = 65535;
} else
#endif
- {
+ {
/* compute line_offset in bytes */
line_offset = s->cr[0x13];
line_offset <<= 3;
start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
/* line compare */
- line_compare = s->cr[0x18] |
+ line_compare = s->cr[0x18] |
((s->cr[0x07] & 0x10) << 4) |
((s->cr[0x09] & 0x40) << 3);
}
{
int full_update;
uint32_t start_addr, line_offset, line_compare;
-
+
full_update = 0;
s->get_offsets(s, &line_offset, &start_addr, &line_compare);
vga_draw_glyph9_32,
vga_draw_glyph9_32,
};
-
+
static const uint8_t cursor_glyph[32 * 4] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
+};
typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS];
-/*
- * Text mode update
+/*
+ * Text mode update
* Missing:
* - double scan
- * - double width
+ * - double width
* - underline
* - flashing
*/
if (s->ds->dpy_colourdepth != NULL && s->ds->depth != 0)
s->ds->dpy_colourdepth(s->ds, 0);
- s->rgb_to_pixel =
+ s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(s->ds)];
full_update |= update_palette16(s);
palette = s->last_palette;
-
+
/* compute font data address (in plane 2) */
v = s->sr[3];
offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
/* ugly hack for CGA 160x100x16 - explain me the logic */
height = 100;
} else {
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
+ height = s->cr[0x12] |
+ ((s->cr[0x07] & 0x02) << 7) |
((s->cr[0x07] & 0x40) << 3);
height = (height + 1) / cheight;
}
s->cursor_end = s->cr[0xb];
}
cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
-
+
depth_index = get_depth_index(s->ds);
if (cw == 16)
vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
else
vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
-
+
dest = s->ds->data;
linesize = s->ds->linesize;
ch_attr_ptr = s->last_ch_attr;
bgcol = palette[cattr >> 4];
fgcol = palette[cattr & 0x0f];
if (cw != 9) {
- vga_draw_glyph8(d1, linesize,
+ vga_draw_glyph8(d1, linesize,
font_ptr, cheight, fgcol, bgcol);
} else {
dup9 = 0;
if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04))
dup9 = 1;
- vga_draw_glyph9(d1, linesize,
+ vga_draw_glyph9(d1, linesize,
font_ptr, cheight, fgcol, bgcol, dup9);
}
if (src == cursor_ptr &&
h = line_last - line_start + 1;
d = d1 + linesize * line_start;
if (cw != 9) {
- vga_draw_glyph8(d, linesize,
+ vga_draw_glyph8(d, linesize,
cursor_glyph, h, fgcol, bgcol);
} else {
- vga_draw_glyph9(d, linesize,
+ vga_draw_glyph9(d, linesize,
cursor_glyph, h, fgcol, bgcol, 1);
}
}
ch_attr_ptr++;
}
if (cx_max != -1) {
- dpy_update(s->ds, cx_min * cw, cy * cheight,
+ dpy_update(s->ds, cx_min * cw, cy * cheight,
(cx_max - cx_min + 1) * cw, cheight);
}
dest += linesize * cheight;
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
- } else
+ } else
#endif
{
ret = 0;
static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight)
{
int width, height;
-
+
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
- } else
+ } else
#endif
{
width = (s->cr[0x01] + 1) * 8;
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
+ height = s->cr[0x12] |
+ ((s->cr[0x07] & 0x02) << 7) |
((s->cr[0x07] & 0x40) << 3);
height = (height + 1);
}
}
#endif /* !USE_SSE2 */
-/*
+/*
* graphic modes
*/
static void vga_draw_graphic(VGAState *s, int full_update)
ds_depth = s->ds->depth;
depth = s->get_bpp(s);
- if (s->ds->dpy_colourdepth != NULL &&
+ if (s->ds->dpy_colourdepth != NULL &&
(ds_depth != depth || !s->ds->shared_buf))
s->ds->dpy_colourdepth(s->ds, depth);
if (ds_depth != s->ds->depth) full_update = 1;
- s->rgb_to_pixel =
+ s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(s->ds)];
shift_control = (s->gr[0x05] >> 5) & 3;
s->shift_control = shift_control;
s->double_scan = double_scan;
}
-
+
if (shift_control == 0) {
full_update |= update_palette16(s);
if (s->sr[0x01] & 8) {
}
vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
- if (s->line_offset != s->last_line_offset ||
+ if (s->line_offset != s->last_line_offset ||
disp_width != s->last_width ||
height != s->last_height) {
dpy_resize(s->ds, disp_width, height, s->line_offset);
s->last_scr_height = height;
s->last_width = disp_width;
s->last_height = height;
- s->last_line_offset = s->line_offset;
+ s->last_line_offset = s->line_offset;
full_update = 1;
}
if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
if (!s->ds->shared_buf && s->cursor_invalidate)
s->cursor_invalidate(s);
-
+
line_offset = s->line_offset;
#if 0
printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
}
page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
- update = full_update |
+ update = full_update |
cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
if ((page1 - page0) > TARGET_PAGE_SIZE) {
/* if wide line, can use another page */
- update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
+ update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
VGA_DIRTY_FLAG);
}
/* explicit invalidation for the hardware cursor */
} else {
if (y_start >= 0) {
/* flush to display */
- dpy_update(s->ds, 0, y_start,
+ dpy_update(s->ds, 0, y_start,
disp_width, y - y_start);
y_start = -1;
}
}
if (y_start >= 0) {
/* flush to display */
- dpy_update(s->ds, 0, y_start,
+ dpy_update(s->ds, 0, y_start,
disp_width, y - y_start);
}
/* reset modified pages */
/* Disable dirty bit tracking */
xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
- s->rgb_to_pixel =
+ s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(s->ds)];
- if (s->ds->depth == 8)
+ if (s->ds->depth == 8)
val = s->rgb_to_pixel(0, 0, 0);
else
val = 0;
memset(d, val, w);
d += s->ds->linesize;
}
- dpy_update(s->ds, 0, 0,
+ dpy_update(s->ds, 0, 0,
s->last_scr_width, s->last_scr_height);
}
#define GMODE_TEXT 0
#define GMODE_GRAPH 1
-#define GMODE_BLANK 2
+#define GMODE_BLANK 2
static void vga_update_display(void *opaque)
{
static void vga_invalidate_display(void *opaque)
{
VGAState *s = (VGAState *)opaque;
-
+
s->last_width = -1;
s->last_height = -1;
}
qemu_put_byte(f, 0);
#endif
vram_size = s->vram_size;
- qemu_put_be32s(f, &vram_size);
- qemu_put_buffer(f, s->vram_ptr, s->vram_size);
+ qemu_put_be32s(f, &vram_size);
+ qemu_put_buffer(f, s->vram_ptr, s->vram_size);
}
static int vga_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_be32s(f, &vram_size);
if (vram_size != s->vram_size)
return -EINVAL;
- qemu_get_buffer(f, s->vram_ptr, s->vram_size);
+ qemu_get_buffer(f, s->vram_ptr, s->vram_size);
}
/* force refresh */
VGAState vga_state;
} PCIVGAState;
-static void vga_map(PCIDevice *pci_dev, int region_num,
+static void vga_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
PCIVGAState *d = (PCIVGAState *)pci_dev;
0, 0, 170, 170, 170, 0, 0, 170,
0, 170, 170, 85, 0, 170, 170, 170,
85, 85, 85, 85, 85, 255, 85, 255,
- 85, 85, 255, 255, 255, 85, 85, 255,
+ 85, 85, 255, 255, 255, 85, 85, 255,
85, 255, 255, 255, 85, 255, 255, 255,
0, 21, 0, 0, 21, 42, 0, 63,
0, 0, 63, 42, 42, 21, 0, 42,
21, 42, 42, 63, 0, 42, 63, 42,
- 0, 21, 21, 0, 21, 63, 0, 63,
+ 0, 21, 21, 0, 21, 63, 0, 63,
21, 0, 63, 63, 42, 21, 21, 42,
21, 63, 42, 63, 21, 42, 63, 63,
21, 0, 0, 21, 0, 42, 21, 42,
21, 63, 63, 63, 21, 63, 63, 63
};
- s->latch = 0;
+ s->latch = 0;
- s->sr_index = 3;
+ s->sr_index = 3;
s->sr[0] = 3;
s->sr[1] = 0;
s->sr[2] = 3;
s->sr[6] = 0;
s->sr[7] = 0;
- s->gr_index = 5;
+ s->gr_index = 5;
s->gr[0] = 0;
s->gr[1] = 0;
s->gr[2] = 0;
s->ar[19] = 8;
s->ar[20] = 0;
- s->ar_flip_flop = 1;
+ s->ar_flip_flop = 1;
- s->cr_index = 15;
+ s->cr_index = 15;
s->cr[0] = 95;
s->cr[1] = 79;
s->cr[2] = 80;
s->cr[23] = 163;
s->cr[24] = 255;
- s->msr = 103;
- s->fcr = 0;
- s->st00 = 0;
- s->st01 = 0;
+ s->msr = 103;
+ s->fcr = 0;
+ s->st00 = 0;
+ s->st01 = 0;
/* dac_* & palette will be initialized by os through out 0x03c8 &
* out 0c03c9(1:3) */
- s->dac_state = 0;
- s->dac_sub_index = 0;
- s->dac_read_index = 0;
- s->dac_write_index = 16;
+ s->dac_state = 0;
+ s->dac_sub_index = 0;
+ s->dac_read_index = 0;
+ s->dac_write_index = 16;
s->dac_cache[0] = 255;
s->dac_cache[1] = 255;
s->dac_cache[2] = 255;
}
/* when used on xen environment, the vga_ram_base is not used */
-void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
+void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size)
{
int i, j, v, b;
register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s);
register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
+ register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
#else
register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
#endif /* CONFIG_BOCHS_VBE */
vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
+ cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
vga_io_memory);
}
-int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
+int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size)
{
VGAState *s;
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
- cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+ cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
vga_ram_size, vga_ram_offset);
#endif
return 0;
}
-int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
+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)
{
PCIVGAState *d;
VGAState *s;
uint8_t *pci_conf;
-
- d = (PCIVGAState *)pci_register_device(bus, "VGA",
+
+ d = (PCIVGAState *)pci_register_device(bus, "VGA",
sizeof(PCIVGAState),
-1, NULL, NULL);
if (!d)
return -1;
s = &d->vga_state;
-
+
vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
vga_init(s);
s->pci_dev = &d->dev;
-
+
pci_conf = d->dev.config;
pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
pci_conf[0x01] = 0x12;
pci_conf[0x02] = 0x11;
pci_conf[0x03] = 0x11;
- pci_conf[0x0a] = 0x00; // VGA controller
+ pci_conf[0x0a] = 0x00; // VGA controller
pci_conf[0x0b] = 0x03;
pci_conf[0x0e] = 0x00; // header_type
-
+
/* XXX: vga_ram_size must be a power of two */
- pci_register_io_region(&d->dev, 0, vga_ram_size,
+ pci_register_io_region(&d->dev, 0, vga_ram_size,
PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
if (vga_bios_size != 0) {
unsigned int bios_total_size;
bios_total_size = 1;
while (bios_total_size < vga_bios_size)
bios_total_size <<= 1;
- pci_register_io_region(&d->dev, PCI_ROM_SLOT, bios_total_size,
+ pci_register_io_region(&d->dev, PCI_ROM_SLOT, bios_total_size,
PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
}
return 0;
static int vga_save_w, vga_save_h;
-static void vga_save_dpy_update(DisplayState *s,
+static void vga_save_dpy_update(DisplayState *s,
int x, int y, int w, int h)
{
}
{
}
-static int ppm_save(const char *filename, uint8_t *data,
+static int ppm_save(const char *filename, uint8_t *data,
int w, int h, int linesize)
{
FILE *f;
{
VGAState *s = (VGAState *)opaque;
DisplayState *saved_ds, ds1, *ds = &ds1;
-
+
/* XXX: this is a little hackish */
vga_invalidate_display(s);
saved_ds = s->ds;
s->ds = ds;
s->graphic_mode = -1;
vga_update_display(s);
-
+
if (ds->data) {
- ppm_save(filename, ds->data, vga_save_w, vga_save_h,
+ ppm_save(filename, ds->data, vga_save_w, vga_save_h,
s->ds->linesize);
qemu_free(ds->data);
}
/*
* QEMU internal VGA defines.
- *
+ *
* Copyright (c) 2003-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
#define VBE_DISPI_INDEX_X_OFFSET 0x8
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
#define VBE_DISPI_INDEX_NB 0xa
-
+
#define VBE_DISPI_ID0 0xB0C0
#define VBE_DISPI_ID1 0xB0C1
#define VBE_DISPI_ID2 0xB0C2
#define VBE_DISPI_ID3 0xB0C3
#define VBE_DISPI_ID4 0xB0C4
-
+
#define VBE_DISPI_DISABLED 0x00
#define VBE_DISPI_ENABLED 0x01
#define VBE_DISPI_GETCAPS 0x02
#define VBE_DISPI_8BIT_DAC 0x20
#define VBE_DISPI_LFB_ENABLED 0x40
#define VBE_DISPI_NOCLEARMEM 0x80
-
+
#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
#ifdef CONFIG_BOCHS_VBE
return (v << 2) | (b << 1) | b;
}
-void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
+void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size);
uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
void vga_invalidate_scanlines(VGAState *s, int y1, int y2);
-void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
+void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1,
+ int poffset, int w,
unsigned int color0, unsigned int color1,
unsigned int color_xor);
-void vga_draw_cursor_line_16(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
+void vga_draw_cursor_line_16(uint8_t *d1, const uint8_t *src1,
+ int poffset, int w,
unsigned int color0, unsigned int color1,
unsigned int color_xor);
-void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
+void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
+ int poffset, int w,
unsigned int color0, unsigned int color1,
unsigned int color_xor);
/*
* QEMU VGA Emulator templates
- *
+ *
* Copyright (c) 2003 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
#if DEPTH == 8
#define BPP 1
-#define PIXEL_TYPE uint8_t
+#define PIXEL_TYPE uint8_t
#elif DEPTH == 15 || DEPTH == 16
#define BPP 2
-#define PIXEL_TYPE uint16_t
+#define PIXEL_TYPE uint16_t
#elif DEPTH == 32
#define BPP 4
-#define PIXEL_TYPE uint32_t
+#define PIXEL_TYPE uint32_t
#else
#error unsupport depth
#endif
#if DEPTH != 15 && !defined(BGR_FORMAT)
-static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
+static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
uint32_t font_data,
- uint32_t xorcol,
+ uint32_t xorcol,
uint32_t bgcol)
{
#if BPP == 1
uint32_t fgcol, uint32_t bgcol)
{
uint32_t font_data, xorcol;
-
+
xorcol = bgcol ^ fgcol;
do {
font_data = font_ptr[0];
uint32_t fgcol, uint32_t bgcol)
{
uint32_t font_data, xorcol;
-
+
xorcol = bgcol ^ fgcol;
do {
font_data = font_ptr[0];
- glue(vga_draw_glyph_line_, DEPTH)(d,
- expand4to8[font_data >> 4],
+ glue(vga_draw_glyph_line_, DEPTH)(d,
+ expand4to8[font_data >> 4],
xorcol, bgcol);
- glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
- expand4to8[font_data & 0x0f],
+ glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
+ expand4to8[font_data & 0x0f],
xorcol, bgcol);
font_ptr += 4;
d += linesize;
}
static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
+ const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol, int dup9)
{
uint32_t font_data, xorcol, v;
-
+
xorcol = bgcol ^ fgcol;
do {
font_data = font_ptr[0];
((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
else
((uint8_t *)d)[8] = bgcol;
-
+
#elif BPP == 2
cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
} while (--h);
}
-/*
+/*
* 4 color mode
*/
-static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t plane_mask, *palette, data, v;
((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
#endif
-/*
+/*
* 4 color mode, dup2 horizontal
*/
-static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t plane_mask, *palette, data, v;
}
}
-/*
+/*
* 16 color mode
*/
-static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t plane_mask, data, v, *palette;
}
}
-/*
+/*
* 16 color mode, dup2 horizontal
*/
-static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t plane_mask, data, v, *palette;
}
}
-/*
+/*
* 256 color mode, double pixels
*
* XXX: add plane_mask support (never used in standard VGA modes)
*/
-static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t *palette;
}
}
-/*
+/*
* standard 256 color mode
*
* XXX: add plane_mask support (never used in standard VGA modes)
*/
-static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t *palette;
}
}
-void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
- const uint8_t *src1,
+void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
+ const uint8_t *src1,
int poffset, int w,
- unsigned int color0,
+ unsigned int color0,
unsigned int color1,
unsigned int color_xor)
{
/* XXX: optimize */
-/*
+/*
* 15 bit color
*/
-static void glue(vga_draw_line15_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line15_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
#if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
s += 2;
d += BPP;
} while (--w != 0);
-#endif
+#endif
}
-/*
+/*
* 16 bit color
*/
-static void glue(vga_draw_line16_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line16_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
#if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
s += 2;
d += BPP;
} while (--w != 0);
-#endif
+#endif
}
-/*
+/*
* 24 bit color
*/
-static void glue(vga_draw_line24_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line24_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
int w;
} while (--w != 0);
}
-/*
+/*
* 32 bit color
*/
-static void glue(vga_draw_line32_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
+static void glue(vga_draw_line32_, PIXEL_NAME)(VGAState *s1, uint8_t *d,
const uint8_t *s, int width)
{
#if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT)
/*
* QEMU keysym to keycode conversion using rdesktop keymaps
- *
+ *
* Copyright (c) 2004 Johannes Schindelin
- *
+ *
* 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
# Printscreen, Scrollock and Pause
# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
-# but (0xe0, 0x37) seems to work.
+# but (0xe0, 0x37) seems to work.
Print 0xb7 localstate
Sys_Req 0xb7 localstate
Execute 0xb7 localstate
-# rdesktop Swiss-German (de-ch) keymap file
-# 2003-06-03 by noldi@tristar.ch
+# rdesktop Swiss-German (de-ch) keymap file
+# 2003-06-03 by noldi@tristar.ch
#
include common
map 0x00000807
# Scan Code 9
parenleft 0x09 shift
cent 0x09 altgr
-#
+#
# Scan Code 10
parenright 0x0a shift
#
braceright 0x0b altgr inhibit
#
# Scan Code 12
-apostrophe 0x0c
+apostrophe 0x0c
question 0x0c shift
dead_acute 0x0c altgr
#
udiaeresis 0x1a
egrave 0x1a shift
bracketleft 0x1a altgr
-#
+#
# Scan Code 28
dead_diaeresis 0x1b
-exclam 0x1b shift
+exclam 0x1b shift
bracketright 0x1b altgr
#
# Scan Code 40
#
# Scan Code 46
y 0x2c addupper
-#
+#
# Scan Code 53
comma 0x33
semicolon 0x33 shift
-#
+#
# Scan Code 54
period 0x34
colon 0x34 shift
#
# Scan Code 55
-minus 0x35
+minus 0x35
underscore 0x35 shift
#
# Suppress Windows unsupported AltGr keys
# QWERTY first row
#
EuroSign 0x12 altgr
-udiaeresis 0x1a
+udiaeresis 0x1a
Udiaeresis 0x1a shift
-otilde 0x1b
+otilde 0x1b
Otilde 0x1b shift
section 0x1b altgr
#
scaron 0x1f altgr
Scaron 0x1f altgr shift
-odiaeresis 0x27
+odiaeresis 0x27
Odiaeresis 0x27 shift
-adiaeresis 0x28
+adiaeresis 0x28
Adiaeresis 0x28 shift
asciicircum 0x28 altgr
apostrophe 0x2b
#
# QWERTY third row
#
-less 0x56
+less 0x56
greater 0x56 shift
bar 0x56 altgr
zcaron 0x2c altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
-dead_circumflex 0x1a
+dead_circumflex 0x1a
dead_diaeresis 0x1a shift
dead_abovering 0x1a shift altgr
-# 2004-03-16 Halldór Guðmundsson and Morten Lange
+# 2004-03-16 Halldór Guðmundsson and Morten Lange
# Keyboard definition file for the Icelandic keyboard
-# to be used in rdesktop 1.3.x ( See rdesktop.org)
+# to be used in rdesktop 1.3.x ( See rdesktop.org)
# generated from XKB map de, and changed manually
# Location for example /usr/local/share/rdesktop/keymaps/is
include common
#Udiaeresis 0x1a shift
#dead_diaeresis 0x1a altgr
#dead_abovering 0x1a shift altgr
-eth 0x1a
-ETH 0x1a shift
+eth 0x1a
+ETH 0x1a shift
apostrophe 0x1b
question 0x1b shift
#plus 0x1b
#ae 0x1e altgr
#AE 0x1e shift altgr
#eth 0x20 altgr
-#eth 0x20
+#eth 0x20
#ETH 0x20 shift altgr
-#ETH 0x20 shift
+#ETH 0x20 shift
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
kra 0x25 altgr
#adiaeresis 0x27
#Adiaeresis 0x27 shift
-ae 0x27
-AE 0x27 shift
+ae 0x27
+AE 0x27 shift
dead_doubleacute 0x27 altgr
#adiaeresis 0x28
#Adiaeresis 0x28 shift
division 0x34 shift altgr
#minus 0x35
#underscore 0x35 shift
-thorn 0x35
-THORN 0x35 shift
+thorn 0x35
+THORN 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
Control_R 0x9d
Control_L 0x1d
-# Translate Super to Windows keys.
-# This is hardcoded. See documentation for details.
+# Translate Super to Windows keys.
+# This is hardcoded. See documentation for details.
Super_R 0xdb
Super_L 0xdc
-# Translate Menu to the Windows Application key.
+# Translate Menu to the Windows Application key.
Menu 0xdd
greater 0x2b shift
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
-copyright 0x2e altgr
+copyright 0x2e altgr
mu 0x32 altgr
comma 0x33
semicolon 0x33 shift
# QWERTY first row
#
EuroSign 0x12 altgr
-aring 0x1a
+aring 0x1a
Aring 0x1a shift
-dead_diaeresis 0x1b
+dead_diaeresis 0x1b
dead_circumflex 0x1b shift
dead_tilde 0x1b altgr
#
# QWERTY second row
#
-odiaeresis 0x27
+odiaeresis 0x27
Odiaeresis 0x27 shift
-adiaeresis 0x28
+adiaeresis 0x28
Adiaeresis 0x28 shift
apostrophe 0x2b
asterisk 0x2b shift
/*
* KQEMU support
- *
+ *
* Copyright (c) 2005 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
target cpus because they are important for user code. Strictly
speaking, only SSE really matters because the OS must support
it if the user code uses it. */
- critical_features_mask =
- CPUID_CMOV | CPUID_CX8 |
- CPUID_FXSR | CPUID_MMX | CPUID_SSE |
+ critical_features_mask =
+ CPUID_CMOV | CPUID_CX8 |
+ CPUID_FXSR | CPUID_MMX | CPUID_SSE |
CPUID_SSE2 | CPUID_SEP;
ext_features_mask = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR;
if (!is_cpuid_supported()) {
goto fail;
}
- pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *
+ pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *
sizeof(unsigned long));
if (!pages_to_flush)
goto fail;
- ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE *
+ ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE *
sizeof(unsigned long));
if (!ram_pages_to_update)
goto fail;
- modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES *
+ modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES *
sizeof(unsigned long));
if (!modified_ram_pages)
goto fail;
{
int i;
unsigned long page_index;
-
+
for(i = 0; i < nb_modified_ram_pages; i++) {
page_index = modified_ram_pages[i] >> TARGET_PAGE_BITS;
modified_ram_pages_table[page_index] = 0;
if (nb_modified_ram_pages >= KQEMU_MAX_MODIFIED_RAM_PAGES) {
/* flush */
#ifdef _WIN32
- ret = DeviceIoControl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
- &nb_modified_ram_pages,
+ ret = DeviceIoControl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
+ &nb_modified_ram_pages,
sizeof(nb_modified_ram_pages),
NULL, 0, &temp, NULL);
#else
- ret = ioctl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
+ ret = ioctl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
&nb_modified_ram_pages);
#endif
kqemu_reset_modified_ram_pages();
{
int fptag, i, j;
struct fpstate fp1, *fp = &fp1;
-
+
fp->fpuc = env->fpuc;
fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
fptag = 0;
}
asm volatile ("frstor %0" : "=m" (*fp));
}
-
+
static void save_native_fp_fsave(CPUState *env)
{
int fptag, i, j;
struct kqemu_cpu_state *kenv)
{
int selector;
-
+
selector = (env->star >> 32) & 0xffff;
#ifdef __x86_64__
if (env->hflags & HF_LMA_MASK) {
code64 = env->hflags & HF_CS64_MASK;
cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_P_MASK |
DESC_S_MASK |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
+ cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
env->eip = env->lstar;
else
env->eip = env->cstar;
- } else
+ } else
#endif
{
env->regs[R_ECX] = (uint32_t)kenv->next_eip;
-
+
cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
+ cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
}
}
qsort(pr, nb_pc_records, sizeof(PCRecord *), pc_rec_cmp);
-
+
f = fopen("/tmp/kqemu.stats", "w");
if (!f) {
perror("/tmp/kqemu.stats");
for(i = 0; i < nb_pc_records; i++) {
r = pr[i];
sum += r->count;
- fprintf(f, "%08lx: %" PRId64 " %0.2f%% %0.2f%%\n",
- r->pc,
- r->count,
+ fprintf(f, "%08lx: %" PRId64 " %0.2f%% %0.2f%%\n",
+ r->pc,
+ r->count,
(double)r->count / (double)total * 100.0,
(double)sum / (double)total * 100.0);
}
kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
#endif
nb_ram_pages_to_update = 0;
-
+
#if KQEMU_VERSION >= 0x010300
kenv->nb_modified_ram_pages = nb_modified_ram_pages;
#endif
{
unsigned int new_hflags;
#ifdef TARGET_X86_64
- if ((env->hflags & HF_LMA_MASK) &&
+ if ((env->hflags & HF_LMA_MASK) &&
(env->segs[R_CS].flags & DESC_L_MASK)) {
/* long mode */
new_hflags = HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
>> (DESC_B_SHIFT - HF_CS32_SHIFT);
new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
>> (DESC_B_SHIFT - HF_SS32_SHIFT);
- if (!(env->cr[0] & CR0_PE_MASK) ||
+ if (!(env->cr[0] & CR0_PE_MASK) ||
(env->eflags & VM_MASK) ||
!(env->hflags & HF_CS32_MASK)) {
/* XXX: try to avoid this test. The problem comes from the
translate-i386.c. */
new_hflags |= HF_ADDSEG_MASK;
} else {
- new_hflags |= ((env->segs[R_DS].base |
+ new_hflags |= ((env->segs[R_DS].base |
env->segs[R_ES].base |
- env->segs[R_SS].base) != 0) <<
+ env->segs[R_SS].base) != 0) <<
HF_ADDSEG_SHIFT;
}
}
- env->hflags = (env->hflags &
+ env->hflags = (env->hflags &
~(HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)) |
new_hflags;
}
env->hflags |= HF_OSFXSR_MASK;
else
env->hflags &= ~HF_OSFXSR_MASK;
-
+
#ifdef DEBUG
if (loglevel & CPU_LOG_INT) {
fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
if (ret == KQEMU_RET_SYSCALL) {
/* syscall instruction */
return do_syscall(env, kenv);
- } else
+ } else
if ((ret & 0xff00) == KQEMU_RET_INT) {
env->exception_index = ret & 0xff;
env->error_code = 0;
#endif
#ifdef DEBUG
if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: interrupt v=%02x:\n",
+ fprintf(logfile, "kqemu: interrupt v=%02x:\n",
env->exception_index);
cpu_dump_state(env, logfile, fprintf, 0);
}
}
#endif
return 0;
- } else if (ret == KQEMU_RET_SOFTMMU) {
+ } else if (ret == KQEMU_RET_SOFTMMU) {
#ifdef CONFIG_PROFILER
{
unsigned long pc = env->eip + env->segs[R_CS].base;
void kqemu_cpu_interrupt(CPUState *env)
{
#if defined(_WIN32) && KQEMU_VERSION >= 0x010101
- /* cancelling the I/O request causes KQEMU to finish executing the
+ /* cancelling the I/O request causes KQEMU to finish executing the
current block and successfully returning. */
CancelIo(kqemu_fd);
#endif
/*
* KQEMU header
- *
+ *
* Copyright (c) 2004-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
long retval;
/* number of ram_dirty entries to update */
- unsigned int nb_ram_pages_to_update;
+ unsigned int nb_ram_pages_to_update;
#define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512
#define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1)
size = x86_stack_size;
if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
- error = target_mmap(0,
+ error = target_mmap(0,
size + qemu_host_page_size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
size must be known */
if (qemu_real_host_page_size < qemu_host_page_size) {
unsigned long end_addr, end_addr1;
- end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
+ end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
~(qemu_real_host_page_size - 1);
end_addr = HOST_PAGE_ALIGN(elf_bss);
if (end_addr1 < end_addr) {
size *= n;
if (size & 15)
sp -= 16 - (size & 15);
-
+
#define NEW_AUX_ENT(id, val) do { \
sp -= n; tputl(sp, val); \
sp -= n; tputl(sp, id); \
if (k_platform)
NEW_AUX_ENT(AT_PLATFORM, u_platform);
#ifdef ARCH_DLINFO
- /*
+ /*
* ARCH_DLINFO must come last so platform specific code can enforce
* special alignment requirements on the AUXV if necessary (eg. PPC).
*/
unsigned long last_bss, elf_bss;
unsigned long error;
int i;
-
+
elf_bss = 0;
last_bss = 0;
error = 0;
bswap_ehdr(interp_elf_ex);
#endif
/* First of all, some simple consistency checks */
- if ((interp_elf_ex->e_type != ET_EXEC &&
- interp_elf_ex->e_type != ET_DYN) ||
+ if ((interp_elf_ex->e_type != ET_EXEC &&
+ interp_elf_ex->e_type != ET_DYN) ||
!elf_check_arch(interp_elf_ex->e_machine)) {
return ~0UL;
}
-
+
/* Now read in all of the header information */
-
+
if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
return ~0UL;
-
- elf_phdata = (struct elf_phdr *)
+
+ elf_phdata = (struct elf_phdr *)
malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
if (!elf_phdata)
return ~0UL;
-
+
/*
* If the size of this structure has changed, then punt, since
* we will be doing the wrong thing.
/* in order to avoid hardcoding the interpreter load
address in qemu, we allocate a big enough memory zone */
error = target_mmap(0, INTERP_MAP_SIZE,
- PROT_NONE, MAP_PRIVATE | MAP_ANON,
+ PROT_NONE, MAP_PRIVATE | MAP_ANON,
-1, 0);
if (error == -1) {
perror("mmap");
elf_type,
interpreter_fd,
eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
-
+
if (error == -1) {
/* Real error */
close(interpreter_fd);
k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
if (k > last_bss) last_bss = k;
}
-
+
/* Now use mmap to map the library into memory. */
close(interpreter_fd);
s->disas_strtab = strings = malloc(strtab.sh_size);
if (!s->disas_symtab || !s->disas_strtab)
return;
-
+
lseek(fd, symtab.sh_offset, SEEK_SET);
if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
return;
retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
if(retval > 0) {
- retval = read(bprm->fd, (char *) elf_phdata,
+ retval = read(bprm->fd, (char *) elf_phdata,
elf_ex.e_phentsize * elf_ex.e_phnum);
}
if(retval < 0) {
perror("load_elf_binary2");
exit(-1);
- }
+ }
/* If the program interpreter is one of these two,
then assume an iBCS2 image. Otherwise assume
int elf_prot = 0;
int elf_flags = 0;
unsigned long error;
-
+
if (elf_ppnt->p_type != PT_LOAD)
continue;
-
+
if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
/* NOTE: for qemu, we do a big mmap to get enough space
without hardcoding any address */
error = target_mmap(0, ET_DYN_MAP_SIZE,
- PROT_NONE, MAP_PRIVATE | MAP_ANON,
+ PROT_NONE, MAP_PRIVATE | MAP_ANON,
-1, 0);
if (error == -1) {
perror("mmap");
}
load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
}
-
+
error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
(elf_ppnt->p_filesz +
TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
elf_prot,
(MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
bprm->fd,
- (elf_ppnt->p_offset -
+ (elf_ppnt->p_offset -
TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
if (error == -1) {
perror("mmap");
if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
#endif
-
+
if (!load_addr_set) {
load_addr_set = 1;
load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
}
}
k = elf_ppnt->p_vaddr;
- if (k < start_code)
+ if (k < start_code)
start_code = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
- if (k > elf_bss)
+ if (k > elf_bss)
elf_bss = k;
if ((elf_ppnt->p_flags & PF_X) && end_code < k)
end_code = k;
- if (end_data < k)
+ if (end_data < k)
end_data = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
if (k > elf_brk) elf_brk = k;
target_ulong reloc_start; /* Offset of relocation records from
beginning of file */
target_ulong reloc_count; /* Number of relocation records */
- target_ulong flags;
+ target_ulong flags;
target_ulong build_date; /* When the program/library was built */
target_ulong filler[5]; /* Reservered, set to zero */
};
"(address %p, currently %x) into segment %s\n",
offset, ptr, (int)*ptr, segment[reloc_type]);
#endif
-
+
switch (reloc_type) {
case OLD_FLAT_RELOC_TYPE_TEXT:
*ptr += libinfo->start_code;
break;
}
DBG_FLT("Relocation became %x\n", (int)*ptr);
-}
+}
/****************************************************************************/
rev, (int) FLAT_VERSION);
return -ENOEXEC;
}
-
+
/* Don't allow old format executables to use shared libraries */
if (rev == OLD_FLAT_VERSION && id != 0) {
fprintf(stderr, "BINFMT_FLAT: shared libraries are not available\n");
textpos = target_mmap(0, text_len, PROT_READ|PROT_EXEC,
MAP_PRIVATE, bprm->fd, 0);
- if (textpos == -1) {
+ if (textpos == -1) {
fprintf(stderr, "Unable to mmap process text\n");
return -1;
}
fpos = ntohl(hdr->data_start);
#ifdef CONFIG_BINFMT_ZFLAT
if (flags & FLAT_FLAG_GZDATA) {
- result = decompress_exec(bprm, fpos, (char *) datapos,
+ result = decompress_exec(bprm, fpos, (char *) datapos,
data_len + (relocs * sizeof(target_ulong)))
} else
#endif
libinfo[id].loaded = 1;
libinfo[id].entry = (0x00ffffff & ntohl(hdr->entry)) + textpos;
libinfo[id].build_date = ntohl(hdr->build_date);
-
+
/*
* We just load the allocations into some temporary memory to
* help simplify all this mumbo jumbo
old_reloc(&libinfo[0], relval);
}
}
-
+
/* zero the BSS. */
memset((void*)(datapos + data_len), 0, bss_len);
stack_len += (bprm->argc + 1) * 4; /* the argv array */
stack_len += (bprm->envc + 1) * 4; /* the envp array */
-
+
res = load_flat_file(bprm, libinfo, 0, &stack_len);
if (res > (unsigned long)-4096)
return res;
-
+
/* Update data segment pointers for all libraries */
for (i=0; i<MAX_SHARED_LIBS; i++) {
if (libinfo[i].loaded) {
/* Align stack. */
sp = p & ~(target_ulong)(sizeof(target_ulong) - 1);
sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, 1);
-
+
/* Fake some return addresses to ensure the call chain will
* initialise library in order for us. We are required to call
* lib 1 first, then 2, ... and finally the main program (id 0).
}
}
#endif
-
+
/* Stash our initial stack pointer into the mm structure */
info->start_code = libinfo[0].start_code;
info->end_code = libinfo[0].start_code = libinfo[0].text_len;
DBG_FLT("start_thread(entry=0x%x, start_stack=0x%x)\n",
(int)info->entry, (int)info->start_stack);
-
+
return 0;
}
#define TARGET_SEMOP 1
#define TARGET_SEMGET 2
-#define TARGET_SEMCTL 3
-#define TARGET_MSGSND 11
+#define TARGET_SEMCTL 3
+#define TARGET_MSGSND 11
#define TARGET_MSGRCV 12
#define TARGET_MSGGET 13
#define TARGET_MSGCTL 14
struct target_ipc_kludge {
unsigned int msgp; /* Really (struct msgbuf *) */
int msgtyp;
-};
+};
struct target_ipc_perm {
int key;
return sp;
}
-int loader_exec(const char * filename, char ** argv, char ** envp,
+int loader_exec(const char * filename, char ** argv, char ** envp,
struct target_pt_regs * regs, struct image_info *infop)
{
struct linux_binprm bprm;
return -1;
}
}
-
+
if(retval>=0) {
/* success. Initialize important registers */
do_init_thread(regs, infop);
/*
* m68k/ColdFire Semihosting ssycall interface
- *
+ *
* Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook.
*
* This program is free software; you can redistribute it and/or modify
/*
* m68k simulator syscall interface
- *
+ *
* Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook.
*
* This program is free software; you can redistribute it and/or modify
/*
* qemu user main
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
return cpu_get_real_ticks();
}
-static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
+static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
int flags)
{
unsigned int e1, e2;
p[1] = tswapl(e2);
}
-static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
+static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
unsigned long addr, unsigned int sel)
{
unsigned int e1, e2;
switch(trapnr) {
case 0x80:
/* linux syscall */
- env->regs[R_EAX] = do_syscall(env,
- env->regs[R_EAX],
+ env->regs[R_EAX] = do_syscall(env,
+ env->regs[R_EAX],
env->regs[R_EBX],
env->regs[R_ECX],
env->regs[R_EDX],
break;
default:
pc = env->segs[R_CS].base + env->eip;
- fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
+ fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
(long)pc, trapnr);
abort();
}
unsigned int n, insn;
target_siginfo_t info;
uint32_t addr;
-
+
for(;;) {
trapnr = cpu_arm_exec(env);
switch(trapnr) {
/* we handle the FPU emulation here, as Linux */
/* we get the opcode */
opcode = tget32(env->regs[15]);
-
+
if (EmulateAll(opcode, &ts->fpa, env) == 0) {
info.si_signo = SIGILL;
info.si_errno = 0;
n -= ARM_SYSCALL_BASE;
env->eabi = 0;
}
- env->regs[0] = do_syscall(env,
- n,
+ env->regs[0] = do_syscall(env,
+ n,
env->regs[0],
env->regs[1],
env->regs[2],
break;
default:
error:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
+ fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
abort();
{
unsigned int i;
target_ulong sp_ptr;
-
+
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
#if defined(DEBUG_WIN)
- printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",
+ printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",
(int)sp_ptr, cwp1);
#endif
for(i = 0; i < 16; i++) {
{
unsigned int new_wim, i, cwp1;
target_ulong sp_ptr;
-
+
new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
((1LL << NWINDOWS) - 1);
-
+
/* restore the invalid window */
cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
#if defined(DEBUG_WIN)
- printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
+ printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
(int)sp_ptr, cwp1);
#endif
for(i = 0; i < 16; i++) {
{
int trapnr, ret;
target_siginfo_t info;
-
+
while (1) {
trapnr = cpu_sparc_exec (env);
-
+
switch (trapnr) {
#ifndef TARGET_SPARC64
- case 0x88:
+ case 0x88:
case 0x90:
#else
case 0x16d:
#endif
ret = do_syscall (env, env->gregs[1],
- env->regwptr[0], env->regwptr[1],
- env->regwptr[2], env->regwptr[3],
+ env->regwptr[0], env->regwptr[1],
+ env->regwptr[2], env->regwptr[3],
env->regwptr[4], env->regwptr[5]);
if ((unsigned int)ret >= (unsigned int)(-515)) {
#ifdef TARGET_SPARC64
/* TO FIX */
return 0;
}
-
+
uint32_t cpu_ppc_load_tbl (CPUState *env)
{
return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
}
-
+
uint32_t cpu_ppc_load_tbu (CPUState *env)
{
return cpu_ppc_get_tb(env) >> 32;
}
-
+
static void cpu_ppc_store_tb (CPUState *env, uint64_t value)
{
/* TO FIX */
{
cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
}
-
+
void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
{
cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);
}
-
+
uint32_t cpu_ppc_load_decr (CPUState *env)
{
/* TO FIX */
return -1;
}
-
+
void cpu_ppc_store_decr (CPUState *env, uint32_t value)
{
/* TO FIX */
}
-
+
void cpu_loop(CPUPPCState *env)
{
target_siginfo_t info;
int trapnr;
uint32_t ret;
-
+
for(;;) {
trapnr = cpu_ppc_exec(env);
if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH &&
}
break;
default:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
+ fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
if (loglevel) {
fprintf(logfile, "qemu: unhandled CPU exception 0x%02x - "
arg5 = 0;
arg6 = 0;
}
- ret = do_syscall(env,
- env->gpr[2],
+ ret = do_syscall(env,
+ env->gpr[2],
env->gpr[4],
env->gpr[5],
env->gpr[6],
env->gpr[7],
- arg5,
+ arg5,
arg6);
}
if ((unsigned int)ret >= (unsigned int)(-1133)) {
break;
default:
// error:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
+ fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
abort();
{
int trapnr, ret;
target_siginfo_t info;
-
+
while (1) {
trapnr = cpu_sh4_exec (env);
-
+
switch (trapnr) {
case 0x160:
- ret = do_syscall(env,
- env->gregs[3],
- env->gregs[4],
- env->gregs[5],
- env->gregs[6],
- env->gregs[7],
- env->gregs[0],
+ ret = do_syscall(env,
+ env->gregs[3],
+ env->gregs[4],
+ env->gregs[5],
+ env->gregs[6],
+ env->gregs[7],
+ env->gregs[0],
0);
env->gregs[0] = ret;
env->pc += 2;
unsigned int n;
target_siginfo_t info;
TaskState *ts = env->opaque;
-
+
for(;;) {
trapnr = cpu_m68k_exec(env);
switch(trapnr) {
ts->sim_syscalls = 0;
n = env->dregs[0];
env->pc += 2;
- env->dregs[0] = do_syscall(env,
- n,
+ env->dregs[0] = do_syscall(env,
+ n,
env->dregs[1],
env->dregs[2],
env->dregs[3],
}
break;
default:
- fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
+ fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
abort();
"-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n",
TARGET_ARCH,
- interp_prefix,
+ interp_prefix,
x86_stack_size,
DEBUG_LOGFILE);
_exit(1);
int optind;
const char *r;
int gdbstub_port = 0;
-
+
if (argc <= 1)
usage();
if (optind >= argc)
break;
-
+
r = argv[optind++];
mask = cpu_str_to_log_mask(r);
if (!mask) {
gdbstub_port = atoi(argv[optind++]);
} else if (!strcmp(r, "r")) {
qemu_uname_release = argv[optind++];
- } else
+ } else
#ifdef USE_CODE_COPY
if (!strcmp(r, "no-code-copy")) {
code_copy_enabled = 0;
- } else
+ } else
#endif
{
usage();
qemu_host_page_size */
env = cpu_init();
global_env = env;
-
+
if (loader_exec(filename, argv+optind, environ, regs, info) != 0) {
printf("Error loading %s\n", filename);
_exit(1);
}
-
+
if (loglevel) {
page_dump(logfile);
-
+
fprintf(logfile, "start_brk 0x%08lx\n" , info->start_brk);
fprintf(logfile, "end_code 0x%08lx\n" , info->end_code);
fprintf(logfile, "start_code 0x%08lx\n" , info->start_code);
ts->used = 1;
ts->info = info;
env->user_mode_only = 1;
-
+
#if defined(TARGET_I386)
cpu_x86_set_cpl(env, 3);
/* flags setup : we activate the IRQs by default as in user mode */
env->eflags |= IF_MASK;
-
+
/* linux register setup */
env->regs[R_EAX] = regs->eax;
env->regs[R_EBX] = regs->ebx;
env->gdt.base = h2g(gdt_table);
env->gdt.limit = sizeof(gdt_table) - 1;
write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+ DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
(3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+ DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
(3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
cpu_x86_load_seg(env, R_CS, __USER_CS);
cpu_x86_load_seg(env, R_DS, __USER_DS);
/*
* mmap support for qemu
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
return -EINVAL;
if (len == 0)
return 0;
-
+
host_start = start & qemu_host_page_mask;
host_end = HOST_PAGE_ALIGN(end);
if (start > host_start) {
for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr);
}
- ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size,
+ ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size,
prot1 & PAGE_BITS);
if (ret != 0)
return ret;
host_end -= qemu_host_page_size;
}
-
+
/* handle the pages in the middle */
if (host_start < host_end) {
ret = mprotect(g2h(host_start), host_end - host_start, prot);
}
/* map an incomplete host page */
-static int mmap_frag(target_ulong real_start,
- target_ulong start, target_ulong end,
+static int mmap_frag(target_ulong real_start,
+ target_ulong start, target_ulong end,
int prot, int flags, int fd, target_ulong offset)
{
target_ulong real_end, ret, addr;
if (addr < start || addr >= end)
prot1 |= page_get_flags(addr);
}
-
+
if (prot1 == 0) {
/* no page was there, so we allocate one */
- ret = (long)mmap(host_start, qemu_host_page_size, prot,
+ ret = (long)mmap(host_start, qemu_host_page_size, prot,
flags | MAP_ANONYMOUS, -1, 0);
if (ret == -1)
return ret;
/* adjust protection to be able to read */
if (!(prot1 & PROT_WRITE))
mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
-
+
/* read the corresponding file data */
pread(fd, g2h(start), end - start, offset);
-
+
/* put final protection */
if (prot_new != (prot1 | PROT_WRITE))
mprotect(host_start, qemu_host_page_size, prot_new);
}
/* NOTE: all the constants are the HOST ones */
-long target_mmap(target_ulong start, target_ulong len, int prot,
+long target_mmap(target_ulong start, target_ulong len, int prot,
int flags, int fd, target_ulong offset)
{
target_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
#ifdef DEBUG_MMAP
{
printf("mmap: start=0x%lx len=0x%lx prot=%c%c%c flags=",
- start, len,
+ start, len,
prot & PROT_READ ? 'r' : '-',
prot & PROT_WRITE ? 'w' : '-',
prot & PROT_EXEC ? 'x' : '-');
/* ??? This needs fixing for remapping. */
abort();
host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE;
- real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE,
+ real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (real_start == -1)
return real_start;
if (host_start == -1)
return host_start;
/* update start so that it points to the file position at 'offset' */
- if (!(flags & MAP_ANONYMOUS))
+ if (!(flags & MAP_ANONYMOUS))
host_start += offset - host_offset;
start = h2g(host_start);
goto the_end1;
}
}
-
+
if (start & ~TARGET_PAGE_MASK) {
errno = EINVAL;
return -1;
errno = EINVAL;
return -1;
}
- retaddr = target_mmap(start, len, prot | PROT_WRITE,
- MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
+ retaddr = target_mmap(start, len, prot | PROT_WRITE,
+ MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (retaddr == -1)
return retaddr;
}
/* handle the end of the mapping */
if (end < real_end) {
- ret = mmap_frag(real_end - qemu_host_page_size,
+ ret = mmap_frag(real_end - qemu_host_page_size,
real_end - qemu_host_page_size, real_end,
- prot, flags, fd,
+ prot, flags, fd,
offset + real_end - qemu_host_page_size - start);
if (ret == -1)
return ret;
real_end -= qemu_host_page_size;
}
-
+
/* map the middle (easier) */
if (real_start < real_end) {
unsigned long offset1;
offset1 = 0;
else
offset1 = offset + real_start - start;
- ret = (long)mmap(g2h(real_start), real_end - real_start,
+ ret = (long)mmap(g2h(real_start), real_end - real_start,
prot, flags, fd, offset1);
if (ret == -1)
return ret;
if (prot != 0)
real_end -= qemu_host_page_size;
}
-
+
/* unmap what we can */
if (real_start < real_end) {
ret = munmap((void *)real_start, real_end - real_start);
/* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED
blocks which have been allocated starting on a host page */
-long target_mremap(target_ulong old_addr, target_ulong old_size,
+long target_mremap(target_ulong old_addr, target_ulong old_size,
target_ulong new_size, unsigned long flags,
target_ulong new_addr)
{
return -EINVAL;
if (end == start)
return 0;
-
+
start &= qemu_host_page_mask;
return msync(g2h(start), end - start, flags);
}
/*
* PPC emulation for qemu: syscall definitions.
- *
+ *
* Copyright (c) 2003 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
#define TARGET_SEMOP 1
#define TARGET_SEMGET 2
-#define TARGET_SEMCTL 3
-#define TARGET_MSGSND 11
+#define TARGET_SEMCTL 3
+#define TARGET_MSGSND 11
#define TARGET_MSGRCV 12
#define TARGET_MSGGET 13
#define TARGET_MSGCTL 14
struct target_ipc_kludge {
unsigned int msgp; /* Really (struct msgbuf *) */
int msgtyp;
-};
+};
struct target_ipc_perm {
int key;
#define MAX_ARG_PAGES 32
/*
- * This structure is used to hold the arguments that are
+ * This structure is used to hold the arguments that are
* used when loading binaries.
*/
struct linux_binprm {
void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
target_ulong loader_build_argptr(int envc, int argc, target_ulong sp,
target_ulong stringp, int push_ptr);
-int loader_exec(const char * filename, char ** argv, char ** envp,
+int loader_exec(const char * filename, char ** argv, char ** envp,
struct target_pt_regs * regs, struct image_info *infop);
int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
void target_set_brk(target_ulong new_brk);
long do_brk(target_ulong new_brk);
void syscall_init(void);
-long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
+long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6);
void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
extern CPUState *global_env;
/* mmap.c */
int target_mprotect(target_ulong start, target_ulong len, int prot);
-long target_mmap(target_ulong start, target_ulong len, int prot,
+long target_mmap(target_ulong start, target_ulong len, int prot,
int flags, int fd, target_ulong offset);
int target_munmap(target_ulong start, target_ulong len);
-long target_mremap(target_ulong old_addr, target_ulong old_size,
+long target_mremap(target_ulong old_addr, target_ulong old_size,
target_ulong new_size, unsigned long flags,
target_ulong new_addr);
int target_msync(target_ulong start, target_ulong len, int flags);
ndbreak() */
#define TARGET_TIOCSBRK TARGET_IO('T', 39) /* 0x5427 */ /* BSD compatibility */
#define TARGET_TIOCCBRK TARGET_IO('T', 40) /* 0x5428 */ /* BSD compatibility */
-#define TARGET_TIOCGSID TARGET_IOR('T', 41, pid_t) /* 0x5429 */ /* Return the session
+#define TARGET_TIOCGSID TARGET_IOR('T', 41, pid_t) /* 0x5429 */ /* Return the session
ID of FD */
#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-m
ux device) */
tus register */
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-#define TARGET_TIOCSERGETMULTI TARGET_IOR('T', 90, int) /* 0x545A
+#define TARGET_TIOCSERGETMULTI TARGET_IOR('T', 90, int) /* 0x545A
*/ /* Get multiport config */
-#define TARGET_TIOCSERSETMULTI TARGET_IOW('T', 91, int) /* 0x545B
+#define TARGET_TIOCSERSETMULTI TARGET_IOW('T', 91, int) /* 0x545B
*/ /* Set multiport config */
-#define TARGET_TIOCMIWAIT TARGET_IO('T', 92) /* 0x545C */ /* wait for a change on
+#define TARGET_TIOCMIWAIT TARGET_IO('T', 92) /* 0x545C */ /* wait for a change on
serial input line(s) */
-#define TARGET_TIOCGICOUNT TARGET_IOR('T', 93, int) /* 0x545D */ /* read
+#define TARGET_TIOCGICOUNT TARGET_IOR('T', 93, int) /* 0x545D */ /* read
serial port inline interrupt counts */
/*
* Emulation of Linux signals
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
static struct sigqueue *first_free; /* first free siginfo queue entry */
static int signal_pending; /* non zero if a signal may be pending */
-static void host_signal_handler(int host_signum, siginfo_t *info,
+static void host_signal_handler(int host_signum, siginfo_t *info,
void *puc);
static uint8_t host_to_target_signal_table[65] = {
return target_to_host_signal_table[sig];
}
-static void host_to_target_sigset_internal(target_sigset_t *d,
+static void host_to_target_sigset_internal(target_sigset_t *d,
const sigset_t *s)
{
int i;
unsigned long sigmask;
uint32_t target_sigmask;
-
+
sigmask = ((unsigned long *)s)[0];
target_sigmask = 0;
for(i = 0; i < 32; i++) {
- if (sigmask & (1 << i))
+ if (sigmask & (1 << i))
target_sigmask |= 1 << (host_to_target_signal(i + 1) - 1);
}
#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
target_sigmask = s->sig[0];
sigmask = 0;
for(i = 0; i < 32; i++) {
- if (target_sigmask & (1 << i))
+ if (target_sigmask & (1 << i))
sigmask |= 1 << (target_to_host_signal(i + 1) - 1);
}
#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
s1.sig[i] = tswapl(s->sig[i]);
target_to_host_sigset_internal(d, &s1);
}
-
-void host_to_target_old_sigset(target_ulong *old_sigset,
+
+void host_to_target_old_sigset(target_ulong *old_sigset,
const sigset_t *sigset)
{
target_sigset_t d;
*old_sigset = d.sig[0];
}
-void target_to_host_old_sigset(sigset_t *sigset,
+void target_to_host_old_sigset(sigset_t *sigset,
const target_ulong *old_sigset)
{
target_sigset_t d;
/* siginfo conversion */
-static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
+static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
const siginfo_t *info)
{
int sig;
tinfo->si_signo = sig;
tinfo->si_errno = 0;
tinfo->si_code = 0;
- if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
+ if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGTRAP) {
/* should never come here, but who knows. The information for
the target is irrelevant */
tinfo->_sifields._rt._pid = info->si_pid;
tinfo->_sifields._rt._uid = info->si_uid;
/* XXX: potential problem if 64 bit */
- tinfo->_sifields._rt._sigval.sival_ptr =
+ tinfo->_sifields._rt._sigval.sival_ptr =
(target_ulong)info->si_value.sival_ptr;
}
}
-static void tswap_siginfo(target_siginfo_t *tinfo,
+static void tswap_siginfo(target_siginfo_t *tinfo,
const target_siginfo_t *info)
{
int sig;
tinfo->si_signo = tswap32(sig);
tinfo->si_errno = tswap32(info->si_errno);
tinfo->si_code = tswap32(info->si_code);
- if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
+ if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGTRAP) {
- tinfo->_sifields._sigfault._addr =
+ tinfo->_sifields._sigfault._addr =
tswapl(info->_sifields._sigfault._addr);
} else if (sig >= TARGET_SIGRTMIN) {
tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
- tinfo->_sifields._rt._sigval.sival_ptr =
+ tinfo->_sifields._rt._sigval.sival_ptr =
tswapl(info->_sifields._rt._sigval.sival_ptr);
}
}
info->si_code = tswap32(tinfo->si_code);
info->si_pid = tswap32(tinfo->_sifields._rt._pid);
info->si_uid = tswap32(tinfo->_sifields._rt._uid);
- info->si_value.sival_ptr =
+ info->si_value.sival_ptr =
(void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
}
j = host_to_target_signal_table[i];
target_to_host_signal_table[j] = i;
}
-
+
/* set all host signal handlers. ALL signals are blocked during
the handlers to serialize them. */
sigfillset(&act.sa_mask);
for(i = 1; i < NSIG; i++) {
sigaction(i, &act, NULL);
}
-
+
memset(sigact_table, 0, sizeof(sigact_table));
first_free = &sigqueue_table[0];
- for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
+ for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
sigqueue_table[i].next = &sigqueue_table[i + 1];
sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
}
{
int host_sig;
host_sig = target_to_host_signal(sig);
- fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
+ fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
sig, strsignal(host_sig));
#if 1
_exit(-host_sig);
target_ulong handler;
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "queue_signal: sig=%d\n",
+ fprintf(stderr, "queue_signal: sig=%d\n",
sig);
#endif
k = &sigact_table[sig - 1];
handler = k->sa._sa_handler;
if (handler == TARGET_SIG_DFL) {
/* default handler : ignore some signal. The other are fatal */
- if (sig != TARGET_SIGCHLD &&
- sig != TARGET_SIGURG &&
+ if (sig != TARGET_SIGCHLD &&
+ sig != TARGET_SIGURG &&
sig != TARGET_SIGWINCH) {
force_sig(sig);
} else {
}
}
-static void host_signal_handler(int host_signum, siginfo_t *info,
+static void host_signal_handler(int host_signum, siginfo_t *info,
void *puc)
{
int sig;
/* the CPU emulator uses some host signals to detect exceptions,
we we forward to it some signals */
- if (host_signum == SIGSEGV || host_signum == SIGBUS
+ if (host_signum == SIGSEGV || host_signum == SIGBUS
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
|| host_signum == SIGFPE
#endif
return -EINVAL;
k = &sigact_table[sig - 1];
#if defined(DEBUG_SIGNAL)
- fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
+ fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
sig, (int)act, (int)oact);
#endif
if (oact) {
#define offsetof(type, field) ((size_t) &((type *)0)->field)
#endif
-static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
+static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
const target_siginfo_t *info)
{
tswap_siginfo(tinfo, info);
}
/* This is the legacy signal stack switching. */
- else
+ else
#endif
if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
!(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
force_sig(TARGET_SIGSEGV /* , current */);
}
-static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUX86State *env)
{
cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
-
+
{
unsigned int tmpflags;
tmpflags = ldl(&sc->eflags);
target_to_host_sigset_internal(&set, &target_set);
sigprocmask(SIG_SETMASK, &set, NULL);
-
+
/* restore registers */
if (restore_sigcontext(env, &frame->sc, &eax))
goto badframe;
#endif
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
sigprocmask(SIG_SETMASK, &set, NULL);
-
+
if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
goto badframe;
// return err;
}
-static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
}
-static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
return g2h((sp - frame_size) & ~7);
}
-static void setup_frame(int sig, struct emulated_sigaction * ka,
+static void setup_frame(int sig, struct emulated_sigaction * ka,
target_sigset_t *set, CPUState *regs)
{
struct sigframe *frame;
give_sigsegv:
force_sig(TARGET_SIGSEGV/*, current*/);
- return;
+ return;
}
long do_sigreturn(CPUState *regs)
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
goto badframe;
- }
+ }
target_to_host_sigset_internal(&blocked, &target_set);
sigprocmask(SIG_SETMASK, &blocked, NULL);
:"r" (®s));
/* Unreached */
#endif
-
+
regs->PC = regs->CP0_EPC;
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
badframe:
force_sig(TARGET_SIGSEGV/*, current*/);
- return 0;
+ return 0;
}
-static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
fprintf(stderr, "setup_frame: not implemented\n");
}
-static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
target_siginfo_t *info,
target_sigset_t *set, CPUState *env)
{
target_sigset_t target_old_set;
struct emulated_sigaction *k;
struct sigqueue *q;
-
+
if (!signal_pending)
return;
k->first = q->next;
if (!k->first)
k->pending = 0;
-
+
sig = gdb_handlesig (cpu_env, sig);
if (!sig) {
fprintf (stderr, "Lost signal\n");
handler = k->sa._sa_handler;
if (handler == TARGET_SIG_DFL) {
/* default handler : ignore some signal. The other are fatal */
- if (sig != TARGET_SIGCHLD &&
- sig != TARGET_SIGURG &&
+ if (sig != TARGET_SIGCHLD &&
+ sig != TARGET_SIGURG &&
sig != TARGET_SIGWINCH) {
force_sig(sig);
}
blocked during the handler */
if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
sigaddset(&set, target_to_host_signal(sig));
-
+
/* block signals in the handler using Linux */
sigprocmask(SIG_BLOCK, &set, &old_set);
/* save the previous blocked signal state to restore it at the
#define TARGET_TCSETSW TARGET_IOW('T', 10, struct target_termios)
#define TARGET_TCSETSF TARGET_IOW('T', 11, struct target_termios)
-/* Note that all the ioctls that are not available in Linux have a
+/* Note that all the ioctls that are not available in Linux have a
* double underscore on the front to: a) avoid some programs to
* thing we support some ioctls under Linux (autoconfiguration stuff)
*/
#define TARGET_TCSETSW TARGET_IOW('T', 10, struct target_termios)
#define TARGET_TCSETSF TARGET_IOW('T', 11, struct target_termios)
-/* Note that all the ioctls that are not available in Linux have a
+/* Note that all the ioctls that are not available in Linux have a
* double underscore on the front to: a) avoid some programs to
* thing we support some ioctls under Linux (autoconfiguration stuff)
*/
/*
* Linux syscalls
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
return target_brk;
if (new_brk < target_original_brk)
return -ENOMEM;
-
+
brk_page = HOST_PAGE_ALIGN(target_brk);
/* If the new brk is less than this, set it and we're done... */
/* We need to allocate more memory after the brk... */
new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
- mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
+ mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
PROT_READ|PROT_WRITE,
MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
if (is_error(mapped_addr)) {
}
}
-static inline fd_set *target_to_host_fds(fd_set *fds,
+static inline fd_set *target_to_host_fds(fd_set *fds,
target_long *target_fds, int n)
{
#if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
#endif
}
-static inline void host_to_target_fds(target_long *target_fds,
+static inline void host_to_target_fds(target_long *target_fds,
fd_set *fds, int n)
{
#if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
}
-static long do_select(long n,
- target_ulong rfd_p, target_ulong wfd_p,
+static long do_select(long n,
+ target_ulong rfd_p, target_ulong wfd_p,
target_ulong efd_p, target_ulong target_tv)
{
fd_set rfds, wfds, efds;
target_efds = NULL;
efds_ptr = NULL;
}
-
+
if (target_tv) {
target_to_host_timeval(&tv, target_tv);
tv_ptr = &tv;
void *data = CMSG_DATA(cmsg);
void *target_data = TARGET_CMSG_DATA(target_cmsg);
- int len = tswapl(target_cmsg->cmsg_len)
+ int len = tswapl(target_cmsg->cmsg_len)
- TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
space += CMSG_SPACE(len);
msgh->msg_controllen = tswapl(space);
}
-static long do_setsockopt(int sockfd, int level, int optname,
+static long do_setsockopt(int sockfd, int level, int optname,
target_ulong optval, socklen_t optlen)
{
int val, ret;
-
+
switch(level) {
case SOL_TCP:
/* TCP options all take an 'int' value. */
if (optlen < sizeof(uint32_t))
return -EINVAL;
-
+
val = tget32(optval);
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
break;
return ret;
}
-static long do_getsockopt(int sockfd, int level, int optname,
+static long do_getsockopt(int sockfd, int level, int optname,
target_ulong optval, target_ulong optlen)
{
int len, lv, val, ret;
socklen_t addrlen)
{
void *addr = alloca(addrlen);
-
+
target_to_host_sockaddr(addr, target_addr, addrlen);
return get_errno(bind(sockfd, addr, addrlen));
}
socklen_t addrlen)
{
void *addr = alloca(addrlen);
-
+
target_to_host_sockaddr(addr, target_addr, addrlen);
return get_errno(connect(sockfd, addr, addrlen));
}
msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
msg.msg_control = alloca(msg.msg_controllen);
msg.msg_flags = tswap32(msgp->msg_flags);
-
+
count = tswapl(msgp->msg_iovlen);
vec = alloca(count * sizeof(struct iovec));
target_vec = tswapl(msgp->msg_iov);
lock_iovec(vec, target_vec, count, send);
msg.msg_iovlen = count;
msg.msg_iov = vec;
-
+
if (send) {
target_to_host_cmsg(&msg, msgp);
ret = get_errno(sendmsg(fd, &msg, flags));
target_msg = tgetl(vptr + n);
flags = tgetl(vptr + 2 * n);
- ret = do_sendrecvmsg(fd, target_msg, flags,
+ ret = do_sendrecvmsg(fd, target_msg, flags,
(num == SOCKOP_sendmsg));
}
break;
break;
raddr = ret;
/* find out the length of the shared memory segment */
-
+
ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
if (is_error(ret)) {
/* can't get length, bail out */
{
struct host_termios *host = dst;
const struct target_termios *target = src;
-
- host->c_iflag =
+
+ host->c_iflag =
target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
- host->c_oflag =
+ host->c_oflag =
target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
- host->c_cflag =
+ host->c_cflag =
target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
- host->c_lflag =
+ host->c_lflag =
target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
host->c_line = target->c_line;
-
- host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
- host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
- host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
- host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
- host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
- host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
- host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
- host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
- host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
- host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
- host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
- host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
- host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
- host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
- host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
- host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
- host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
+
+ host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
+ host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
+ host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
+ host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
+ host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
+ host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
+ host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
+ host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
+ host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
+ host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
+ host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
+ host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
+ host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
+ host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
+ host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
+ host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
+ host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
}
-
+
static void host_to_target_termios (void *dst, const void *src)
{
struct target_termios *target = dst;
const struct host_termios *host = src;
- target->c_iflag =
+ target->c_iflag =
tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
- target->c_oflag =
+ target->c_oflag =
tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
- target->c_cflag =
+ target->c_cflag =
tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
- target->c_lflag =
+ target->c_lflag =
tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
target->c_line = host->c_line;
-
+
target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
}
/* XXX: add locking support */
-static int write_ldt(CPUX86State *env,
+static int write_ldt(CPUX86State *env,
target_ulong ptr, unsigned long bytecount, int oldmode)
{
struct target_modify_ldt_ldt_s ldt_info;
ldt_info.limit = tswap32(target_ldt_info->limit);
ldt_info.flags = tswap32(target_ldt_info->flags);
unlock_user_struct(target_ldt_info, ptr, 0);
-
+
if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
return -EINVAL;
seg_32bit = ldt_info.flags & 1;
goto install;
}
}
-
+
entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
(ldt_info.limit & 0x0ffff);
entry_2 = (ldt_info.base_addr & 0xff000000) |
int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount)
{
int ret = -ENOSYS;
-
+
switch (func) {
case 0:
ret = read_ldt(ptr, bytecount);
TaskState *ts;
uint8_t *new_stack;
CPUState *new_env;
-
+
if (flags & CLONE_VM) {
ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
memset(ts, 0, sizeof(TaskState));
if (!newsp)
newsp = env->gpr[1];
new_env->gpr[1] = newsp;
- {
+ {
int i;
for (i = 7; i < 32; i++)
new_env->gpr[i] = 0;
unlock_user_struct(target_fl, arg, 1);
}
break;
-
+
case TARGET_F_SETLK:
case TARGET_F_SETLKW:
lock_user_struct(target_fl, arg, 1);
unlock_user_struct(target_fl, arg, 0);
ret = fcntl(fd, cmd, &fl);
break;
-
+
case TARGET_F_GETLK64:
ret = fcntl(fd, cmd >> 1, &fl64);
if (ret == 0) {
const argtype *arg_type;
int size;
-#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
-#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
+#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
+#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
#include "syscall_types.h"
#undef STRUCT
#undef STRUCT_SPECIAL
TARGET_IOC_SIZEMASK) {
arg_type = ie->arg_type;
if (arg_type[0] != TYPE_PTR) {
- fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
+ fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
ie->target_cmd);
exit(1);
}
arg_type++;
size = thunk_type_size(arg_type, 0);
- ie->target_cmd = (ie->target_cmd &
+ ie->target_cmd = (ie->target_cmd &
~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
(size << TARGET_IOC_SIZESHIFT);
}
/* automatic consistency check if same arch */
#if defined(__i386__) && defined(TARGET_I386)
if (ie->target_cmd != ie->host_cmd) {
- fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
+ fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
ie->target_cmd, ie->host_cmd);
}
#endif
unlock_user_struct(target_ts, target_addr, 1);
}
-long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
+long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6)
{
long ret;
struct stat st;
struct statfs stfs;
void *p;
-
+
#ifdef DEBUG
gemu_log("syscall %d", num);
#endif
{
int how = arg1;
sigset_t set, oldset, *set_ptr;
-
+
if (arg2) {
switch(how) {
case TARGET_SIG_BLOCK:
{
int how = arg1;
sigset_t set, oldset, *set_ptr;
-
+
if (arg2) {
switch(how) {
case TARGET_SIG_BLOCK:
sigset_t set;
struct timespec uts, *puts;
siginfo_t uinfo;
-
+
p = lock_user(arg1, sizeof(target_sigset_t), 1);
target_to_host_sigset(&set, p);
unlock_user(p, arg1, 0);
int resource = arg1;
struct target_rlimit *target_rlim;
struct rlimit rlim;
-
+
ret = get_errno(getrlimit(resource, &rlim));
if (!is_error(ret)) {
lock_user_struct(target_rlim, arg2, 0);
v5 = tswapl(v[4]);
v6 = tswapl(v[5]);
unlock_user(v, arg1, 0);
- ret = get_errno(target_mmap(v1, v2, v3,
+ ret = get_errno(target_mmap(v1, v2, v3,
target_to_host_bitmask(v4, mmap_flags_tbl),
v5, v6));
}
#else
- ret = get_errno(target_mmap(arg1, arg2, arg3,
- target_to_host_bitmask(arg4, mmap_flags_tbl),
+ ret = get_errno(target_mmap(arg1, arg2, arg3,
+ target_to_host_bitmask(arg4, mmap_flags_tbl),
arg5,
arg6));
#endif
#else
#define MMAP_SHIFT TARGET_PAGE_BITS
#endif
- ret = get_errno(target_mmap(arg1, arg2, arg3,
- target_to_host_bitmask(arg4, mmap_flags_tbl),
+ ret = get_errno(target_mmap(arg1, arg2, arg3,
+ target_to_host_bitmask(arg4, mmap_flags_tbl),
arg5,
arg6 << MMAP_SHIFT));
break;
convert_statfs:
if (!is_error(ret)) {
struct target_statfs *target_stfs;
-
+
lock_user_struct(target_stfs, arg2, 0);
/* ??? put_user is probably wrong. */
put_user(stfs.f_type, &target_stfs->f_type);
convert_statfs64:
if (!is_error(ret)) {
struct target_statfs64 *target_stfs;
-
+
lock_user_struct(target_stfs, arg3, 0);
/* ??? put_user is probably wrong. */
put_user(stfs.f_type, &target_stfs->f_type);
ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
break;
#endif
-
+
case TARGET_NR_syslog:
goto unimplemented;
case TARGET_NR_setitimer:
if (arg2) {
pvalue = &value;
- target_to_host_timeval(&pvalue->it_interval,
+ target_to_host_timeval(&pvalue->it_interval,
arg2);
- target_to_host_timeval(&pvalue->it_value,
+ target_to_host_timeval(&pvalue->it_value,
arg2 + sizeof(struct target_timeval));
} else {
pvalue = NULL;
case TARGET_NR_getitimer:
{
struct itimerval value;
-
+
ret = get_errno(getitimer(arg1, &value));
if (!is_error(ret) && arg2) {
host_to_target_timeval(arg2,
do_stat:
if (!is_error(ret)) {
struct target_stat *target_st;
-
+
lock_user_struct(target_st, arg2, 0);
target_st->st_dev = tswap16(st.st_dev);
target_st->st_ino = tswapl(st.st_ino);
/* no need to transcode because we use the linux syscall */
{
struct new_utsname * buf;
-
+
lock_user_struct(buf, arg1, 0);
ret = get_errno(sys_uname(buf));
if (!is_error(ret)) {
dirp = malloc(count);
if (!dirp)
return -ENOMEM;
-
+
ret = get_errno(sys_getdents(arg1, dirp, count));
if (!is_error(ret)) {
struct dirent *de;
break;
#ifdef TARGET_NR_setresuid
case TARGET_NR_setresuid:
- ret = get_errno(setresuid(low2highuid(arg1),
- low2highuid(arg2),
+ ret = get_errno(setresuid(low2highuid(arg1),
+ low2highuid(arg2),
low2highuid(arg3)));
break;
#endif
#endif
#ifdef TARGET_NR_getresgid
case TARGET_NR_setresgid:
- ret = get_errno(setresgid(low2highgid(arg1),
- low2highgid(arg2),
+ ret = get_errno(setresgid(low2highgid(arg1),
+ low2highgid(arg2),
low2highgid(arg3)));
break;
#endif
uint32_t *target_grouplist;
gid_t *grouplist;
int i;
-
+
grouplist = alloca(gidsetsize * sizeof(gid_t));
target_grouplist = lock_user(arg2, gidsetsize * 4, 1);
for(i = 0;i < gidsetsize; i++)
if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) tswapl(__mhdr->msg_control)
+ tswapl(__mhdr->msg_controllen))
|| ((unsigned char *) __cmsg + TARGET_CMSG_ALIGN (tswapl(__cmsg->cmsg_len))
- > ((unsigned char *) tswapl(__mhdr->msg_control)
+ > ((unsigned char *) tswapl(__mhdr->msg_control)
+ tswapl(__mhdr->msg_controllen))))
/* No more entries. */
return 0;
void host_to_target_sigset(target_sigset_t *d, const sigset_t *s);
void target_to_host_sigset(sigset_t *d, const target_sigset_t *s);
-void host_to_target_old_sigset(target_ulong *old_sigset,
+void host_to_target_old_sigset(target_ulong *old_sigset,
const sigset_t *sigset);
-void target_to_host_old_sigset(sigset_t *sigset,
+void target_to_host_old_sigset(sigset_t *sigset,
const target_ulong *old_sigset);
struct target_sigaction;
int do_sigaction(int sig, const struct target_sigaction *act,
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
/* cdrom commands */
-#define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */
+#define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */
#define TARGET_CDROMRESUME 0x5302 /* Resume paused Audio Operation */
#define TARGET_CDROMPLAYMSF 0x5303 /* Play Audio MSF (struct cdrom_msf) */
-#define TARGET_CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index
+#define TARGET_CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index
(struct cdrom_ti) */
-#define TARGET_CDROMREADTOCHDR 0x5305 /* Read TOC header
+#define TARGET_CDROMREADTOCHDR 0x5305 /* Read TOC header
(struct cdrom_tochdr) */
-#define TARGET_CDROMREADTOCENTRY 0x5306 /* Read TOC entry
+#define TARGET_CDROMREADTOCENTRY 0x5306 /* Read TOC entry
(struct cdrom_tocentry) */
#define TARGET_CDROMSTOP 0x5307 /* Stop the cdrom drive */
#define TARGET_CDROMSTART 0x5308 /* Start the cdrom drive */
#define TARGET_CDROMEJECT 0x5309 /* Ejects the cdrom media */
-#define TARGET_CDROMVOLCTRL 0x530a /* Control output volume
+#define TARGET_CDROMVOLCTRL 0x530a /* Control output volume
(struct cdrom_volctrl) */
-#define TARGET_CDROMSUBCHNL 0x530b /* Read subchannel data
+#define TARGET_CDROMSUBCHNL 0x530b /* Read subchannel data
(struct cdrom_subchnl) */
-#define TARGET_CDROMREADMODE2 0x530c /* Read TARGET_CDROM mode 2 data (2336 Bytes)
+#define TARGET_CDROMREADMODE2 0x530c /* Read TARGET_CDROM mode 2 data (2336 Bytes)
(struct cdrom_read) */
#define TARGET_CDROMREADMODE1 0x530d /* Read TARGET_CDROM mode 1 data (2048 Bytes)
(struct cdrom_read) */
#define TARGET_CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */
#define TARGET_CDROMEJECT_SW 0x530f /* enable(1)/disable(0) auto-ejecting */
-#define TARGET_CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session
- address of multi session disks
+#define TARGET_CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session
+ address of multi session disks
(struct cdrom_multisession) */
-#define TARGET_CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
+#define TARGET_CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
if available (struct cdrom_mcn) */
-#define TARGET_CDROM_GET_UPC TARGET_CDROM_GET_MCN /* This one is depricated,
+#define TARGET_CDROM_GET_UPC TARGET_CDROM_GET_MCN /* This one is depricated,
but here anyway for compatability */
#define TARGET_CDROMRESET 0x5312 /* hard-reset the drive */
-#define TARGET_CDROMVOLREAD 0x5313 /* Get the drive's volume setting
+#define TARGET_CDROMVOLREAD 0x5313 /* Get the drive's volume setting
(struct cdrom_volctrl) */
#define TARGET_CDROMREADRAW 0x5314 /* read data in raw mode (2352 Bytes)
(struct cdrom_read) */
-/*
+/*
* These ioctls are used only used in aztcd.c and optcd.c
*/
#define TARGET_CDROMREADCOOKED 0x5315 /* read data in cooked mode */
#define TARGET_CDROMSEEK 0x5316 /* seek msf address */
-
+
/*
- * This ioctl is only used by the scsi-cd driver.
+ * This ioctl is only used by the scsi-cd driver.
It is for playing audio in logical block addressing mode.
*/
#define TARGET_CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */
-/*
+/*
* These ioctls are only used in optcd.c
*/
#define TARGET_CDROMREADALL 0x5318 /* read all 2646 bytes */
-/*
- * These ioctls are (now) only in ide-cd.c for controlling
+/*
+ * These ioctls are (now) only in ide-cd.c for controlling
* drive spindown time. They should be implemented in the
* Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10,
* GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE...
#define TARGET_CDROMGETSPINDOWN 0x531d
#define TARGET_CDROMSETSPINDOWN 0x531e
-/*
+/*
* These ioctls are implemented through the uniform CD-ROM driver
* They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM
* drivers are eventually ported to the uniform CD-ROM driver interface.
STRUCT(serial_multiport_struct,
TYPE_INT, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR,
- TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT,
+ TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT,
MK_ARRAY(TYPE_INT, 32))
STRUCT(serial_icounter_struct,
TYPE_SHORT, MK_ARRAY(TYPE_CHAR, 14))
STRUCT(rtentry,
- TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr),
- TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, TYPE_PTRVOID,
+ TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr),
+ TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, TYPE_PTRVOID,
TYPE_ULONG, TYPE_ULONG, TYPE_SHORT)
STRUCT(ifmap,
- TYPE_ULONG, TYPE_ULONG, TYPE_SHORT, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR,
+ TYPE_ULONG, TYPE_ULONG, TYPE_SHORT, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR,
/* Spare 3 bytes */
TYPE_CHAR, TYPE_CHAR, TYPE_CHAR)
STRUCT(sockaddr_ifreq,
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), MK_STRUCT(STRUCT_sockaddr))
-
+
STRUCT(short_ifreq,
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_SHORT)
TYPE_INT, TYPE_PTRVOID)
STRUCT(arpreq,
- MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), TYPE_INT, MK_STRUCT(STRUCT_sockaddr),
+ MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), TYPE_INT, MK_STRUCT(STRUCT_sockaddr),
MK_ARRAY(TYPE_CHAR, 16))
STRUCT(arpreq_old,
/*
* vm86 linux syscall support
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
target_v86->regs.eflags = tswap32(env->eflags);
unlock_user_struct(target_v86, ts->target_v86, 1);
#ifdef DEBUG_VM86
- fprintf(logfile, "save_v86_state: eflags=%08x cs:ip=%04x:%04x\n",
+ fprintf(logfile, "save_v86_state: eflags=%08x cs:ip=%04x:%04x\n",
env->eflags, env->segs[R_CS].selector, env->eip);
#endif
static inline int set_IF(CPUX86State *env)
{
TaskState *ts = env->opaque;
-
+
ts->v86flags |= VIF_MASK;
if (ts->v86flags & VIP_MASK) {
return_to_32bit(env, TARGET_VM86_STI);
goto cannot_handle;
if (is_revectored(intno, &ts->vm86plus.int_revectored))
goto cannot_handle;
- if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,
+ if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,
&ts->vm86plus.int21_revectored))
goto cannot_handle;
int_ptr = (uint32_t *)(intno << 2);
if ((segoffs >> 16) == TARGET_BIOSSEG)
goto cannot_handle;
#if defined(DEBUG_VM86)
- fprintf(logfile, "VM86: emulating int 0x%x. CS:IP=%04x:%04x\n",
+ fprintf(logfile, "VM86: emulating int 0x%x. CS:IP=%04x:%04x\n",
intno, segoffs >> 16, segoffs & 0xffff);
#endif
/* save old state */
csp = (uint8_t *)(env->segs[R_CS].selector << 4);
ip = env->eip & 0xffff;
pc = csp + ip;
-
+
ssp = (uint8_t *)(env->segs[R_SS].selector << 4);
sp = env->regs[R_ESP] & 0xffff;
ADD16(ip, 1);
env->eip = ip;
if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) {
- if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[intno >> 3] >>
+ if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[intno >> 3] >>
(intno &7)) & 1) {
return_to_32bit(env, TARGET_VM86_INTx + (intno << 8));
return;
return;
}
VM86_FAULT_RETURN;
-
+
case 0xfa: /* cli */
env->eip = ip;
clear_IF(env);
VM86_FAULT_RETURN;
-
+
case 0xfb: /* sti */
env->eip = ip;
if (set_IF(env))
TaskState *ts = env->opaque;
struct target_vm86plus_struct * target_v86;
int ret;
-
+
switch (subfunction) {
case TARGET_VM86_REQUEST_IRQ:
case TARGET_VM86_FREE_IRQ:
lock_user_struct(target_v86, vm86_addr, 1);
/* build vm86 CPU state */
ts->v86flags = tswap32(target_v86->regs.eflags);
- env->eflags = (env->eflags & ~SAFE_MASK) |
+ env->eflags = (env->eflags & ~SAFE_MASK) |
(tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK;
ts->vm86plus.cpu_type = tswapl(target_v86->cpu_type);
cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs));
ret = tswap32(target_v86->regs.eax); /* eax will be restored at
the end of the syscall */
- memcpy(&ts->vm86plus.int_revectored,
+ memcpy(&ts->vm86plus.int_revectored,
&target_v86->int_revectored, 32);
- memcpy(&ts->vm86plus.int21_revectored,
+ memcpy(&ts->vm86plus.int21_revectored,
&target_v86->int21_revectored, 32);
ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags);
- memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab,
+ memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab,
target_v86->vm86plus.vm86dbg_intxxtab, 32);
unlock_user_struct(target_v86, vm86_addr, 0);
-
+
#ifdef DEBUG_VM86
- fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n",
+ fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n",
env->segs[R_CS].selector, env->eip);
#endif
/* now the virtual CPU is ready for vm86 execution ! */
/*
* QEMU Executable loader
- *
+ *
* 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
{"eor", 4, one(0005174), one(0177777), "#wSs", m68000up },
{"eor", 4, one(0005100), one(0177700), "#w$s", m68000up },
{"eor", 2, one(0130500), one(0170700), "Dd$s", m68000up },
-
+
{"exg", 2, one(0140500), one(0170770), "DdDs", m68000up },
{"exg", 2, one(0140510), one(0170770), "AdAs", m68000up },
{"exg", 2, one(0140610), one(0170770), "DdAs", m68000up },
{"roxrl", 2, one(0160260), one(0170770), "DdDs", m68000up },
{"rtd", 4, one(0047164), one(0177777), "#w", m68010up },
-
+
{"rte", 2, one(0047163), one(0177777), "", m68000up | mcfisa_a },
-
+
{"rtm", 2, one(0003300), one(0177760), "Rs", m68020 },
-
+
{"rtr", 2, one(0047167), one(0177777), "", m68000up },
-
+
{"rts", 2, one(0047165), one(0177777), "", m68000up | mcfisa_a },
{"satsl", 2, one(0046200), one(0177770), "Ds", mcfisa_b },
zero can it be zero, and then it must be zero. */
unsigned long exponent, int_bit;
const unsigned char *ufrom = (const unsigned char *) from;
-
+
exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
fmt->exp_start, fmt->exp_len);
int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
fmt->man_start, 1);
-
+
if ((exponent == 0) != (int_bit == 0))
return 0;
else
}
return result;
}
-
+
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
"l" 32 bit floating point constant in .lit4
MDMX instruction operands (note that while these use the FP register
- fields, they accept both $fN and $vN names for the registers):
+ fields, they accept both $fN and $vN names for the registers):
"O" MDMX alignment offset (OP_*_ALN)
"Q" MDMX vector/scalar/immediate source (OP_*_VSEL and OP_*_FT)
- "X" MDMX destination register (OP_*_FD)
+ "X" MDMX destination register (OP_*_FD)
"Y" MDMX source register (OP_*_FS)
"Z" MDMX source register (OP_*_FT)
#define INSN_MIPS16 0x00002000
/* MIPS-3D ASE */
#define INSN_MIPS3D 0x00004000
-/* MDMX ASE */
+/* MDMX ASE */
#define INSN_MDMX 0x00008000
/* Chip specific instructions. These are bitmasks. */
Because of the lookup algorithm used, entries with the same opcode
name must be contiguous.
-
+
Many instructions are short hand for other instructions (i.e., The
jal <register> instruction is short for jalr <register>). */
lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
(*info->fprintf_func) (info->stream, "0x%x", lsb);
break;
-
+
case 'B':
msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
(*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32;
(*info->fprintf_func) (info->stream, "0x%x", lsb);
break;
-
+
case 'F':
msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32;
(*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
/*
* QEMU monitor
- *
+ *
* Copyright (c) 2003-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
/*
* Supported types:
- *
+ *
* 'F' filename
* 'B' block device name
* 's' string (accept optional quote)
static void do_commit(const char *device)
{
int i, all_devices;
-
+
all_devices = !strcmp(device, "all");
for (i = 0; i < MAX_DISKS; i++) {
if (bs_table[i]) {
- if (all_devices ||
+ if (all_devices ||
!strcmp(bdrv_get_device_name(bs_table[i]), device))
bdrv_commit(bs_table[i]);
}
if (!item)
goto help;
for(cmd = info_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(item, cmd->name))
+ if (compare_cmd(item, cmd->name))
goto found;
}
help:
cpu_dump_state(env, NULL, monitor_fprintf,
X86_DUMP_FPU);
#else
- cpu_dump_state(env, NULL, monitor_fprintf,
+ cpu_dump_state(env, NULL, monitor_fprintf,
0);
#endif
}
mon_get_cpu();
for(env = first_cpu; env != NULL; env = env->next_cpu) {
- term_printf("%c CPU #%d:",
+ term_printf("%c CPU #%d:",
(env == mon_cpu) ? '*' : ' ',
env->cpu_index);
#if defined(TARGET_I386)
{
int i;
const char *str;
-
+
i = 0;
for(;;) {
str = readline_get_history(i);
static void do_log(const char *items)
{
int mask;
-
+
if (!strcmp(items, "none")) {
mask = 0;
} else {
term_printf("'");
}
-static void memory_dump(int count, int format, int wsize,
+static void memory_dump(int count, int format, int wsize,
target_ulong addr, int is_physical)
{
CPUState *env;
flags = 0;
if (env) {
#ifdef TARGET_X86_64
- if ((env->efer & MSR_EFER_LMA) &&
+ if ((env->efer & MSR_EFER_LMA) &&
(env->segs[R_CS].flags & DESC_L_MASK))
flags = 2;
else
break;
cpu_memory_rw_debug(env, addr, buf, l, 0);
}
- i = 0;
+ i = 0;
while (i < l) {
switch(wsize) {
default:
#define GET_TLONG(h, l) (l)
#endif
-static void do_memory_dump(int count, int format, int size,
+static void do_memory_dump(int count, int format, int size,
uint32_t addrh, uint32_t addrl)
{
target_long addr = GET_TLONG(addrh, addrl);
term_printf("\n");
}
-static void do_memory_save(unsigned int valh, unsigned int vall,
+static void do_memory_save(unsigned int valh, unsigned int vall,
uint32_t size, const char *filename)
{
FILE *f;
static const KeyDef key_defs[] = {
{ 0x2a, "shift" },
{ 0x36, "shift_r" },
-
+
{ 0x38, "alt" },
{ 0xb8, "alt_r" },
{ 0x1d, "ctrl" },
{ 0x30, "b" },
{ 0x31, "n" },
{ 0x32, "m" },
-
+
{ 0x39, "spc" },
{ 0x3a, "caps_lock" },
{ 0x3b, "f1" },
{ 0x47, "kp_7" },
{ 0x48, "kp_8" },
{ 0x49, "kp_9" },
-
+
{ 0x56, "<" },
{ 0x57, "f11" },
uint8_t keycodes[16];
const char *p;
int nb_keycodes, keycode, i;
-
+
nb_keycodes = 0;
p = string;
while (*p != '\0') {
static int mouse_button_state;
-static void do_mouse_move(const char *dx_str, const char *dy_str,
+static void do_mouse_move(const char *dx_str, const char *dy_str,
const char *dz_str)
{
int dx, dy, dz;
dx = strtol(dx_str, NULL, 0);
dy = strtol(dy_str, NULL, 0);
dz = 0;
- if (dz_str)
+ if (dz_str)
dz = strtol(dz_str, NULL, 0);
kbd_mouse_event(dx, dy, dz, mouse_button_state);
}
#if defined(TARGET_I386)
static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
{
- term_printf("%08x: %08x %c%c%c%c%c%c%c%c\n",
+ term_printf("%08x: %08x %c%c%c%c%c%c%c%c\n",
addr,
pte & mask,
pte & PG_GLOBAL_MASK ? 'G' : '-',
print_pte((l1 << 22), pde, ~((1 << 20) - 1));
} else {
for(l2 = 0; l2 < 1024; l2++) {
- cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
+ cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
(uint8_t *)&pte, 4);
pte = le32_to_cpu(pte);
if (pte & PG_PRESENT_MASK) {
- print_pte((l1 << 22) + (l2 << 12),
- pte & ~PG_PSE_MASK,
+ print_pte((l1 << 22) + (l2 << 12),
+ pte & ~PG_PSE_MASK,
~0xfff);
}
}
}
}
-static void mem_print(uint32_t *pstart, int *plast_prot,
+static void mem_print(uint32_t *pstart, int *plast_prot,
uint32_t end, int prot)
{
int prot1;
if (prot != prot1) {
if (*pstart != -1) {
term_printf("%08x-%08x %08x %c%c%c\n",
- *pstart, end, end - *pstart,
+ *pstart, end, end - *pstart,
prot1 & PG_USER_MASK ? 'u' : '-',
'r',
prot1 & PG_RW_MASK ? 'w' : '-');
mem_print(&start, &last_prot, end, prot);
} else {
for(l2 = 0; l2 < 1024; l2++) {
- cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
+ cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
(uint8_t *)&pte, 4);
pte = le32_to_cpu(pte);
end = (l1 << 22) + (l2 << 12);
#else
term_printf("kqemu support: not compiled\n");
#endif
-}
+}
#ifdef CONFIG_PROFILER
#endif
static term_cmd_t term_cmds[] = {
- { "help|?", "s?", do_help,
+ { "help|?", "s?", do_help,
"[cmd]", "show the help" },
- { "commit", "s", do_commit,
+ { "commit", "s", do_commit,
"device|all", "commit changes to the disk images (if -snapshot is used) or backing files" },
{ "info", "s?", do_info,
"subcommand", "show various information about the system state" },
"[-f] device", "eject a removable media (use -f to force it)" },
{ "change", "BF", do_change,
"device filename", "change a removable media" },
- { "screendump", "F", do_screen_dump,
+ { "screendump", "F", do_screen_dump,
"filename", "save screen into PPM image 'filename'" },
{ "log", "s", do_log,
- "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
+ "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
{ "savevm", "s?", do_savevm,
- "tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" },
+ "tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" },
{ "loadvm", "s", do_loadvm,
- "tag|id", "restore a VM snapshot from its tag or id" },
+ "tag|id", "restore a VM snapshot from its tag or id" },
{ "delvm", "s", do_delvm,
- "tag|id", "delete a VM snapshot from its tag or id" },
- { "stop", "", do_stop,
+ "tag|id", "delete a VM snapshot from its tag or id" },
+ { "stop", "", do_stop,
"", "stop emulation", },
- { "c|cont", "", do_cont,
+ { "c|cont", "", do_cont,
"", "resume emulation", },
#ifdef CONFIG_GDBSTUB
- { "gdbserver", "i?", do_gdbserver,
+ { "gdbserver", "i?", do_gdbserver,
"[port]", "start gdbserver session (default port=1234)", },
#endif
- { "x", "/l", do_memory_dump,
+ { "x", "/l", do_memory_dump,
"/fmt addr", "virtual memory dump starting at 'addr'", },
- { "xp", "/l", do_physical_memory_dump,
+ { "xp", "/l", do_physical_memory_dump,
"/fmt addr", "physical memory dump starting at 'addr'", },
- { "p|print", "/l", do_print,
+ { "p|print", "/l", do_print,
"/fmt expr", "print expression value (use $reg for CPU register access)", },
- { "i", "/ii.", do_ioport_read,
+ { "i", "/ii.", do_ioport_read,
"/fmt addr", "I/O port read" },
- { "sendkey", "s", do_send_key,
+ { "sendkey", "s", do_send_key,
"keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
- { "system_reset", "", do_system_reset,
+ { "system_reset", "", do_system_reset,
"", "reset the system" },
- { "system_powerdown", "", do_system_powerdown,
+ { "system_powerdown", "", do_system_powerdown,
"", "send system power down event" },
- { "sum", "ii", do_sum,
+ { "sum", "ii", do_sum,
"addr size", "compute the checksum of a memory region" },
{ "usb_add", "s", do_usb_add,
"device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
{ "usb_del", "s", do_usb_del,
"device", "remove USB device 'bus.addr'" },
- { "cpu", "i", do_cpu_set,
+ { "cpu", "i", do_cpu_set,
"index", "set the default CPU" },
- { "mouse_move", "sss?", do_mouse_move,
+ { "mouse_move", "sss?", do_mouse_move,
"dx dy [dz]", "send mouse move events" },
- { "mouse_button", "i", do_mouse_button,
+ { "mouse_button", "i", do_mouse_button,
"state", "change mouse button state (1=L, 2=M, 4=R)" },
{ "mouse_set", "i", do_mouse_set,
"index", "set which mouse device receives events" },
#endif
{ "stopcapture", "i", do_stop_capture,
"capture index", "stop capture" },
- { "memsave", "lis", do_memory_save,
+ { "memsave", "lis", do_memory_save,
"addr size file", "save to disk virtual memory dump starting at 'addr' of size 'size'", },
- { NULL, NULL, },
+ { NULL, NULL, },
};
static term_cmd_t info_cmds[] = {
{ NULL },
};
-static void expr_error(const char *fmt)
+static void expr_error(const char *fmt)
{
term_printf(fmt);
term_printf("\n");
case '$':
{
char buf[128], *q;
-
+
pch++;
q = buf;
while ((*pch >= 'a' && *pch <= 'z') ||
ret = get_monitor_def(&n, buf);
if (ret == -1)
expr_error("unknown register");
- else if (ret == -2)
+ else if (ret == -2)
expr_error("no cpu defined");
}
break;
{
target_long val, val2;
int op;
-
+
val = expr_unary();
for(;;) {
op = *pch;
break;
case '/':
case '%':
- if (val2 == 0)
+ if (val2 == 0)
expr_error("division by zero");
if (op == '/')
val /= val2;
#ifdef DEBUG
term_printf("command='%s'\n", cmdline);
#endif
-
+
/* extract the command name */
p = cmdline;
q = cmdname;
len = sizeof(cmdname) - 1;
memcpy(cmdname, pstart, len);
cmdname[len] = '\0';
-
+
/* find the command */
for(cmd = term_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(cmdname, cmd->name))
+ if (compare_cmd(cmdname, cmd->name))
goto found;
}
term_printf("unknown command: '%s'\n", cmdname);
for(i = 0; i < MAX_ARGS; i++)
str_allocated[i] = NULL;
-
+
/* parse the parameters */
typestr = cmd->args_type;
nb_args = 0;
{
int ret;
char *str;
-
- while (isspace(*p))
+
+ while (isspace(*p))
p++;
if (*typestr == '?') {
typestr++;
case '/':
{
int count, format, size;
-
+
while (isspace(*p))
p++;
if (*p == '/') {
case 'l':
{
target_long val;
- while (isspace(*p))
+ while (isspace(*p))
p++;
if (*typestr == '?' || *typestr == '.') {
if (*typestr == '?') {
} else {
if (*p == '.') {
p++;
- while (isspace(*p))
+ while (isspace(*p))
p++;
has_arg = 1;
} else {
{
int has_option;
/* option */
-
+
c = *typestr++;
if (c == '\0')
goto bad_type;
- while (isspace(*p))
+ while (isspace(*p))
p++;
has_option = 0;
if (*p == '-') {
p++;
if (*p != c) {
- term_printf("%s: unsupported option -%c\n",
+ term_printf("%s: unsupported option -%c\n",
cmdname, *p);
goto fail;
}
while (isspace(*p))
p++;
if (*p != '\0') {
- term_printf("%s: extraneous characters at the end of line\n",
+ term_printf("%s: extraneous characters at the end of line\n",
cmdname);
goto fail;
}
int input_path_len;
const char *p;
- p = strrchr(input, '/');
+ p = strrchr(input, '/');
if (!p) {
input_path_len = 0;
pstrcpy(file_prefix, sizeof(file_prefix), input);
/*
* QEMU low level functions
- *
+ *
* Copyright (c) 2003 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
free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
if ((ram_size + 8192 * 1024) >= free_space) {
ram_mb = (ram_size / (1024 * 1024));
- fprintf(stderr,
+ fprintf(stderr,
"You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
tmpdir, ram_mb);
if (strcmp(tmpdir, "/dev/shm") == 0) {
"mount -t tmpfs -o size=%dm none /dev/shm\n",
ram_mb + 16);
} else {
- fprintf(stderr,
+ fprintf(stderr,
"Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
"QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
"temporary RAM file will be opened.\n");
exit(1);
}
}
- snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
+ snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
tmpdir);
phys_ram_fd = mkstemp(phys_ram_file);
if (phys_ram_fd < 0) {
- fprintf(stderr,
+ fprintf(stderr,
"warning: could not create temporary file in '%s'.\n"
"Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
"Using '/tmp' as fallback.\n",
tmpdir);
- snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
+ snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
"/tmp");
phys_ram_fd = mkstemp(phys_ram_file);
if (phys_ram_fd < 0) {
- fprintf(stderr, "Could not create temporary memory file '%s'\n",
+ fprintf(stderr, "Could not create temporary memory file '%s'\n",
phys_ram_file);
exit(1);
}
}
size = (size + 4095) & ~4095;
ftruncate(phys_ram_fd, phys_ram_size + size);
- ptr = mmap(NULL,
- size,
- PROT_WRITE | PROT_READ, MAP_SHARED,
+ ptr = mmap(NULL,
+ size,
+ PROT_WRITE | PROT_READ, MAP_SHARED,
phys_ram_fd, phys_ram_size);
if (ptr == MAP_FAILED) {
fprintf(stderr, "Could not map physical memory\n");
+++ rombios.h 1 Nov 2006 19:16:34 -0000
@@ -19,7 +19,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
+
/* define it to include QEMU specific code */
-//#define BX_QEMU
+#define BX_QEMU
-
+
#ifndef LEGACY
# define BX_ROMBIOS32 1
Index: rombios32.c
@@ -852,6 +852,11 @@
int ioapic_id, i, len;
int mp_config_table_size;
-
+
+#ifdef BX_QEMU
+ if (smp_cpus <= 1)
+ return;
*/
#define LOAD_SEG 0x9000
-
-.code16
+
+.code16
.text
.globl _start
mov $0x8ffe, %sp
ljmp $LOAD_SEG + 0x20, $0
-1:
+1:
.fill 510 - (1b - _start), 1, 0
/* boot sector signature */
ARCH_POP,
+ ARCH_HEATHROW,
};
-
+
/* Hardware definition(s) */
@@ -174,6 +175,7 @@
int bd_ioctl (bloc_device_t *bd, int func, void *args);
-void bd_set_boot_part (bloc_device_t *bd, part_t *partition);
+void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum);
part_t **_bd_parts (bloc_device_t *bd);
-
+
void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1,
uint32_t io_base2, uint32_t io_base3,
- void *OF_private);
+ void *OF_private0, void *OF_private1);
void ide_pci_pmac_register (uint32_t io_base0, uint32_t io_base1,
void *OF_private);
-
+
@@ -399,17 +401,23 @@
uint16_t min_grant, uint16_t max_latency);
void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses);
+ int irq_line);
void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
void *private_data);
-+void OF_finalize_pci_ide (void *dev,
++void OF_finalize_pci_ide (void *dev,
+ uint32_t io_base0, uint32_t io_base1,
+ uint32_t io_base2, uint32_t io_base3);
int OF_register_bus (const unsigned char *name, uint32_t address,
- int width, int height, int depth);
+void OF_vga_register (const unsigned char *name, unused uint32_t address,
+ int width, int height, int depth,
-+ unsigned long vga_bios_addr,
++ unsigned long vga_bios_addr,
+ unsigned long vga_bios_size);
void *OF_blockdev_register (void *parent, void *private,
const unsigned char *type,
bloc_device_t *next;
};
@@ -66,6 +67,7 @@
-
+
static int ide_initialize (bloc_device_t *bd, int device);
static int ide_read_sector (bloc_device_t *bd, void *buffer, int secnum);
+static int ide_reset (bloc_device_t *bd);
-
+
static int mem_initialize (bloc_device_t *bd, int device);
static int mem_read_sector (bloc_device_t *bd, void *buffer, int secnum);
@@ -212,6 +214,17 @@
{
}
-
+
+void bd_reset_all(void)
+{
+ bloc_device_t *bd;
return bd->seclen;
@@ -223,10 +236,12 @@
}
-
+
/* XXX: to be suppressed */
-void bd_set_boot_part (bloc_device_t *bd, part_t *partition)
+void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum)
+ bd->bpartnum = partnum;
}
}
-
+
@@ -240,6 +255,13 @@
return &bd->bparts;
}
-
+
+void bd_set_boot_device (bloc_device_t *bd)
+{
+#if defined (USE_OPENFIRMWARE)
+ bd_set_boot_device(bd);
}
}
-
+
@@ -717,34 +737,29 @@
/* IDE PCI access for pc */
static uint8_t ide_pci_port_read (bloc_device_t *bd, int port)
+ value = inb(bd->io_base + port);
+ return value;
}
-
+
static void ide_pci_port_write (bloc_device_t *bd, int port, uint8_t value)
{
- *(uint8_t *)(bd->io_base + port) = value;
- eieio();
+ outb(bd->io_base + port, value);
}
-
+
static uint32_t ide_pci_data_readl (bloc_device_t *bd)
{
- eieio();
- return *((uint32_t *)bd->io_base);
+ return inl(bd->io_base);
}
-
+
static void ide_pci_data_writel (bloc_device_t *bd, uint32_t val)
{
- *(uint32_t *)(bd->io_base) = val;
- eieio();
+ outl(bd->io_base, val);
}
-
+
static void ide_pci_control_write (bloc_device_t *bd, uint32_t val)
{
- *((uint8_t *)bd->tmp) = val;
- eieio();
+ outb(bd->tmp + 2, val);
}
-
+
static ide_ops_t ide_pci_pc_ops = {
@@ -761,7 +776,7 @@
-
+
void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1,
uint32_t io_base2, uint32_t io_base3,
- unused void *OF_private)
}
@@ -935,6 +950,8 @@
}
-
+
static void atapi_pad_req (void *buffer, int len);
+static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer,
+ int maxlen);
static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum);
-
+
static int ide_initialize (bloc_device_t *bd, int device)
@@ -1035,9 +1052,7 @@
DPRINTF("INQUIRY\n");
@@ -1105,6 +1118,22 @@
memset(p + len, 0, 12 - len);
}
-
+
+static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer,
+ int maxlen)
+{
@@ -1112,16 +1141,9 @@
uint32_t status, value;
int i, len;
-
+
- /* select drive */
- if (bd->drv == 0)
- ide_port_write(bd, 0x06, 0x40);
+++ OpenHackWare-release-0.4/src/libpart/core.c 2005-07-03 16:17:41.000000000 +0200
@@ -126,7 +126,7 @@
}
-
+
int part_register (bloc_device_t *bd, part_t *partition,
- const unsigned char *name)
+ const unsigned char *name, int partnum)
{
part_t **cur;
-
+
@@ -134,6 +134,7 @@
partition->bd = bd;
partition->next = NULL;
@@ -141,29 +142,15 @@
return 0;
}
-
+
-static inline int set_boot_part (bloc_device_t *bd, int partnum)
-{
- part_t *cur;
{
part_t **listp, *cur;
- int i;
-
+
listp = _bd_parts(bd);
- cur = *listp;
- for (i = 0; i != partnum; i++) {
- if (cur == NULL)
-+
++
+ for (cur = *listp; cur != NULL; cur = cur->next) {
+ if (cur->partnum == partnum)
break;
- cur = cur->next;
}
-
+
return cur;
@@ -192,17 +179,20 @@
part_set_blocsize(bd, part, 512);
part->flags = PART_TYPE_RAW | PART_FLAG_BOOT;
- part_register(bd, part, "Raw");
+ part_register(bd, part, "Raw", 0);
-
+
return part;
}
-
+
+bloc_device_t *part_get_bd (part_t *part)
+{
+ return part->bd;
{
- part_t *part0, *boot_part, **cur;
+ part_t *part0 = NULL, *boot_part, **cur;
-
+
- /* Register the 0 partition: raw partition containing the whole disk */
- part0 = part_get_raw(bd);
/* Try to find a valid boot partition */
- DPRINTF("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs,
+ dprintf("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs,
part_fs(boot_part), part0);
-
+
return boot_part;
@@ -279,6 +277,7 @@
part->boot_size.offset = 0;
part->boot_load = 0;
part->boot_entry = 0;
+ part->flags |= PART_FLAG_BOOT;
-
+
return 0;
}
diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/isofs.c OpenHackWare-release-0.4/src/libpart/isofs.c
--- OpenHackWare-release-0.4.org/src/libpart/libpart.h 2005-03-31 09:23:33.000000000 +0200
+++ OpenHackWare-release-0.4/src/libpart/libpart.h 2005-07-03 16:17:41.000000000 +0200
@@ -30,6 +30,7 @@
-
+
struct part_t {
bloc_device_t *bd;
+ int partnum;
uint32_t spb;
@@ -54,7 +55,7 @@
};
-
+
int part_register (bloc_device_t *bd, part_t *partition,
- const unsigned char *name);
+ const unsigned char *name, int partnum);
+ 0xFE000000, /* Grackle (Heathrow) */
+ 0xF2000000, /* UniNorth (Mac99) */
+ };
-
+
/* Retrieve NVRAM configuration */
- nvram_retry:
+ for(i = 0; i < 3; i++) {
@@ -433,9 +437,12 @@
vga_puts(copyright);
vga_puts("\n");
-
+
+#if 0
/* QEMU is quite incoherent: d is cdrom, not second drive */
+ /* XXX: should probe CD-ROM position */
@@ -1017,6 +1017,33 @@
string, strlen(string) + 1);
}
-
+
+/* convert '\1' char to '\0' */
+static OF_prop_t *OF_prop_string_new1 (OF_env_t *env, OF_node_t *node,
+ const unsigned char *name,
+ if (arch == ARCH_MAC99) {
+ OF_node_t *unin;
+ OF_regprop_t regs;
-
+
+ unin = OF_node_new(OF_env, OF_node_root,
+ "uni-n", 0xf8000000);
+ if (unin == NULL) {
+ OF_prop_int_new(OF_env, unin, "device-rev", 3);
+ OF_node_put(OF_env, unin);
+ }
-
+
#if 1 /* This is mandatory for claim to work
* but I don't know where it should really be (in cpu ?)
@@ -1693,7 +1747,9 @@
-
+
/* "/options/boot-args" node */
{
- const unsigned char *args = "-v rootdev cdrom";
- OF_prop_int_new(OF_env, node, "#size-cells", dev->acells);
+ OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->icells);
dprintf("Done %p %p\n", parent, node);
-
+
return node;
@@ -2040,8 +2096,9 @@
OF_env_t *OF_env;
+ OF_node_t *pci_host, *als;
int nranges;
+ unsigned char buffer[OF_NAMELEN_MAX];
-
+
OF_env = OF_env_main;
dprintf("register PCI host '%s' '%s' '%s' '%s'\n",
@@ -2052,6 +2109,17 @@
ERROR("Cannot create pci host\n");
return NULL;
}
-+
++
+ als = OF_node_get(OF_env, "aliases");
+ if (als == NULL) {
+ ERROR("Cannot get 'aliases'\n");
+ sprintf(buffer, "/%s", dev->name);
+ OF_prop_string_set(OF_env, als, "pci", buffer);
+ OF_node_put(OF_env, als);
-+
++
+
regs[0].address = cfg_base;
regs[0].size = cfg_len;
@@ -2136,6 +2204,11 @@
return pci_dev;
}
-
+
+/* XXX: suppress that, used for interrupt map init */
+OF_node_t *pci_host_node;
+uint32_t pci_host_interrupt_map[7 * 32];
OF_property_new(OF_env, dev, "bus-range", regs, sizeof(OF_regprop_t));
+ pci_host_node = dev;
}
-
+
void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
- uint32_t *regions, uint32_t *sizes)
+ uint32_t *regions, uint32_t *sizes,
pci_reg_prop_t pregs[6], rregs[6];
@@ -2156,6 +2231,7 @@
int i, j, k;
-
+
OF_env = OF_env_main;
+ /* XXX: only useful for VGA card in fact */
if (regions[0] != 0x00000000)
+#if 1
{
OF_prop_t *prop_name = ((OF_node_t *)dev)->prop_name;
-
+
@@ -2390,6 +2481,54 @@
return 0;
}
-
+
+static void keylargo_ata(OF_node_t *mio, uint32_t base_address,
-+ uint32_t base, int irq1, int irq2,
++ uint32_t base, int irq1, int irq2,
+ uint16_t pic_phandle)
+{
+ OF_env_t *OF_env = OF_env_main;
uint16_t pic_phandle;
+ int rec_len;
+ OF_prop_t *mio_reg;
-
+
OF_DPRINTF("mac-io: %p\n", dev);
OF_env = OF_env_main;
@@ -2416,10 +2557,14 @@
+ }
+ dprintf("\n");
+#endif
-+ OF_property_new(OF_env, pci_host_node, "interrupt-map",
-+ pci_host_interrupt_map,
++ OF_property_new(OF_env, pci_host_node, "interrupt-map",
++ pci_host_interrupt_map,
+ pci_host_interrupt_map_len * sizeof(uint32_t));
+ tab[0] = 0xf800;
+ tab[1] = 0;
+ tab[2] = 0;
+ tab[3] = 0;
-+ OF_property_new(OF_env, pci_host_node, "interrupt-map-mask",
++ OF_property_new(OF_env, pci_host_node, "interrupt-map-mask",
+ tab, 4 * sizeof(uint32_t));
+ }
+#if 0
+ }
+ {
+ OF_node_t *rtc;
-
+
rtc = OF_node_new(OF_env, via, "rtc", OF_ADDRESS_NONE);
if (rtc == NULL) {
@@ -2813,14 +2963,68 @@
OF_node_put(OF_env, chs);
OF_node_put(OF_env, als);
}
-
-+void OF_finalize_pci_ide (void *dev,
+
++void OF_finalize_pci_ide (void *dev,
+ uint32_t io_base0, uint32_t io_base1,
+ uint32_t io_base2, uint32_t io_base3)
+{
OF_method_new(OF_env, dsk, "read", &OF_blockdev_read);
@@ -3432,7 +3636,8 @@
}
-
+
void OF_vga_register (const unsigned char *name, unused uint32_t address,
- int width, int height, int depth)
+ int width, int height, int depth,
+ p = (const uint8_t *)vga_bios_addr;
+ if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') {
+ size = *(uint32_t *)(p + 4);
-+ OF_property_new(OF_env, disp, "driver,AAPL,MacOS,PowerPC",
++ OF_property_new(OF_env, disp, "driver,AAPL,MacOS,PowerPC",
+ p + 8, size);
+ }
+ }
+ uint32_t sizes[7];
pci_device_t *next;
};
-
+
@@ -158,6 +158,7 @@
-
+
/* IRQ numbers assigned to PCI IRQs */
static uint8_t prep_pci_irqs[4] = { 9, 11, 9, 11 };
+static uint8_t heathrow_pci_irqs[4] = { 0x15, 0x16, 0x17, 0x18 };
static uint8_t pmac_pci_irqs[4] = { 8, 9, 10, 11 };
-
+
/* PREP PCI host */
@@ -399,6 +400,79 @@
&uninorth_config_readl, &uninorth_config_writel,
};
-
+
+/* Grackle PCI host */
+
+static uint32_t grackle_cfg_address (pci_bridge_t *bridge,
@@ -466,12 +540,22 @@
},
};
-
+
+static int ide_config_cb2 (pci_device_t *device)
+{
+ OF_finalize_pci_ide(device->common.OF_private,
@@ -481,7 +565,9 @@
},
};
-
+
-static int ide_config_cb (pci_device_t *device)
+#if 0
+/* should base it on PCI ID, not on arch */
-
return 0;
}
-
+
@@ -512,16 +592,12 @@
device->common.OF_private);
break;
- device->common.OF_private);
break;
}
-
+
return 0;
}
+#endif
-
+
static pci_subclass_t mass_subclass[] = {
{
@@ -530,7 +606,7 @@
+ device->sizes[6]);
}
vga_console_register();
-
+
@@ -750,6 +828,13 @@
NULL, &PREP_pci_ops,
};
-
+
+pci_dev_t grackle_fake_bridge = {
+ 0xFFFF, 0xFFFF,
+ "pci", "pci-bridge", "DEC,21154", "DEC,21154.pci-bridge",
{
- 0x106B, 0x001F,
- NULL, "pci", "AAPL,UniNorth", "uni-north",
-+ 0x106B, 0x001F, NULL,
++ 0x106B, 0x001F, NULL,
+ "pci", "AAPL,UniNorth", "uni-north",
3, 2, 1,
NULL, &uninorth_fake_bridge,
0x1057, 0x4801, NULL,
@@ -1443,7 +1528,14 @@
}
-
+
static const pci_dev_t misc_pci[] = {
- /* Apple Mac-io controller */
+ /* Paddington Mac I/O */
-+ {
++ {
+ 0x106B, 0x0017,
+ "mac-io", "mac-io", "AAPL,343S1211", "paddington\1heathrow",
+ 1, 1, 1,
+ &macio_config_cb, NULL,
+ },
+ /* KeyLargo Mac I/O */
- {
+ {
0x106B, 0x0022,
"mac-io", "mac-io", "AAPL,Keylargo", "Keylargo",
@@ -1599,7 +1691,7 @@
- uint32_t cmd;
+ uint32_t cmd, addr;
int i;
-
+
device->min_grant = min_grant;
@@ -1611,22 +1703,28 @@
printf("MAP PCI device %d:%d to IRQ %d\n",
device->bus, device->devfn, i,
device->regions[i], device->sizes[i],
- device->regions[i] & 0x00000001 ? "I/O" : "memory");
-+ (device->regions[i] & 0x00000001) && i != 6 ? "I/O" :
++ (device->regions[i] & 0x00000001) && i != 6 ? "I/O" :
+ "memory");
+ if (i != 6) {
cmd = pci_config_readl(bridge, device->bus, device->devfn, 0x04);
+++ Makefile 14 Jun 2006 00:51:06 -0000
@@ -22,7 +22,7 @@
cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin
-
+
clean:
- /bin/rm -f biossums *.o *.s *.ld86 \
+ /bin/rm -f biossums vbetables-gen vbetables.h *.o *.s *.ld86 \
temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak
-
+
dist-clean: clean
@@ -79,3 +79,9 @@
-
+
biossums: biossums.c
$(CC) -o biossums biossums.c
+
+ pop ax
+cirrus_set_video_mode_extended_1:
and al, #0x7f
-
+
push ds
@@ -1011,6 +1018,13 @@
jnz cirrus_vesa_02h_3
@@ -1479,6 +1493,38 @@
pop bx
ret
-
+
+cirrus_clear_vram:
+ pusha
+ push es
+ mov ax, si
+ mov cx, #8192
+ cld
-+ rep
++ rep
+ stosw
+ pop ax
+ inc ah
@@ -118,21 +118,114 @@
.word VBE_VESA_MODE_END_OF_LIST
#endif
-
+
+ .align 2
vesa_pm_start:
dw vesa_pm_set_window - vesa_pm_start
+ dw VBE_DISPI_IOPORT_DATA + 1
+ dw 0xffff
+ dw 0xffff
-
+
USE32
vesa_pm_set_window:
- mov ax, #0x4f05
+ pop dx
+ mov ax, #0x004f
ret
-
+
vesa_pm_set_display_start:
- mov ax, #0x4f07
- int #0x10
+ mov ax, #0x0100
+ ret
+vesa_pm_set_display_start1:
-+; convert offset to (X, Y) coordinate
++; convert offset to (X, Y) coordinate
+; (would be simpler to change Bochs VBE API...)
+ push eax
+ push ecx
+ pop eax
+ mov ax, #0x004f
ret
-
+
vesa_pm_unimplemented:
@@ -835,6 +928,64 @@
ASM_END
-
-
+
+
+Bit16u vbe_biosfn_read_video_state_size()
+{
+ return 9 * 2;
+ enable = inw(VBE_DISPI_IOPORT_DATA);
+ write_word(ES, BX, enable);
+ BX += 2;
-+ if (!(enable & VBE_DISPI_ENABLED))
++ if (!(enable & VBE_DISPI_ENABLED))
+ return;
+ for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
+ if (i != VBE_DISPI_INDEX_ENABLE) {
+
+ enable = read_word(ES, BX);
+ BX += 2;
-+
++
+ if (!(enable & VBE_DISPI_ENABLED)) {
+ outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
+ outw(VBE_DISPI_IOPORT_DATA, enable);
+}
+
/** Function 04h - Save/Restore State
- *
+ *
* Input:
@@ -849,10 +1000,48 @@
* BX = Number of 64-byte blocks to hold the state buffer (if DL=00h)
- *
+ *
*/
-void vbe_biosfn_save_restore_state(AX, DL, CX, ES, BX)
+void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX)
-}
+ Bit16u ss=get_SS();
+ Bit16u result, val;
-
+
+ result = 0x4f;
+ switch(GET_DL()) {
+ case 0x00:
+ }
+ write_word(ss, AX, result);
+}
-
+
/** Function 05h - Display Window Control
- *
+ *
@@ -1090,7 +1279,7 @@
*/
ASM_START
void vbe_biosfn_return_controller_information(AX, ES, DI);
void vbe_biosfn_return_mode_information(AX, CX, ES, DI);
void vbe_biosfn_set_mode(AX, BX, ES, DI);
--void vbe_biosfn_save_restore_state(AX, DL, CX, ES, BX);
+-void vbe_biosfn_save_restore_state(AX, DL, CX, ES, BX);
+void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX);
void vbe_biosfn_set_get_palette_data(AX);
void vbe_biosfn_return_protected_mode_interface(AX);
-
+
@@ -151,6 +151,12 @@
Bit8u Reserved[189];
} ModeInfoBlock;
-
+
+typedef struct ModeInfoListItem
+{
+ Bit16u mode;
+#define VBE_VESA_MODE_1600X1200X1555 0x11D
+#define VBE_VESA_MODE_1600X1200X565 0x11E
+#define VBE_VESA_MODE_1600X1200X888 0x11F
-
+
// BOCHS/PLEX86 'own' mode numbers
#define VBE_OWN_MODE_320X200X8888 0x140
@@ -202,6 +212,12 @@
+#define VBE_OWN_MODE_1152X864X565 0x14a
+#define VBE_OWN_MODE_1152X864X888 0x14b
+#define VBE_OWN_MODE_1152X864X8888 0x14c
-
+
#define VBE_VESA_MODE_END_OF_LIST 0xFFFF
-
+
@@ -259,7 +275,7 @@
// like 0xE0000000
-
-
+
+
- #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 4
+ #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 8
-
+
#define VBE_DISPI_BANK_ADDRESS 0xA0000
#define VBE_DISPI_BANK_SIZE_KB 64
Index: vgabios.c
+static Bit16u biosfn_save_video_state();
+static Bit16u biosfn_restore_video_state();
extern Bit8u video_save_pointer_table[];
-
+
// This is for compiling with gcc2 and gcc3
@@ -748,12 +748,7 @@
vbe_biosfn_set_mode(&AX,BX,ES,DI);
//FIXME
@@ -3138,23 +3133,215 @@
}
-
+
// --------------------------------------------------------------------------------------------
-static void biosfn_read_video_state_size (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX;
+// --------------------------------------------------------------------------------------------
-+static Bit16u biosfn_read_video_state_size2 (CX)
++static Bit16u biosfn_read_video_state_size2 (CX)
+ Bit16u CX;
{
-#ifdef DEBUG
+ return size;
+}
+
-+static void biosfn_read_video_state_size (CX, BX)
++static void biosfn_read_video_state_size (CX, BX)
+ Bit16u CX; Bit16u *BX;
{
-#ifdef DEBUG
}
-static void biosfn_restore_video_state (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX;
+
-+static Bit16u biosfn_save_video_state (CX,ES,BX)
++static Bit16u biosfn_save_video_state (CX,ES,BX)
+ Bit16u CX;Bit16u ES;Bit16u BX;
{
-#ifdef DEBUG
+ return BX;
+}
+
-+static Bit16u biosfn_restore_video_state (CX,ES,BX)
++static Bit16u biosfn_restore_video_state (CX,ES,BX)
+ Bit16u CX;Bit16u ES;Bit16u BX;
+{
+ Bit16u i, crtc_addr, v, addr1, ar_index;
+ crtc_addr = read_word(ES, BX + 0x40);
+ addr1 = BX;
+ BX += 5;
-+
++
+ for(i=1;i<=4;i++){
+ outb(VGAREG_SEQU_ADDRESS, i);
+ outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++;
+ // enable write protection if needed
+ outb(crtc_addr, 0x11);
+ outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11));
-+
++
+ // Set Attribute Ctl
+ ar_index = read_byte(ES, addr1 + 0x03);
+ inb(VGAREG_ACTL_RESET);
+ }
+ outb(VGAREG_ACTL_ADDRESS, ar_index);
+ inb(VGAREG_ACTL_RESET);
-+
++
+ for(i=0;i<=8;i++) {
+ outb(VGAREG_GRDC_ADDRESS,i);
+ outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++;
+ }
+ BX += 2; /* crtc_addr */
+ BX += 4; /* plane latches */
-+
++
+ outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++;
+ outb(crtc_addr, read_byte(ES, addr1)); addr1++;
+ outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++;
+ }
+ return BX;
}
-
+
// ============================================================================================
diff -u -w vbetables-gen.c
--- vbetables-gen.c 1970-01-01 01:00:00.000000000 +0100
+ printf("static ModeInfoListItem mode_info_list[]=\n");
+ printf("{\n");
+ for(pm = modes; pm->mode != 0; pm++) {
-+ printf("{ 0x%04x, /* %dx%dx%d */\n",
++ printf("{ 0x%04x, /* %dx%dx%d */\n",
+ pm->mode, pm->width, pm->height, pm->depth);
-+ printf("{ /*Bit16u ModeAttributes*/ %s,\n",
++ printf("{ /*Bit16u ModeAttributes*/ %s,\n",
+ "VBE_MODE_ATTRIBUTE_SUPPORTED | "
+ "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | "
+ "VBE_MODE_ATTRIBUTE_COLOR_MODE | "
+ "VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE | "
+ "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE");
-+
++
+ printf("/*Bit8u WinAAttributes*/ %s,\n",
+ "VBE_WINDOW_ATTRIBUTE_RELOCATABLE | "
+ "VBE_WINDOW_ATTRIBUTE_READABLE | "
+ "VBE_WINDOW_ATTRIBUTE_WRITEABLE");
-+
++
+ printf("/*Bit8u WinBAttributes*/ %d,\n", 0);
-+
++
+ printf("/*Bit16u WinGranularity*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB");
-+
++
+ printf("/*Bit16u WinSize*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB");
-+
++
+ printf("/*Bit16u WinASegment*/ %s,\n", "VGAMEM_GRAPH");
-+
++
+ printf("/*Bit16u WinBSegment*/ 0x%04x,\n", 0);
-+
++
+ printf("/*Bit32u WinFuncPtr*/ %d,\n", 0);
-+
++
+ if (pm->depth == 4)
+ pitch = (pm->width + 7) / 8;
+ else
+ printf("/*Bit8u NumberOfPlanes*/ %d,\n", 1);
+ printf("/*Bit8u BitsPerPixel*/ %d,\n", pm->depth);
+ }
-+ printf("/*Bit8u NumberOfBanks*/ %d,\n",
++ printf("/*Bit8u NumberOfBanks*/ %d,\n",
+ (pm->height * pitch + 65535) / 65536);
+
+ if (pm->depth == 4)
+ break;
+ }
+
-+ printf("/*Bit8u RedMaskSize*/ %d,\n", r_size);
-+ printf("/*Bit8u RedFieldPosition*/ %d,\n", r_pos);
-+ printf("/*Bit8u GreenMaskSize*/ %d,\n", g_size);
-+ printf("/*Bit8u GreenFieldPosition*/ %d,\n", g_pos);
-+ printf("/*Bit8u BlueMaskSize*/ %d,\n", b_size);
-+ printf("/*Bit8u BlueFieldPosition*/ %d,\n", b_pos);
-+ printf("/*Bit8u RsvdMaskSize*/ %d,\n", a_size);
-+ printf("/*Bit8u RsvdFieldPosition*/ %d,\n", a_pos);
-+ printf("/*Bit8u DirectColorModeInfo*/ %d,\n", 0);
++ printf("/*Bit8u RedMaskSize*/ %d,\n", r_size);
++ printf("/*Bit8u RedFieldPosition*/ %d,\n", r_pos);
++ printf("/*Bit8u GreenMaskSize*/ %d,\n", g_size);
++ printf("/*Bit8u GreenFieldPosition*/ %d,\n", g_pos);
++ printf("/*Bit8u BlueMaskSize*/ %d,\n", b_size);
++ printf("/*Bit8u BlueFieldPosition*/ %d,\n", b_pos);
++ printf("/*Bit8u RsvdMaskSize*/ %d,\n", a_size);
++ printf("/*Bit8u RsvdFieldPosition*/ %d,\n", a_pos);
++ printf("/*Bit8u DirectColorModeInfo*/ %d,\n", 0);
+
+// Mandatory information for VBE 2.0 and above
-+ printf("/*Bit32u PhysBasePtr*/ %s,\n",
++ printf("/*Bit32u PhysBasePtr*/ %s,\n",
+ "VBE_DISPI_LFB_PHYSICAL_ADDRESS");
+ printf("/*Bit32u OffScreenMemOffset*/ %d,\n", 0);
+ printf("/*Bit16u OffScreenMemSize*/ %d,\n", 0);
same. */
/*ARGSUSED*/
-static unsigned long
+static unsigned long
insert_bat (insn, value, errmsg)
uint32_t insn;
int32_t value;
extraction function just checks that the fields are the same. */
/*ARGSUSED*/
-static unsigned long
+static unsigned long
insert_rbs (insn, value, errmsg)
uint32_t insn;
int32_t value;
@itemize @minus
-@item
+@item
Full system emulation. In this mode, QEMU emulates a full system (for
example a PC), including one or several processors and various
peripherals. It can be used to launch different Operating Systems
without rebooting the PC or to debug system code.
-@item
+@item
User mode emulation. In this mode, QEMU can launch
processes compiled for one CPU on another CPU. It can be used to
launch the Wine Windows API emulator (@url{http://www.winehq.org}) or
@end itemize
QEMU can run without an host kernel driver and yet gives acceptable
-performance.
+performance.
For system emulation, the following hardware targets are supported:
@itemize
following peripherals:
@itemize @minus
-@item
+@item
i440FX host PCI bridge and PIIX3 PCI to ISA bridge
@item
Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA
extensions (hardware level, including all non standard modes).
@item
PS/2 mouse and keyboard
-@item
+@item
2 PCI IDE interfaces with hard disk and CD-ROM support
@item
Floppy disk
-@item
+@item
NE2000 PCI network adapters
@item
Serial ports
@item -net socket[,vlan=n][,fd=h][,mcast=maddr:port]
Create a VLAN @var{n} shared with another QEMU virtual
-machines using a UDP multicast socket, effectively making a bus for
+machines using a UDP multicast socket, effectively making a bus for
every QEMU with same multicast address @var{maddr} and @var{port}.
NOTES:
@enumerate
-@item
-Several QEMU can be running on different hosts and share same bus (assuming
+@item
+Several QEMU can be running on different hosts and share same bus (assuming
correct multicast setup for these hosts).
@item
mcast support is compatible with User Mode Linux (argument @option{eth@var{N}=mcast}), see
@table @option
-@item -kernel bzImage
+@item -kernel bzImage
Use @var{bzImage} as kernel image.
-@item -append cmdline
+@item -append cmdline
Use @var{cmdline} as kernel command line
@item -initrd file
non graphical mode.
@item -s
-Wait gdb connection to port 1234 (@pxref{gdb_usage}).
+Wait gdb connection to port 1234 (@pxref{gdb_usage}).
@item -p port
Change gdb connection port. @var{port} can be either a decimal number
to specify a TCP port, or a host device (same devices as the serial port).
@item -S
Do not start CPU at startup (you must type 'c' in the monitor).
-@item -d
+@item -d
Output log in /tmp/qemu.log
@item -hdachs c,h,s,[,t]
Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <=
@table @key
@item Ctrl-a h
Print this help
-@item Ctrl-a x
+@item Ctrl-a x
Exit emulator
-@item Ctrl-a s
+@item Ctrl-a s
Save disk data back to file (if -snapshot)
@item Ctrl-a b
Send break (magic sysrq in Linux)
Remove or insert removable medias images
(such as CD-ROM or floppies)
-@item
+@item
Freeze/unfreeze the Virtual Machine (VM) and save or restore its state
from a disk file.
@item help or ? [cmd]
Show the help for all commands or just for command @var{cmd}.
-@item commit
+@item commit
Commit changes to the disk images (if -snapshot is used)
-@item info subcommand
+@item info subcommand
show various information about the system state
@table @option
data. Its syntax is: @option{/@{count@}@{format@}@{size@}}
@table @var
-@item count
+@item count
is the number of items to be dumped.
@item format
@end table
-Examples:
+Examples:
@itemize
@item
Dump 10 instructions at the current instruction pointer:
-@example
+@example
(qemu) x/10i $eip
0x90107063: ret
0x90107064: sti
@item
Dump 80 16 bit values at the start of the video memory.
-@smallexample
+@smallexample
(qemu) xp/80hx 0xb8000
0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
VM snapshots currently have the following known limitations:
@itemize
-@item
+@item
They cannot cope with removable devices if they are removed or
inserted after a snapshot is done.
-@item
+@item
A few device drivers still have incomplete snapshot support so their
state is not saved or restored properly (in particular USB).
@end itemize
@subsubsection Mac OS X
-@file{/dev/cdrom} is an alias to the first CDROM.
+@file{/dev/cdrom} is an alias to the first CDROM.
Currently there is no specific code to handle removable medias, so it
is better to use the @code{change} or @code{eject} monitor commands to
QEMU can automatically create a virtual FAT disk image from a
directory tree. In order to use it, just type:
-@example
+@example
qemu linux.img -hdb fat:/my_directory
@end example
Floppies can be emulated with the @code{:floppy:} option:
-@example
+@example
qemu linux.img -fda fat:floppy:/my_directory
@end example
A read/write support is available for testing (beta stage) with the
@code{:rw:} option:
-@example
+@example
qemu linux.img -fda fat:floppy:rw:/my_directory
@end example
| (10.0.2.2)
|
----> DNS server (10.0.2.3)
- |
+ |
----> SMB server (10.0.2.4)
@end example
Cameras) are not supported yet.
@enumerate
-@item If you use an early Linux 2.4 kernel, verify that no Linux driver
+@item If you use an early Linux 2.4 kernel, verify that no Linux driver
is actually using the USB device. A simple way to do that is simply to
disable the corresponding kernel module by renaming it from @file{mydriver.o}
to @file{mydriver.o.disabled}.
@end example
@item Launch QEMU and do in the monitor:
-@example
+@example
info usbhost
Device 1.2, speed 480 Mb/s
Class 00: USB device 1234:5678, USB DISK
hubs, it won't work).
@item Add the device in QEMU by using:
-@example
+@example
usb_add host:1234:5678
@end example
Add/Troubleshoot a device => Add a new device & Next => No, select the
hardware from a list & Next => NT Apm/Legacy Support & Next => Next
(again) a few times. Now the driver is installed and Windows 2000 now
-correctly instructs QEMU to shutdown at the appropriate moment.
+correctly instructs QEMU to shutdown at the appropriate moment.
@subsubsection Share a directory between Unix and Windows
QEMU emulates the following PowerMac peripherals:
@itemize @minus
-@item
-UniNorth PCI Bridge
+@item
+UniNorth PCI Bridge
@item
PCI VGA compatible card with VESA Bochs Extensions
-@item
+@item
2 PMAC IDE interfaces with hard disk and CD-ROM support
-@item
+@item
NE2000 PCI adapters
@item
Non Volatile RAM
QEMU emulates the following PREP peripherals:
@itemize @minus
-@item
+@item
PCI Bridge
@item
PCI VGA compatible card with VESA Bochs Extensions
-@item
+@item
2 IDE interfaces with hard disk and CD-ROM support
@item
Floppy disk
-@item
+@item
NE2000 network adapters
@item
Serial port
@table @option
-@item -g WxH[xDEPTH]
+@item -g WxH[xDEPTH]
Set the initial VGA graphic mode. The default is 800x600x15.
@end table
-@c man end
+@c man end
More information is available at
IOMMU
@item
TCX Frame buffer
-@item
+@item
Lance (Am7990) Ethernet
@item
Non Volatile RAM M48T08
@end table
-@c man end
+@c man end
@node Sparc64 System emulator invocation
@section Sparc64 System emulator invocation
@itemize @minus
@item
-UltraSparc IIi APB PCI Bridge
+UltraSparc IIi APB PCI Bridge
@item
PCI VGA compatible card with VESA Bochs Extensions
@item
installation from NFS. The following devices are emulated:
@itemize @minus
-@item
+@item
MIPS R4K CPU
@item
PC style serial port
ARM926E or ARM1026E CPU
@item
Two PL011 UARTs
-@item
+@item
SMC 91c111 Ethernet adapter
@item
PL110 LCD controller
PL190 Vectored Interrupt Controller
@item
Four PL011 UARTs
-@item
+@item
SMC 91c111 Ethernet adapter
@item
PL110 LCD controller
A Linux 2.6 test image is available on the QEMU web site. More
information is available in the QEMU mailing-list archive.
-@node QEMU User space emulator
-@chapter QEMU User space emulator
+@node QEMU User space emulator
+@chapter QEMU User space emulator
@menu
* Supported Operating Systems ::
@subsection Quick Start
In order to launch a Linux process, QEMU needs the process executable
-itself and all the target (x86) dynamic libraries used by it.
+itself and all the target (x86) dynamic libraries used by it.
@itemize
@item On x86, you can just try to launch any process by using the native
libraries:
-@example
+@example
qemu-i386 -L / /bin/ls
@end example
@item Since QEMU is also a linux process, you can launch qemu with qemu (NOTE: you can only do that if you compiled QEMU from the sources):
-@example
+@example
qemu-i386 -L / qemu-i386 -L / /bin/ls
@end example
@code{LD_LIBRARY_PATH} is not set:
@example
-unset LD_LIBRARY_PATH
+unset LD_LIBRARY_PATH
@end example
Then you can launch the precompiled @file{ls} x86 executable:
@end example
@item Download the binary x86 Wine install
-(@file{qemu-XXX-i386-wine.tar.gz} on the QEMU web page).
+(@file{qemu-XXX-i386-wine.tar.gz} on the QEMU web page).
@item Configure Wine on your account. Look at the provided script
@file{/usr/local/qemu-i386/@/bin/wine-conf.sh}. Your previous
@table @option
@item -h
Print the help
-@item -L path
+@item -L path
Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
@item -s size
Set the x86 stack size in bytes (default=524288)
@item On x86, you can just try to launch any process by using the native
libraries:
-@example
+@example
qemu-darwin-i386 /bin/ls
@end example
or to run the ppc version of the executable:
-@example
+@example
qemu-darwin-ppc /bin/ls
@end example
@item On ppc, you'll have to tell qemu where your x86 libraries (and dynamic linker)
are installed:
-@example
+@example
qemu-darwin-i386 -L /opt/x86_root/ /bin/ls
@end example
@table @option
@item -h
Print the help
-@item -L path
+@item -L path
Set the library root path (default=/)
@item -s size
Set the stack size in bytes (default=524288)
@url{http://www.mingw.org/}. You can find detailed installation
instructions in the download section and the FAQ.
-@item Download
+@item Download
the MinGW development library of SDL 1.2.x
(@file{SDL-devel-1.2.x-@/mingw32.tar.gz}) from
@url{http://www.libsdl.org}. Unpack it in a temporary place, and
correct SDL directory when invoked.
@item Extract the current version of QEMU.
-
+
@item Start the MSYS shell (file @file{msys.bat}).
-@item Change to the QEMU directory. Launch @file{./configure} and
+@item Change to the QEMU directory. Launch @file{./configure} and
@file{make}. If you have problems using SDL, verify that
@file{sdl-config} can be launched from the MSYS command line.
-@item You can install QEMU in @file{Program Files/Qemu} by typing
+@item You can install QEMU in @file{Program Files/Qemu} by typing
@file{make install}. Don't forget to copy @file{SDL.dll} in
@file{Program Files/Qemu}.
Install the MinGW cross compilation tools available at
@url{http://www.mingw.org/}.
-@item
+@item
Install the Win32 version of SDL (@url{http://www.libsdl.org}) by
unpacking @file{i386-mingw32msvc.tar.gz}. Set up the PATH environment
variable so that @file{i386-mingw32msvc-sdl-config} can be launched by
the QEMU configuration script.
-@item
+@item
Configure QEMU for Windows cross compilation:
@example
./configure --enable-mingw32
choosen for the MinGW tools with --cross-prefix. You can also use
--prefix to set the Win32 install path.
-@item You can install QEMU in the installation directory by typing
+@item You can install QEMU in the installation directory by typing
@file{make install}. Don't forget to copy @file{SDL.dll} in the
-installation directory.
+installation directory.
@end itemize
/*
* QEMU disk image utility
- *
+ *
* Copyright (c) 2003-2007 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
term_printf(filename);
}
-void __attribute__((noreturn)) error(const char *fmt, ...)
+void __attribute__((noreturn)) error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
tty.c_cflag |= CS8;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 0;
-
+
tcsetattr (0, TCSANOW, &tty);
atexit(term_exit);
int64_t size;
const char *p;
BlockDriver *drv;
-
+
encrypted = 0;
for(;;) {
c = getopt(argc, argv, "b:f:he");
break;
}
}
- if (optind >= argc)
+ if (optind >= argc)
help();
filename = argv[optind++];
size = 0;
break;
}
}
- if (optind >= argc)
+ if (optind >= argc)
help();
filename = argv[optind++];
break;
}
}
- if (optind >= argc)
+ if (optind >= argc)
help();
filename = argv[optind++];
- if (optind >= argc)
+ if (optind >= argc)
help();
out_filename = argv[optind++];
-
+
bs = bdrv_new_open(filename, fmt);
drv = bdrv_find_format(out_fmt);
error("Error while formatting '%s'", out_filename);
}
}
-
+
out_bs = bdrv_new_open(out_filename, out_fmt);
if (compress) {
n = cluster_sectors;
else
n = nb_sectors;
- if (bdrv_read(bs, sector_num, buf, n) < 0)
+ if (bdrv_read(bs, sector_num, buf, n) < 0)
error("error while reading");
if (n < cluster_sectors)
memset(buf + n * 512, 0, cluster_size - n * 512);
if (is_not_zero(buf, cluster_size)) {
- if (bdrv_write_compressed(out_bs, sector_num, buf,
+ if (bdrv_write_compressed(out_bs, sector_num, buf,
cluster_sectors) != 0)
error("error while compressing sector %" PRId64,
sector_num);
n = (IO_BUF_SIZE / 512);
else
n = nb_sectors;
- if (bdrv_read(bs, sector_num, buf, n) < 0)
+ if (bdrv_read(bs, sector_num, buf, n) < 0)
error("error while reading");
/* NOTE: at the same time we convert, we do not write zero
sectors to have a chance to compress the image. Ideally, we
buf1 = buf;
while (n > 0) {
if (is_allocated_sectors(buf1, n, &n1)) {
- if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
+ if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
error("error while writing");
}
sector_num += n1;
return (((int64_t) high) << 32) + low;
}
- if (_stati64(filename, &st) < 0)
+ if (_stati64(filename, &st) < 0)
return -1;
return st.st_size;
}
static int64_t get_allocated_file_size(const char *filename)
{
struct stat st;
- if (stat(filename, &st) < 0)
+ if (stat(filename, &st) < 0)
return -1;
return (int64_t)st.st_blocks * 512;
}
break;
}
}
- if (optind >= argc)
+ if (optind >= argc)
help();
filename = argv[optind++];
if (allocated_size < 0)
sprintf(dsize_buf, "unavailable");
else
- get_human_readable_size(dsize_buf, sizeof(dsize_buf),
+ get_human_readable_size(dsize_buf, sizeof(dsize_buf),
allocated_size);
printf("image: %s\n"
"file format: %s\n"
"virtual size: %s (%" PRId64 " bytes)\n"
"disk size: %s\n",
- filename, fmt_name, size_buf,
+ filename, fmt_name, size_buf,
(total_sectors * 512),
dsize_buf);
if (bdrv_is_encrypted(bs))
printf("encrypted: yes\n");
if (bdrv_get_info(bs, &bdi) >= 0) {
- if (bdi.cluster_size != 0)
+ if (bdi.cluster_size != 0)
printf("cluster_size: %d\n", bdi.cluster_size);
}
bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
if (backing_filename[0] != '\0') {
path_combine(backing_filename2, sizeof(backing_filename2),
filename, backing_filename);
- printf("backing file: %s (actual path: %s)\n",
+ printf("backing file: %s (actual path: %s)\n",
backing_filename,
backing_filename2);
}
@table @var
@item filename
is a disk image filename
-@item base_image
+@item base_image
is the read-only disk image which is used as base for a copy on
write image; the copy on write image only stores the modified data
-@item fmt
+@item fmt
is the disk image format. It is guessed automatically in most cases. The following formats are supported:
@table @code
CD-ROM images present for example in the Knoppix CD-ROMs.
@end table
-@item size
+@item size
is the disk image size in kilobytes. Optional suffixes @code{M}
-(megabyte) and @code{G} (gigabyte) are supported
+(megabyte) and @code{G} (gigabyte) are supported
@item output_filename
-is the destination disk image filename
+is the destination disk image filename
@item output_fmt
is the destination format
@item -c
indicates that target image must be compressed (qcow format only)
-@item -e
+@item -e
indicates that the target image must be encrypted (qcow format only)
@end table
@item create [-e] [-b @var{base_image}] [-f @var{fmt}] @var{filename} [@var{size}]
Create the new disk image @var{filename} of size @var{size} and format
-@var{fmt}.
+@var{fmt}.
If @var{base_image} is specified, then the image will record only the
differences from @var{base_image}. No size needs to be specified in
@itemize @minus
-@item
+@item
Full system emulation. In this mode, QEMU emulates a full system
(usually a PC), including a processor and various peripherals. It can
be used to launch an different Operating System without rebooting the
PC or to debug system code.
-@item
+@item
User mode emulation (Linux host only). In this mode, QEMU can launch
Linux processes compiled for one CPU on another CPU. It can be used to
launch the Wine Windows API emulator (@url{http://www.winehq.org}) or
QEMU generic features:
-@itemize
+@itemize
@item User space only or full system emulation.
@item Precise exceptions support.
-@item The virtual CPU is a library (@code{libqemu}) which can be used
+@item The virtual CPU is a library (@code{libqemu}) which can be used
in other projects (look at @file{qemu/tests/qruncom.c} to have an
example of user mode @code{libqemu} usage).
@end itemize
QEMU user mode emulation features:
-@itemize
+@itemize
@item Generic Linux system call converter, including most ioctls.
@item clone() emulation using native CPU clone() to use Linux scheduler for threads.
-@item Accurate signal handling by remapping host signals to target signals.
+@item Accurate signal handling by remapping host signals to target signals.
@end itemize
QEMU full system emulation features:
-@itemize
+@itemize
@item QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU.
@end itemize
QEMU x86 target features:
-@itemize
+@itemize
-@item The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation.
+@item The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation.
LDT/GDT and IDT are emulated. VM86 mode is also supported to run DOSEMU.
@item Support of host page sizes bigger than 4KB in user mode emulation.
@item QEMU can emulate itself on x86.
-@item An extensive Linux x86 CPU test program is included @file{tests/test-i386}.
+@item An extensive Linux x86 CPU test program is included @file{tests/test-i386}.
It can be used to test other x86 virtual CPUs.
@end itemize
Current QEMU limitations:
-@itemize
+@itemize
@item No SSE/MMX support (yet).
@item IPC syscalls are missing.
-@item The x86 segment limits and access rights are not tested at every
+@item The x86 segment limits and access rights are not tested at every
memory access (yet). Hopefully, very few OSes seem to rely on that for
normal use.
-@item On non x86 host CPUs, @code{double}s are used instead of the non standard
+@item On non x86 host CPUs, @code{double}s are used instead of the non standard
10 byte @code{long double}s of x86 for floating point emulation to get
maximum performances.
@itemize
-@item Full PowerPC 32 bit emulation, including privileged instructions,
+@item Full PowerPC 32 bit emulation, including privileged instructions,
FPU and MMU.
@item Can run most PowerPC Linux binaries.
Current QEMU limitations:
-@itemize
+@itemize
@item Tagged add/subtract instructions are not supported, but they are
probably not used.
instructions to build a function (see @file{op.h:dyngen_code()}).
In essence, the process is similar to [1], but more work is done at
-compile time.
+compile time.
A key idea to get optimal performances is that constant parameters can
be passed to the simple operations. For that purpose, dummy ELF
Correct translated code invalidation is done efficiently by maintaining
a linked list of every translated block contained in a given page. Other
-linked lists are also maintained to undo direct block chaining.
+linked lists are also maintained to undo direct block chaining.
Although the overhead of doing @code{mprotect()} calls is important,
most MSDOS programs can be emulated at reasonnable speed with QEMU and
@section Exception support
longjmp() is used when an exception such as division by zero is
-encountered.
+encountered.
The host SIGSEGV and SIGBUS signal handlers are used to get invalid
memory accesses. The exact CPU state can be retrieved because all the
In order to avoid flushing the translated code each time the MMU
mappings change, QEMU uses a physically indexed translation cache. It
-means that each basic block is indexed with its physical address.
+means that each basic block is indexed with its physical address.
When MMU mappings change, only the chaining of the basic blocks is
reset (i.e. a basic block can no longer jump directly to another one).
@table @asis
-@item [1]
+@item [1]
@url{http://citeseer.nj.nec.com/piumarta98optimizing.html}, Optimizing
direct threaded code by selective inlining (1998) by Ian Piumarta, Fabio
Riccardi.
Willows Software.
@item [7]
-@url{http://user-mode-linux.sourceforge.net/},
+@url{http://user-mode-linux.sourceforge.net/},
The User-mode Linux Kernel.
@item [8]
-@url{http://www.plex86.org/},
+@url{http://www.plex86.org/},
The new Plex86 project.
@item [9]
-@url{http://www.vmware.com/},
+@url{http://www.vmware.com/},
The VMWare PC virtualizer.
@item [10]
-@url{http://www.microsoft.com/windowsxp/virtualpc/},
+@url{http://www.microsoft.com/windowsxp/virtualpc/},
The VirtualPC PC virtualizer.
@item [11]
-@url{http://www.twoostwo.org/},
+@url{http://www.twoostwo.org/},
The TwoOStwo PC virtualizer.
@end table
/*
* QEMU readline utility
- *
+ *
* Copyright (c) 2003-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
}
term_hist_entry--;
if (term_hist_entry >= 0) {
- pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
+ pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
term_history[term_hist_entry]);
term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
}
char *cmdline;
nb_completions = 0;
-
+
cmdline = qemu_malloc(term_cmd_buf_index + 1);
if (!cmdline)
return;
/*
* QEMU SDL display driver
- *
+ *
* Copyright (c) 2003 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
{
SDL_Event ev1, *ev = &ev1;
int mod_state;
-
+
if (last_vm_running != vm_running) {
last_vm_running = vm_running;
sdl_update_caption();
toggle_full_screen(ds);
gui_keysym = 1;
break;
- case 0x02 ... 0x0a: /* '1' to '9' keys */
+ case 0x02 ... 0x0a: /* '1' to '9' keys */
/* Reset the modifiers sent to the current console */
reset_keys();
console_select(keycode - 0x02);
}
}
}
- if (is_graphic_console() && !gui_keysym)
+ if (is_graphic_console() && !gui_keysym)
sdl_process_key(&ev->key);
break;
case SDL_QUIT:
} else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) {
dz = 1;
}
-#endif
+#endif
sdl_send_mouse_event(dz);
}
}
}
}
-static void sdl_cleanup(void)
+static void sdl_cleanup(void)
{
SDL_Quit();
}
/* 0100nnnn10111010 lds <REG_N>,Y1 */{"lds",{A_REG_N,A_Y1},{HEX_4,REG_N,HEX_B,HEX_A}, arch_sh_dsp_up},
/* 0100nnnn01011010 lds <REG_N>,FPUL */{"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}, arch_sh2e_up},
-
+
/* 0100nnnn01101010 lds <REG_M>,FPSCR */{"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}, arch_sh2e_up},
/* 0100nnnn00000110 lds.l @<REG_N>+,MACH*/{"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}, arch_sh1_up},
/* 0100nnnn10110110 lds.l @<REG_N>+,Y1 */{"lds.l",{A_INC_N,A_Y1},{HEX_4,REG_N,HEX_B,HEX_6}, arch_sh_dsp_up},
/* 0100nnnn01010110 lds.l @<REG_M>+,FPUL*/{"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}, arch_sh2e_up},
-
+
/* 0100nnnn01100110 lds.l @<REG_M>+,FPSCR*/{"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}, arch_sh2e_up},
/* 0000000000111000 ldtlb */{"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}, arch_sh3_up},
/* 0000nnnn10111010 sts Y1,<REG_N> */{"sts",{A_Y1,A_REG_N},{HEX_0,REG_N,HEX_B,HEX_A}, arch_sh_dsp_up},
/* 0000nnnn01011010 sts FPUL,<REG_N> */{"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}, arch_sh2e_up},
-
+
/* 0000nnnn01101010 sts FPSCR,<REG_N> */{"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}, arch_sh2e_up},
/* 0100nnnn00000010 sts.l MACH,@-<REG_N>*/{"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}, arch_sh1_up},
/* 0100nnnn10110110 sts.l Y1,@-<REG_N> */{"sts.l",{A_Y1,A_DEC_N},{HEX_4,REG_N,HEX_B,HEX_2}, arch_sh_dsp_up},
/* 0100nnnn01010010 sts.l FPUL,@-<REG_N>*/{"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}, arch_sh2e_up},
-
+
/* 0100nnnn01100010 sts.l FPSCR,@-<REG_N>*/{"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}, arch_sh2e_up},
/* 0011nnnnmmmm1000 sub <REG_M>,<REG_N> */{"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}, arch_sh1_up},
/* 0011nnnnmmmm0001 1001dddddddddddd movu.w @(<DISP12>,<REG_M>),<REG_N> */
{"movu.w",{A_DISP_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_1,HEX_9,DISP0_12BY2}, arch_sh2a_nofpu_up | arch_op32},
-{ 0, {0}, {0}, 0 }
+{ 0, {0}, {0}, 0 }
};
#endif
while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
|| op->nibbles[3] != (unsigned) (insn & 0xf))
op++;
-
+
print_movxy (op,
(4 * ((insn & (is_movy ? 0x200 : 0x100)) == 0)
+ 2 * is_movy
---BEGIN---
Copyright (c) 1995,1996 Danny Gasparovski. All rights reserved.
-
+
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
/*
* QEMU BOOTP/DHCP server
- *
+ *
* 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
const uint8_t *p, *p_end;
int len, tag;
- *pmsg_type = 0;
+ *pmsg_type = 0;
p = buf;
p_end = buf + size;
while (p < p_end) {
tag = p[0];
if (tag == RFC1533_PAD) {
- p++;
+ p++;
} else if (tag == RFC1533_END) {
break;
} else {
/* extract exact DHCP msg type */
dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type);
dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type);
-
+
if (dhcp_msg_type == 0)
dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */
-
- if (dhcp_msg_type != DHCPDISCOVER &&
+
+ if (dhcp_msg_type != DHCPDISCOVER &&
dhcp_msg_type != DHCPREQUEST)
return;
/* XXX: this is a hack to get the client mac address */
memcpy(client_ethaddr, bp->bp_hwaddr, 6);
-
+
if ((m = m_get()) == NULL)
return;
m->m_data += if_maxlinkhdr;
*q++ = 1;
*q++ = DHCPACK;
}
-
+
if (dhcp_msg_type == DHCPDISCOVER ||
dhcp_msg_type == DHCPREQUEST) {
*q++ = RFC2132_SRV_ID;
*q++ = 0xff;
*q++ = 0xff;
*q++ = 0x00;
-
+
*q++ = RFC1533_GATEWAY;
*q++ = 4;
memcpy(q, &saddr.sin_addr, 4);
q += 4;
-
+
*q++ = RFC1533_DNS;
*q++ = 4;
dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
}
}
*q++ = RFC1533_END;
-
- m->m_len = sizeof(struct bootp_t) -
+
+ m->m_len = sizeof(struct bootp_t) -
sizeof(struct ip) - sizeof(struct udphdr);
udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
*
* This routine is very heavily used in the network
* code and should be modified for each CPU to be as fast as possible.
- *
+ *
* XXX Since we will never span more than 1 mbuf, we can optimise this
*/
u_int16_t s[2];
u_int32_t l;
} l_util;
-
+
if (m->m_len == 0)
goto cont;
w = mtod(m, u_int16_t *);
-
+
mlen = m->m_len;
-
+
if (len < mlen)
mlen = len;
len -= mlen;
while ((mlen -= 2) >= 0) {
sum += *w++;
}
-
+
if (byte_swapped) {
REDUCE;
sum <<= 8;
sum += s_util.s;
mlen = 0;
} else
-
+
mlen = -1;
} else if (mlen == -1)
s_util.c[0] = *(u_int8_t *)w;
-
+
cont:
#ifdef DEBUG
if (len) {
/*
* Copyright (c) 1995 Danny Gasparovski.
* Portions copyright (c) 2000 Kelly Price.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
extern char *strerror _P((int));
-/* Carry over one item from main.c so that the tty's restored.
+/* Carry over one item from main.c so that the tty's restored.
* Only done when the tty being used is /dev/tty --RedWolf */
extern struct termios slirp_tty_settings;
extern int slirp_tty_restore;
/* Close the old debugging file */
if (dfd)
fclose(dfd);
-
+
dfd = fopen(file,"w");
if (dfd != NULL) {
#if 0
{
u_char *pptr = (u_char *)dat;
int j,k;
-
+
n /= 16;
n++;
DEBUG_MISC((dfd, "PACKET DUMPED: \n"));
#if 0
/*
* Statistic routines
- *
+ *
* These will print statistics to the screen, the debug file (dfd), or
* a buffer, depending on "type", so that the stats can be sent over
* the link as well.
{
struct slirp_ifstats *is = &ttyp->ifstats;
char buff[512];
-
+
lprint(" \r\n");
-
+
if (if_comp & IF_COMPRESS)
strcpy(buff, "on");
else if (if_comp & IF_NOCOMPRESS)
allttystats()
{
struct ttys *ttyp;
-
+
for (ttyp = ttys; ttyp; ttyp = ttyp->next)
ttystats(ttyp);
}
void
ipstats()
{
- lprint(" \r\n");
+ lprint(" \r\n");
lprint("IP stats:\r\n");
lprint(" %6d total packets received (%d were unaligned)\r\n",
vjstats()
{
lprint(" \r\n");
-
+
lprint("VJ compression stats:\r\n");
-
+
lprint(" %6d outbound packets (%d compressed)\r\n",
comp_s.sls_packets, comp_s.sls_compressed);
lprint(" %6d searches for connection stats (%d misses)\r\n",
lprint(" \r\n");
lprint("TCP stats:\r\n");
-
+
lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal);
lprint(" %6d data packets (%d bytes)\r\n",
tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte);
lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup);
lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl);
lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin);
-
- lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal);
+
+ lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal);
lprint(" %6d acks (for %d bytes)\r\n",
tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte);
lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack);
tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte);
lprint(" %6d completely duplicate packets (%d bytes)\r\n",
tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte);
-
+
lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n",
tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte);
lprint(" %6d out-of-order packets (%d bytes)\r\n",
lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum);
lprint(" %6d discarded for bad header offset fields\r\n",
tcpstat.tcps_rcvbadoff);
-
+
lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt);
lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts);
lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects);
lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack);
lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat);
lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss);
-
-
+
+
/* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */
/* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */
{
struct mbuf *m;
int i;
-
+
lprint(" \r\n");
-
+
lprint("Mbuf stats:\r\n");
lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max);
-
+
i = 0;
for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next)
i++;
lprint(" %6d mbufs on free list\r\n", i);
-
+
i = 0;
for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next)
i++;
struct socket *so;
lprint(" \r\n");
-
+
lprint(
"Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n");
-
+
for (so = tcb.so_next; so != &tcb; so = so->so_next) {
-
+
n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE");
while (n < 17)
buff[n++] = ' ';
inet_ntoa(so->so_faddr), ntohs(so->so_fport),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
}
-
+
for (so = udb.so_next; so != &udb; so = so->so_next) {
-
+
n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000);
while (n < 17)
buff[n++] = ' ';
int exit_status;
{
struct ttys *ttyp;
-
+
DEBUG_CALL("slirp_exit");
DEBUG_ARG("exit_status = %d", exit_status);
if (!dfd)
debug_init("slirp_stats", 0xf);
lprint_arg = (char **)&dfd;
-
+
ipstats();
tcpstats();
udpstats();
allttystats();
vjstats();
}
-
+
for (ttyp = ttys; ttyp; ttyp = ttyp->next)
tty_detached(ttyp, 1);
-
+
if (slirp_forked) {
/* Menendez time */
if (kill(getppid(), SIGQUIT) < 0)
lprint("Couldn't kill parent process %ld!\n",
(long) getppid());
}
-
+
/* Restore the terminal if we gotta */
if(slirp_tty_restore)
tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
{
int ret;
int total;
-
+
/* This should succeed most of the time */
ret = send(fd, bptr, n,0);
if (ret == n || ret <= 0)
return ret;
-
+
/* Didn't write everything, go into the loop */
total = ret;
while (n > total) {
/*
* if_input - read() the tty, do "top level" processing (ie: check for any escapes),
* and pass onto (*ttyp->if_input)
- *
+ *
* XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet.
*/
#define INBUFF_SIZE 2048 /* XXX */
{
u_char if_inbuff[INBUFF_SIZE];
int if_n;
-
+
DEBUG_CALL("if_input");
DEBUG_ARG("ttyp = %lx", (long)ttyp);
-
+
if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0);
-
+
DEBUG_MISC((dfd, " read %d bytes\n", if_n));
-
+
if (if_n <= 0) {
if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) {
if (ttyp->up)
}
}
ttyp->ones = ttyp->zeros = 0;
-
+
(*ttyp->if_input)(ttyp, if_inbuff, if_n);
}
-#endif
-
+#endif
+
/*
* if_output: Queue packet into an output queue.
- * There are 2 output queue's, if_fastq and if_batchq.
+ * There are 2 output queue's, if_fastq and if_batchq.
* Each output queue is a doubly linked list of double linked lists
* of mbufs, each list belonging to one "session" (socket). This
* way, we can output packets fairly by sending one packet from each
* session, instead of all the packets from one session, then all packets
- * from the next session, etc. Packets on the if_fastq get absolute
+ * from the next session, etc. Packets on the if_fastq get absolute
* priority, but if one session hogs the link, it gets "downgraded"
* to the batchq until it runs out of packets, then it'll return
* to the fastq (eg. if the user does an ls -alR in a telnet session,
{
struct mbuf *ifq;
int on_fastq = 1;
-
+
DEBUG_CALL("if_output");
DEBUG_ARG("so = %lx", (long)so);
DEBUG_ARG("ifm = %lx", (long)ifm);
-
+
/*
* First remove the mbuf from m_usedlist,
* since we're gonna use m_next and m_prev ourselves
remque(ifm);
ifm->m_flags &= ~M_USEDLIST;
}
-
+
/*
- * See if there's already a batchq list for this session.
+ * See if there's already a batchq list for this session.
* This can include an interactive session, which should go on fastq,
* but gets too greedy... hence it'll be downgraded from fastq to batchq.
* We mustn't put this packet back on the fastq (or we'll send it out of order)
goto diddit;
}
}
-
+
/* No match, check which queue to put it on */
if (so && (so->so_iptos & IPTOS_LOWDELAY)) {
ifq = if_fastq.ifq_prev;
}
} else
ifq = if_batchq.ifq_prev;
-
+
/* Create a new doubly linked list for this session */
ifm->ifq_so = so;
ifs_init(ifm);
insque(ifm, ifq);
-
+
diddit:
++if_queued;
-
+
if (so) {
/* Update *_queued */
so->so_queued++;
* have been sent over the link
* (XXX These are arbitrary numbers, probably not optimal..)
*/
- if (on_fastq && ((so->so_nqueued >= 6) &&
+ if (on_fastq && ((so->so_nqueued >= 6) &&
(so->so_nqueued - so->so_queued) >= 3)) {
-
+
/* Remove from current queue... */
remque(ifm->ifs_next);
-
+
/* ...And insert in the new. That'll teach ya! */
insque(ifm->ifs_next, &if_batchq);
}
if_start(void)
{
struct mbuf *ifm, *ifqt;
-
+
DEBUG_CALL("if_start");
-
+
if (if_queued == 0)
return; /* Nothing to do */
-
+
again:
/* check if we can really output */
if (!slirp_can_output())
ifm = next_m;
else
ifm = if_batchq.ifq_next;
-
+
/* Set which packet to send on next iteration */
next_m = ifm->ifq_next;
}
ifqt = ifm->ifq_prev;
remque(ifm);
--if_queued;
-
+
/* If there are more packets for this session, re-queue them */
if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
insque(ifm->ifs_next, ifqt);
ifs_remque(ifm);
}
-
+
/* Update so_queued */
if (ifm->ifq_so) {
if (--ifm->ifq_so->so_queued == 0)
/* If there's no more queued, reset nqueued */
ifm->ifq_so->so_nqueued = 0;
}
-
+
/* Encapsulate the packet for sending */
if_encap(ifm->m_data, ifm->m_len);
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
u_int in_bytes; /* Input bytes */
u_int in_errpkts; /* Input Error Packets */
u_int in_errbytes; /* Input Error Bytes */
-
+
u_int bytes_saved; /* Number of bytes that compression "saved" */
/* ie: number of bytes that didn't need to be sent over the link
* because of compression */
-
+
u_int in_mbad; /* Bad incoming packets */
};
/* INFO (15) */ 0,
/* INFO REPLY (16) */ 0,
/* ADDR MASK (17) */ 0,
-/* ADDR MASK REPLY (18) */ 0
+/* ADDR MASK REPLY (18) */ 0
};
/*
register struct ip *ip=mtod(m, struct ip *);
int icmplen=ip->ip_len;
/* int code; */
-
+
DEBUG_CALL("icmp_input");
DEBUG_ARG("m = %lx", (long )m);
DEBUG_ARG("m_len = %d", m->m_len);
icmpstat.icps_received++;
-
+
/*
* Locate icmp structure in mbuf, and check
* that its not corrupted and of at least minimum length.
}
m->m_len += hlen;
m->m_data -= hlen;
-
+
/* icmpstat.icps_inhist[icp->icmp_type]++; */
/* code = icp->icmp_code; */
struct sockaddr_in addr;
if ((so = socreate()) == NULL) goto freeit;
if(udp_attach(so) == -1) {
- DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
+ DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
errno,strerror(errno)));
sofree(so);
m_free(m);
so->so_iptos = ip->ip_tos;
so->so_type = IPPROTO_ICMP;
so->so_state = SS_ISFCONNECTED;
-
+
/* Send the packet */
addr.sin_family = AF_INET;
if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
(struct sockaddr *)&addr, sizeof(addr)) == -1) {
DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",
errno,strerror(errno)));
- icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
+ icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
udp_detach(so);
}
} /* if ip->ip_dst.s_addr == alias_addr.s_addr */
icmpstat.icps_notsupp++;
m_freem(m);
break;
-
+
default:
icmpstat.icps_badtype++;
m_freem(m);
* mbuf *msrc is used as a template, but is NOT m_free()'d.
* It is reported as the bad ip packet. The header should
* be fully correct and in host byte order.
- * ICMP fragmentation is illegal. All machines must accept 576 bytes in one
+ * ICMP fragmentation is illegal. All machines must accept 576 bytes in one
* packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548
*/
/* check msrc */
if(!msrc) goto end_error;
ip = mtod(msrc, struct ip *);
-#if DEBUG
+#if DEBUG
{ char bufa[20], bufb[20];
strcpy(bufa, inet_ntoa(ip->ip_src));
strcpy(bufb, inet_ntoa(ip->ip_dst));
/* make the header of the reply packet */
ip = mtod(m, struct ip *);
hlen= sizeof(struct ip ); /* no options in reply */
-
+
/* fill in icmp */
- m->m_data += hlen;
+ m->m_data += hlen;
m->m_len -= hlen;
icp = mtod(m, struct icmp *);
else if(s_ip_len>ICMP_MAXDATALEN) /* maximum size */
s_ip_len=ICMP_MAXDATALEN;
- m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */
+ m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */
/* min. size = 8+sizeof(struct ip)+8 */
/* fill in ip */
ip->ip_hl = hlen >> 2;
ip->ip_len = m->m_len;
-
+
ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */
ip->ip_ttl = MAXTTL;
ip->ip_src = alias_addr;
(void ) ip_output((struct socket *)NULL, m);
-
+
icmpstat.icps_reflect++;
end_error:
/*
* Changes and additions relating to SLiRP are
* Copyright (c) 1995 Danny Gasparovski.
- *
+ *
* Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
{
register struct ip *ip;
int hlen;
-
+
DEBUG_CALL("ip_input");
DEBUG_ARG("m = %lx", (long)m);
DEBUG_ARG("m_len = %d", m->m_len);
ipstat.ips_total++;
-
+
if (m->m_len < sizeof (struct ip)) {
ipstat.ips_toosmall++;
return;
}
-
+
ip = mtod(m, struct ip *);
-
+
if (ip->ip_v != IPVERSION) {
ipstat.ips_badvers++;
goto bad;
}
/* keep ip header intact for ICMP reply
- * ip->ip_sum = cksum(m, hlen);
- * if (ip->ip_sum) {
+ * ip->ip_sum = cksum(m, hlen);
+ * if (ip->ip_sum) {
*/
if(cksum(m,hlen)) {
ipstat.ips_badsum++;
* (We could look in the reassembly queue to see
* if the packet was previously fragmented,
* but it's not worth the time; just let them time out.)
- *
+ *
* XXX This should fail, don't fragment yet
*/
if (ip->ip_off &~ IP_DF) {
ip->ip_len -= hlen;
if (ip->ip_off & IP_MF)
((struct ipasfrag *)ip)->ipf_mff |= 1;
- else
+ else
((struct ipasfrag *)ip)->ipf_mff &= ~1;
ip->ip_off <<= 3;
register struct ipasfrag *q;
int hlen = ip->ip_hl << 2;
int i, next;
-
+
DEBUG_CALL("ip_reass");
DEBUG_ARG("ip = %lx", (long)ip);
DEBUG_ARG("fp = %lx", (long)fp);
q = (struct ipasfrag *)fp;
goto insert;
}
-
+
/*
* Find a segment which begins after this one does.
*/
ip = (struct ipasfrag *)(m->m_ext + delta);
}
- /* DEBUG_ARG("ip = %lx", (long)ip);
+ /* DEBUG_ARG("ip = %lx", (long)ip);
* ip=(struct ipasfrag *)m->m_data; */
ip->ip_len = next;
ip_slowtimo()
{
register struct ipq *fp;
-
+
DEBUG_CALL("ip_slowtimo");
-
+
fp = (struct ipq *) ipq.next;
if (fp == 0)
return;
i = m->m_len - (sizeof (struct ip) + olen);
memcpy(opts, opts + olen, (unsigned)i);
m->m_len -= olen;
-
+
ip->ip_hl = sizeof(struct ip) >> 2;
}
DEBUG_CALL("ip_output");
DEBUG_ARG("so = %lx", (long)so);
DEBUG_ARG("m0 = %lx", (long)m0);
-
+
/* We do no options */
/* if (opt) {
* m = ip_insertoptions(m, opt, &len);
* goto bad;
* }
*/
-
+
/*
* If small enough for interface, can just send directly.
*/
ipstat.ips_cantfrag++;
goto bad;
}
-
+
len = (if_mtu - hlen) &~ 7; /* ip databytes per packet */
if (len < 8) {
error = -1;
m->m_data += if_maxlinkhdr;
mhip = mtod(m, struct ip *);
*mhip = *ip;
-
+
/* No options */
/* if (hlen > sizeof (struct ip)) {
* mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
mhip->ip_off |= IP_MF;
if (off + len >= (u_int16_t)ip->ip_len)
len = (u_int16_t)ip->ip_len - off;
- else
+ else
mhip->ip_off |= IP_MF;
mhip->ip_len = htons((u_int16_t)(len + mhlen));
-
+
if (m_copy(m, m0, off, len) < 0) {
error = -1;
goto sendorfree;
}
-
+
mhip->ip_off = htons((u_int16_t)mhip->ip_off);
mhip->ip_sum = 0;
mhip->ip_sum = cksum(m, mhlen);
void slirp_init(void);
-void slirp_select_fill(int *pnfds,
+void slirp_select_fill(int *pnfds,
fd_set *readfds, fd_set *writefds, fd_set *xfds);
void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds);
int slirp_can_output(void);
void slirp_output(const uint8_t *pkt, int pkt_len);
-int slirp_redir(int is_udp, int host_port,
+int slirp_redir(int is_udp, int host_port,
struct in_addr guest_addr, int guest_port);
-int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
+int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
int guest_port);
extern const char *tftp_prefix;
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
* Find a nice value for msize
* XXX if_maxlinkhdr already in mtu
*/
- msize = (if_mtu>if_mru?if_mtu:if_mru) +
+ msize = (if_mtu>if_mru?if_mtu:if_mru) +
if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
}
/*
* Get an mbuf from the free list, if there are none
* malloc one
- *
+ *
* Because fragmentation can occur if we alloc new mbufs and
* free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
* which tells m_free to actually free() it
{
register struct mbuf *m;
int flags = 0;
-
+
DEBUG_CALL("m_get");
-
+
if (m_freelist.m_next == &m_freelist) {
m = (struct mbuf *)malloc(msize);
if (m == NULL) goto end_error;
m = m_freelist.m_next;
remque(m);
}
-
+
/* Insert it in the used list */
insque(m,&m_usedlist);
m->m_flags = (flags | M_USEDLIST);
-
+
/* Initialise it */
m->m_size = msize - sizeof(struct m_hdr);
m->m_data = m->m_dat;
m_free(m)
struct mbuf *m;
{
-
+
DEBUG_CALL("m_free");
DEBUG_ARG("m = %lx", (long )m);
-
+
if(m) {
/* Remove from m_usedlist */
if (m->m_flags & M_USEDLIST)
remque(m);
-
+
/* If it's M_EXT, free() it */
if (m->m_flags & M_EXT)
free(m->m_ext);
*/
if (M_FREEROOM(m) < n->m_len)
m_inc(m,m->m_size+MINCSIZE);
-
+
memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
m->m_len += n->m_len;
m->m_ext = (char *)realloc(m->m_ext,size);
/* if (m->m_ext == NULL)
* return (struct mbuf *)NULL;
- */
+ */
m->m_data = m->m_ext + datasize;
} else {
char *dat;
* return (struct mbuf *)NULL;
*/
memcpy(dat, m->m_dat, m->m_size);
-
+
m->m_ext = dat;
m->m_data = m->m_ext + datasize;
m->m_flags |= M_EXT;
}
-
+
m->m_size = size;
}
void *dat;
{
struct mbuf *m;
-
+
DEBUG_CALL("dtom");
DEBUG_ARG("dat = %lx", (long )dat);
return m;
}
}
-
+
DEBUG_ERROR((dfd, "dtom failed"));
-
+
return (struct mbuf *)0;
}
int mh_size; /* Size of data */
struct socket *mh_so;
-
+
caddr_t mh_data; /* Location of data */
int mh_len; /* Amount of data in this mbuf */
};
-/*
+/*
* How much room is in the mbuf, from m_data to the end of the mbuf
*/
#define M_ROOM(m) ((m->m_flags & M_EXT)? \
struct mbstat {
int mbs_alloced; /* Number of mbufs allocated */
-
+
};
extern struct mbstat mbstat;
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
+ *
* Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
if (x_display)
lprint("X Redir: Redirecting to display %d\r\n", x_display);
}
-
+
return CFG_OK;
}
int screen;
{
int i;
-
+
if (x_port >= 0) {
lprint("X Redir: X already being redirected.\r\n");
show_x(0, 0);
{
char buff[256];
struct hostent *he = NULL;
-
+
if (gethostname(buff,256) == 0)
he = gethostbyname(buff);
if (he)
int port;
{
struct ex_list *tmp_ptr;
-
+
/* First, check if the port is "bound" */
for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
return -1;
}
-
+
tmp_ptr = *ex_ptr;
*ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
(*ex_ptr)->ex_fport = port;
#ifdef HAVE_GRANTPT
char *ptr;
-
+
if ((master = open("/dev/ptmx", O_RDWR)) < 0 ||
grantpt(master) < 0 ||
unlockpt(master) < 0 ||
close(master);
return -1;
}
-
+
if ((slave = open(ptr, O_RDWR)) < 0 ||
ioctl(slave, I_PUSH, "ptem") < 0 ||
ioctl(slave, I_PUSH, "ldterm") < 0 ||
close(slave);
return -1;
}
-
+
*amaster = master;
*aslave = slave;
return 0;
-
+
#else
-
+
static char line[] = "/dev/ptyXX";
register const char *cp1, *cp2;
-
+
for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
line[8] = *cp1;
for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
* process, which connects to this socket, after which we
* exec the wanted program. If something (strange) happens,
* the accept() call could block us forever.
- *
+ *
* do_pty = 0 Fork/exec inetd style
* do_pty = 1 Fork/exec using slirp.telnetd
* do_ptr = 2 Fork/exec using pty
char *bptr;
char *curarg;
int c, i, ret;
-
+
DEBUG_CALL("fork_exec");
DEBUG_ARG("so = %lx", (long)so);
DEBUG_ARG("ex = %lx", (long)ex);
DEBUG_ARG("do_pty = %lx", (long)do_pty);
-
+
if (do_pty == 2) {
if (slirp_openpty(&master, &s) == -1) {
lprint("Error: openpty failed: %s\n", strerror(errno));
addr.sin_family = AF_INET;
addr.sin_port = 0;
addr.sin_addr.s_addr = INADDR_ANY;
-
+
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
listen(s, 1) < 0) {
lprint("Error: inet socket: %s\n", strerror(errno));
closesocket(s);
-
+
return 0;
}
}
-
+
switch(fork()) {
case -1:
lprint("Error: fork failed: %s\n", strerror(errno));
if (do_pty == 2)
close(master);
return 0;
-
+
case 0:
/* Set the DISPLAY */
if (do_pty == 2) {
ret = connect(s, (struct sockaddr *)&addr, addrlen);
} while (ret < 0 && errno == EINTR);
}
-
+
#if 0
if (x_port >= 0) {
#ifdef HAVE_SETENV
putenv(buff);
#endif
}
-#endif
+#endif
dup2(s, 0);
dup2(s, 1);
dup2(s, 2);
for (s = 3; s <= 255; s++)
close(s);
-
+
i = 0;
bptr = strdup(ex); /* No need to free() this */
if (do_pty == 1) {
*bptr++ = (char)0;
argv[i++] = strdup(curarg);
} while (c);
-
+
argv[i] = 0;
execvp(argv[0], argv);
-
+
/* Ooops, failed, let's tell the user why */
{
char buff[256];
-
- sprintf(buff, "Error: execvp of %s failed: %s\n",
+
+ sprintf(buff, "Error: execvp of %s failed: %s\n",
argv[0], strerror(errno));
write(2, buff, strlen(buff)+1);
}
close(0); close(1); close(2); /* XXX */
exit(1);
-
+
default:
if (do_pty == 2) {
close(s);
setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
}
fd_nonblock(so->s);
-
+
/* Append the telnet options now */
if (so->so_m != 0 && do_pty == 1) {
sbappend(so, so->so_m);
so->so_m = 0;
}
-
+
return 1;
}
}
const char *str;
{
char *bptr;
-
+
bptr = (char *)malloc(strlen(str)+1);
strcpy(bptr, str);
-
+
return bptr;
}
#endif
#endif
struct sockaddr_in sock_in;
char buff[256];
-
+
ret = -1;
if (slirp_socket_passwd) {
s = socket(AF_INET, SOCK_STREAM, 0);
#endif
slirp_exit(0);
}
-
-
+
+
void
snooze()
{
sigset_t s;
int i;
-
+
/* Don't need our data anymore */
/* XXX This makes SunOS barf */
/* brk(0); */
-
+
/* Close all fd's */
for (i = 255; i >= 0; i--)
close(i);
-
+
signal(SIGQUIT, slirp_exit);
signal(SIGHUP, snooze_hup);
sigemptyset(&s);
-
+
/* Wait for any signal */
sigsuspend(&s);
-
+
/* Just in case ... */
exit(255);
}
int n;
fd_set readfds;
struct ttys *ttyp;
-
+
/* Don't need our data anymore */
/* XXX This makes SunOS barf */
/* brk(0); */
-
+
signal(SIGQUIT, slirp_exit);
signal(SIGHUP, slirp_exit);
signal(SIGINT, slirp_exit);
signal(SIGTERM, slirp_exit);
-
+
/* Fudge to get term_raw and term_restore to work */
if (NULL == (ttyp = tty_attach (0, slirp_tty))) {
lprint ("Error: tty_attach failed in misc.c:relay()\r\n");
ttyp->fd = 0;
ttyp->flags |= TTY_CTTY;
term_raw(ttyp);
-
+
while (1) {
FD_ZERO(&readfds);
-
+
FD_SET(0, &readfds);
FD_SET(s, &readfds);
-
+
n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
-
+
if (n <= 0)
slirp_exit(0);
-
+
if (FD_ISSET(0, &readfds)) {
n = read(0, buf, 8192);
if (n <= 0)
if (n <= 0)
slirp_exit(0);
}
-
+
if (FD_ISSET(s, &readfds)) {
n = read(s, buf, 8192);
if (n <= 0)
slirp_exit(0);
}
}
-
+
/* Just in case.... */
exit(1);
}
#endif
{
va_list args;
-
+
#ifdef __STDC__
va_start(args, format);
#else
int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data;
int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data;
int deltap = lprint_ptr - lprint_sb->sb_data;
-
+
lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data,
lprint_sb->sb_datalen + TCP_SNDSPACE);
-
+
/* Adjust all values */
lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw;
lprint_sb->sb_rptr = lprint_sb->sb_data + deltar;
lprint_ptr = lprint_sb->sb_data + deltap;
-
+
lprint_sb->sb_datalen += TCP_SNDSPACE;
}
}
-#endif
+#endif
if (lprint_print)
lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
-
+
/* Check if they want output to be logged to file as well */
if (lfd) {
- /*
+ /*
* Remove \r's
* otherwise you'll get ^M all over the file
*/
int len = strlen(format);
char *bptr1, *bptr2;
-
+
bptr1 = bptr2 = strdup(format);
-
+
while (len--) {
if (*bptr1 == '\r')
memcpy(bptr1, bptr1+1, len+1);
char *buff3 = buff4;
struct emu_t *emup;
struct socket *so;
-
+
if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
lprint("Error: Bad arguments\r\n");
return;
}
-
+
if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
lport = 0;
if (sscanf(buff1, "%d", &fport) != 1) {
return;
}
}
-
+
if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
buff3 = 0;
if (sscanf(buff2, "%256s", buff1) != 1) {
return;
}
}
-
+
if (buff3) {
if (strcmp(buff3, "lowdelay") == 0)
tos = IPTOS_LOWDELAY;
return;
}
}
-
+
if (strcmp(buff1, "ftp") == 0)
emu = EMU_FTP;
else if (strcmp(buff1, "irc") == 0)
lprint("Error: Unknown service\r\n");
return;
}
-
+
/* First, check that it isn't already emulated */
for (emup = tcpemu; emup; emup = emup->next) {
if (emup->lport == lport && emup->fport == fport) {
return;
}
}
-
+
/* link it */
emup = (struct emu_t *)malloc(sizeof (struct emu_t));
emup->lport = (u_int16_t)lport;
emup->emu = emu;
emup->next = tcpemu;
tcpemu = emup;
-
+
/* And finally, mark all current sessions, if any, as being emulated */
for (so = tcb.so_next; so != &tcb; so = so->so_next) {
if ((lport && lport == ntohs(so->so_lport)) ||
so->so_iptos = tos;
}
}
-
+
lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
}
{
struct timeval t;
fd_set fdset;
-
+
FD_ZERO(&fdset);
-
+
t.tv_sec = 0;
t.tv_usec = usec * 1000;
-
+
select(0, &fdset, &fdset, &fdset, &t);
}
{
#ifdef FIONBIO
int opt = 1;
-
+
ioctlsocket(fd, FIONBIO, &opt);
#else
int opt;
-
+
opt = fcntl(fd, F_GETFL, 0);
opt |= O_NONBLOCK;
fcntl(fd, F_SETFL, opt);
{
#ifdef FIONBIO
int opt = 0;
-
+
ioctlsocket(fd, FIONBIO, &opt);
#else
int opt;
-
+
opt = fcntl(fd, F_GETFL, 0);
opt &= ~O_NONBLOCK;
fcntl(fd, F_SETFL, opt);
int fd0[2];
int s;
char buff[256];
-
+
DEBUG_CALL("rsh_exec");
DEBUG_ARG("so = %lx", (long)so);
-
+
if (pipe(fd)<0) {
lprint("Error: pipe failed: %s\n", strerror(errno));
return 0;
return 0;
}
#endif
-
+
switch(fork()) {
case -1:
lprint("Error: fork failed: %s\n", strerror(errno));
close(fd0[0]);
close(fd0[1]);
return 0;
-
+
case 0:
close(fd[0]);
close(fd0[0]);
-
+
/* Set the DISPLAY */
if (x_port >= 0) {
#ifdef HAVE_SETENV
putenv(buff);
#endif
}
-
+
dup2(fd0[1], 0);
dup2(fd0[1], 1);
dup2(fd[1], 2);
for (s = 3; s <= 255; s++)
close(s);
-
+
execlp("rsh","rsh","-l", user, host, args, NULL);
-
+
/* Ooops, failed, let's tell the user why */
-
- sprintf(buff, "Error: execlp of %s failed: %s\n",
+
+ sprintf(buff, "Error: execlp of %s failed: %s\n",
"rsh", strerror(errno));
write(2, buff, strlen(buff)+1);
close(0); close(1); close(2); /* XXX */
exit(1);
-
+
default:
close(fd[1]);
close(fd0[1]);
ns->s=fd[0];
so->s=fd0[0];
-
+
return 1;
}
}
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
/* Done as a macro in socket.h */
/* int
- * sbspace(struct sockbuff *sb)
+ * sbspace(struct sockbuff *sb)
* {
* return SB_DATALEN - sb->sb_cc;
* }
void
sbdrop(sb, num)
struct sbuf *sb;
- int num;
+ int num;
{
- /*
+ /*
* We can only drop how much we have
- * This should never succeed
+ * This should never succeed
*/
if(num > sb->sb_cc)
num = sb->sb_cc;
sb->sb_rptr += num;
if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
sb->sb_rptr -= sb->sb_datalen;
-
+
}
void
struct mbuf *m;
{
int ret = 0;
-
+
DEBUG_CALL("sbappend");
DEBUG_ARG("so = %lx", (long)so);
DEBUG_ARG("m = %lx", (long)m);
DEBUG_ARG("m->m_len = %d", m->m_len);
-
+
/* Shouldn't happen, but... e.g. foreign host closes connection */
if (m->m_len <= 0) {
m_free(m);
return;
}
-
+
/*
* If there is urgent data, call sosendoob
* if not all was sent, sowrite will take care of the rest
sosendoob(so);
return;
}
-
+
/*
* We only write if there's nothing in the buffer,
* ottherwise it'll arrive out of order, and hence corrupt
*/
if (!so->so_rcv.sb_cc)
ret = send(so->s, m->m_data, m->m_len, 0);
-
+
if (ret <= 0) {
- /*
+ /*
* Nothing was written
* It's possible that the socket has closed, but
* we don't need to check because if it has closed,
struct mbuf *m;
{
int len, n, nn;
-
+
len = m->m_len;
if (sb->sb_wptr < sb->sb_rptr) {
char *to;
{
char *from;
-
+
from = sb->sb_rptr + off;
if (from >= sb->sb_data + sb->sb_datalen)
from -= sb->sb_datalen;
memcpy(to+off,sb->sb_data,len);
}
}
-
+
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
/* virtual address alias for host */
struct in_addr alias_addr;
-const uint8_t special_ethaddr[6] = {
+const uint8_t special_ethaddr[6] = {
0x52, 0x54, 0x00, 0x12, 0x35, 0x00
};
DWORD ret;
IP_ADDR_STRING *pIPAddr;
struct in_addr tmp_addr;
-
+
FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
BufLen = sizeof(FIXED_INFO);
-
+
if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
if (FixedInfo) {
GlobalFree(FixedInfo);
}
FixedInfo = GlobalAlloc(GPTR, BufLen);
}
-
+
if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
if (FixedInfo) {
}
return -1;
}
-
+
pIPAddr = &(FixedInfo->DnsServerList);
inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
*pdns_addr = tmp_addr;
#if 0
printf( "DNS Servers:\n" );
printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String );
-
+
pIPAddr = FixedInfo -> DnsServerList.Next;
while ( pIPAddr ) {
printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String );
FILE *f;
int found = 0;
struct in_addr tmp_addr;
-
+
f = fopen("/etc/resolv.conf", "r");
if (!f)
return -1;
void slirp_init(void)
{
// debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
-
+
#ifdef _WIN32
{
WSADATA Data;
static void updtime(void)
{
gettimeofday(&tt, 0);
-
+
curtime = (u_int)tt.tv_sec * (u_int)1000;
curtime += (u_int)tt.tv_usec / (u_int)1000;
-
+
if ((tt.tv_usec % 1000) >= 500)
curtime++;
}
#endif
-void slirp_select_fill(int *pnfds,
+void slirp_select_fill(int *pnfds,
fd_set *readfds, fd_set *writefds, fd_set *xfds)
{
struct socket *so, *so_next;
global_readfds = NULL;
global_writefds = NULL;
global_xfds = NULL;
-
+
nfds = *pnfds;
/*
* First, TCP sockets
*/
do_slowtimo = 0;
if (link_up) {
- /*
+ /*
* *_slowtimo needs calling if there are IP fragments
* in the fragment queue, or there are TCP connections active
*/
do_slowtimo = ((tcb.so_next != &tcb) ||
((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
-
+
for (so = tcb.so_next; so != &tcb; so = so_next) {
so_next = so->so_next;
-
+
/*
* See if we need a tcp_fasttimo
*/
if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
time_fasttimo = curtime; /* Flag when we want a fasttimo */
-
+
/*
* NOFDREF can include still connecting to local-host,
* newly socreated() sockets etc. Don't want to select these.
*/
if (so->so_state & SS_NOFDREF || so->s == -1)
continue;
-
+
/*
* Set for reading sockets which are accepting
*/
UPD_NFDS(so->s);
continue;
}
-
+
/*
* Set for writing sockets which are connecting
*/
UPD_NFDS(so->s);
continue;
}
-
+
/*
* Set for writing if we are connected, can send more, and
* we have something to send
FD_SET(so->s, writefds);
UPD_NFDS(so->s);
}
-
+
/*
* Set for reading (and urgent data) if we are connected, can
* receive more, and we have room for it XXX /2 ?
UPD_NFDS(so->s);
}
}
-
+
/*
* UDP sockets
*/
for (so = udb.so_next; so != &udb; so = so_next) {
so_next = so->so_next;
-
+
/*
* See if it's timed out
*/
} else
do_slowtimo = 1; /* Let socket expire */
}
-
+
/*
* When UDP packets are received from over the
* link, they're sendto()'d straight away, so
}
}
}
-
+
/*
* Setup timeout to use minimum CPU usage, especially when idle
*/
-
- /*
+
+ /*
* First, see the timeout needed by *timo
*/
timeout.tv_sec = 0;
timeout.tv_usec = 0;
else if (timeout.tv_usec > 510000)
timeout.tv_usec = 510000;
-
+
/* Can only fasttimo if we also slowtimo */
if (time_fasttimo) {
tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
if (tmp_time < 0)
tmp_time = 0;
-
+
/* Choose the smallest of the 2 */
if (tmp_time < timeout.tv_usec)
timeout.tv_usec = (u_int)tmp_time;
}
}
*pnfds = nfds;
-}
+}
void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
{
/* Update time */
updtime();
-
+
/*
- * See if anything has timed out
+ * See if anything has timed out
*/
if (link_up) {
if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
last_slowtimo = curtime;
}
}
-
+
/*
* Check sockets
*/
*/
for (so = tcb.so_next; so != &tcb; so = so_next) {
so_next = so->so_next;
-
+
/*
* FD_ISSET is meaningless on these sockets
* (and they can crash the program)
*/
if (so->so_state & SS_NOFDREF || so->s == -1)
continue;
-
+
/*
* Check for URG data
* This will soread as well, so no need to
continue;
} /* else */
ret = soread(so);
-
+
/* Output it if we read something */
if (ret > 0)
tcp_output(sototcpcb(so));
}
-
+
/*
* Check sockets for writing
*/
if (so->so_state & SS_ISFCONNECTING) {
/* Connected */
so->so_state &= ~SS_ISFCONNECTING;
-
+
ret = send(so->s, &ret, 0, 0);
if (ret < 0) {
/* XXXXX Must fix, zero bytes is a NOP */
if (errno == EAGAIN || errno == EWOULDBLOCK ||
errno == EINPROGRESS || errno == ENOTCONN)
continue;
-
+
/* else failed */
so->so_state = SS_NOFDREF;
}
/* else so->so_state &= ~SS_ISFCONNECTING; */
-
+
/*
* Continue tcp_input
*/
} else
ret = sowrite(so);
/*
- * XXXXX If we wrote something (a lot), there
+ * XXXXX If we wrote something (a lot), there
* could be a need for a window update.
* In the worst case, the remote will send
* a window probe to get things going again
*/
}
-
+
/*
* Probe a still-connecting, non-blocking socket
* to check if it's still alive
#ifdef PROBE_CONN
if (so->so_state & SS_ISFCONNECTING) {
ret = recv(so->s, (char *)&ret, 0,0);
-
+
if (ret < 0) {
/* XXX */
if (errno == EAGAIN || errno == EWOULDBLOCK ||
errno == EINPROGRESS || errno == ENOTCONN)
continue; /* Still connecting, continue */
-
+
/* else failed */
so->so_state = SS_NOFDREF;
-
+
/* tcp_input will take care of it */
} else {
ret = send(so->s, &ret, 0,0);
so->so_state = SS_NOFDREF;
} else
so->so_state &= ~SS_ISFCONNECTING;
-
+
}
tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
} /* SS_ISFCONNECTING */
#endif
}
-
+
/*
* Now UDP sockets.
* Incoming packets are sent straight away, they're not buffered.
*/
for (so = udb.so_next; so != &udb; so = so_next) {
so_next = so->so_next;
-
+
if (so->s != -1 && FD_ISSET(so->s, readfds)) {
sorecvfrom(so);
}
}
}
-
+
/*
* See if we can start outputting
*/
#define ARPOP_REQUEST 1 /* ARP request */
#define ARPOP_REPLY 2 /* ARP reply */
-struct ethhdr
+struct ethhdr
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
switch(ar_op) {
case ARPOP_REQUEST:
if (!memcmp(ah->ar_tip, &special_addr, 3)) {
- if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS)
+ if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS)
goto arp_ok;
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_addr == ah->ar_tip[3])
if (pkt_len < ETH_HLEN)
return;
-
+
proto = ntohs(*(uint16_t *)(pkt + 12));
switch(proto) {
case ETH_P_ARP:
slirp_output(buf, ip_data_len + ETH_HLEN);
}
-int slirp_redir(int is_udp, int host_port,
+int slirp_redir(int is_udp, int host_port,
struct in_addr guest_addr, int guest_port)
{
if (is_udp) {
- if (!udp_listen(htons(host_port), guest_addr.s_addr,
+ if (!udp_listen(htons(host_port), guest_addr.s_addr,
htons(guest_port), 0))
return -1;
} else {
- if (!solisten(htons(host_port), guest_addr.s_addr,
+ if (!solisten(htons(host_port), guest_addr.s_addr,
htons(guest_port), 0))
return -1;
}
return 0;
}
-int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
+int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
int guest_port)
{
- return add_exec(&exec_list, do_pty, (char *)args,
+ return add_exec(&exec_list, do_pty, (char *)args,
addr_low_byte, htons(guest_port));
}
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
u_int fport;
{
struct socket *so;
-
+
for (so = head->so_next; so != head; so = so->so_next) {
- if (so->so_lport == lport &&
+ if (so->so_lport == lport &&
so->so_laddr.s_addr == laddr.s_addr &&
so->so_faddr.s_addr == faddr.s_addr &&
so->so_fport == fport)
break;
}
-
+
if (so == head)
return (struct socket *)NULL;
return so;
-
+
}
/*
socreate()
{
struct socket *so;
-
+
so = (struct socket *)malloc(sizeof(struct socket));
if(so) {
memset(so, 0, sizeof(struct socket));
tcp_last_so = &tcb;
else if (so == udp_last_so)
udp_last_so = &udb;
-
+
m_free(so->so_m);
-
- if(so->so_next && so->so_prev)
+
+ if(so->so_next && so->so_prev)
remque(so); /* crashes if so is not in a queue */
free(so);
int len = sb->sb_datalen - sb->sb_cc;
struct iovec iov[2];
int mss = so->so_tcpcb->t_maxseg;
-
+
DEBUG_CALL("soread");
DEBUG_ARG("so = %lx", (long )so);
-
- /*
+
+ /*
* No need to check if there's enough room to read.
* soread wouldn't have been called if there weren't
*/
-
+
len = sb->sb_datalen - sb->sb_cc;
-
+
iov[0].iov_base = sb->sb_wptr;
if (sb->sb_wptr < sb->sb_rptr) {
iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
n = 1;
}
}
-
+
#ifdef HAVE_READV
nn = readv(so->s, (struct iovec *)iov, n);
DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
#else
nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
-#endif
+#endif
if (nn <= 0) {
if (nn < 0 && (errno == EINTR || errno == EAGAIN))
return 0;
return -1;
}
}
-
+
#ifndef HAVE_READV
/*
* If there was no error, try and read the second time round
if (ret > 0)
nn += ret;
}
-
+
DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
#endif
-
+
/* Update fields */
sb->sb_cc += nn;
sb->sb_wptr += nn;
sb->sb_wptr -= sb->sb_datalen;
return nn;
}
-
+
/*
* Get urgent data
- *
+ *
* When the socket is created, we set it SO_OOBINLINE,
* so when OOB data arrives, we soread() it and everything
* in the send buffer is sent as urgent data
DEBUG_CALL("sorecvoob");
DEBUG_ARG("so = %lx", (long)so);
-
+
/*
* We take a guess at how much urgent data has arrived.
* In most situations, when urgent data arrives, the next
* read() should get all the urgent data. This guess will
* be wrong however if more data arrives just after the
- * urgent data, or the read() doesn't return all the
+ * urgent data, or the read() doesn't return all the
* urgent data.
*/
soread(so);
{
struct sbuf *sb = &so->so_rcv;
char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
-
+
int n, len;
-
+
DEBUG_CALL("sosendoob");
DEBUG_ARG("so = %lx", (long)so);
DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
-
+
if (so->so_urgc > 2048)
so->so_urgc = 2048; /* XXXX */
-
+
if (sb->sb_rptr < sb->sb_wptr) {
/* We can send it directly */
n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
so->so_urgc -= n;
-
+
DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
} else {
- /*
+ /*
* Since there's no sendv or sendtov like writev,
* we must copy all data to a linear buffer then
* send it all
#ifdef DEBUG
if (n != len)
DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
-#endif
+#endif
DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
}
-
+
sb->sb_cc -= n;
sb->sb_rptr += n;
if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
sb->sb_rptr -= sb->sb_datalen;
-
+
return n;
}
/*
- * Write data from so_rcv to so's socket,
+ * Write data from so_rcv to so's socket,
* updating all sbuf field as necessary
*/
int
struct sbuf *sb = &so->so_rcv;
int len = sb->sb_cc;
struct iovec iov[2];
-
+
DEBUG_CALL("sowrite");
DEBUG_ARG("so = %lx", (long)so);
-
+
if (so->so_urgc) {
sosendoob(so);
if (sb->sb_cc == 0)
* No need to check if there's something to write,
* sowrite wouldn't have been called otherwise
*/
-
+
len = sb->sb_cc;
-
+
iov[0].iov_base = sb->sb_rptr;
if (sb->sb_rptr < sb->sb_wptr) {
iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
#ifdef HAVE_READV
nn = writev(so->s, (const struct iovec *)iov, n);
-
+
DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
#else
nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0);
/* This should never happen, but people tell me it does *shrug* */
if (nn < 0 && (errno == EAGAIN || errno == EINTR))
return 0;
-
+
if (nn <= 0) {
DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
so->so_state, errno));
tcp_sockclosed(sototcpcb(so));
return -1;
}
-
+
#ifndef HAVE_READV
if (n == 2 && nn == iov[0].iov_len) {
int ret;
}
DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
#endif
-
+
/* Update sbuf */
sb->sb_cc -= nn;
sb->sb_rptr += nn;
if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
sb->sb_rptr -= sb->sb_datalen;
-
+
/*
* If in DRAIN mode, and there's no more data, set
* it CANTSENDMORE
*/
if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
sofcantsendmore(so);
-
+
return nn;
}
{
struct sockaddr_in addr;
int addrlen = sizeof(struct sockaddr_in);
-
+
DEBUG_CALL("sorecvfrom");
DEBUG_ARG("so = %lx", (long)so);
-
+
if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
char buff[256];
int len;
-
- len = recvfrom(so->s, buff, 256, 0,
+
+ len = recvfrom(so->s, buff, 256, 0,
(struct sockaddr *)&addr, &addrlen);
/* XXX Check if reply is "correct"? */
-
+
if(len == -1 || len == 0) {
u_char code=ICMP_UNREACH_PORT;
if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
-
+
DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
errno,strerror(errno)));
icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
if (!(m = m_get())) return;
m->m_data += if_maxlinkhdr;
-
- /*
+
+ /*
* XXX Shouldn't FIONREAD packets destined for port 53,
* but I don't know the max packet size for DNS lookups
*/
len = M_FREEROOM(m);
/* if (so->so_fport != htons(53)) { */
ioctlsocket(so->s, FIONREAD, &n);
-
+
if (n > len) {
n = (m->m_data - m->m_dat) + m->m_len + n + 1;
m_inc(m, n);
len = M_FREEROOM(m);
}
/* } */
-
+
m->m_len = recvfrom(so->s, m->m_data, len, 0,
(struct sockaddr *)&addr, &addrlen);
- DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
+ DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
m->m_len, errno,strerror(errno)));
if(m->m_len<0) {
u_char code=ICMP_UNREACH_PORT;
if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
-
+
DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
m_free(m);
* m->m_len = 0;
* }
*/
-
- /*
+
+ /*
* If this packet was destined for CTL_ADDR,
* make it look like that's where it came from, done by udp_output
*/
DEBUG_CALL("sosendto");
DEBUG_ARG("so = %lx", (long)so);
DEBUG_ARG("m = %lx", (long)m);
-
+
addr.sin_family = AF_INET;
if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
/* It's an alias */
addr.sin_port = so->so_fport;
DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
-
+
/* Don't care what port we get */
ret = sendto(so->s, m->m_data, m->m_len, 0,
(struct sockaddr *)&addr, sizeof (struct sockaddr));
if (ret < 0)
return -1;
-
+
/*
* Kill the socket if there's no reply in 4 minutes,
* but only if it's an expirable socket
DEBUG_ARG("laddr = %x", laddr);
DEBUG_ARG("lport = %d", lport);
DEBUG_ARG("flags = %x", flags);
-
+
if ((so = socreate()) == NULL) {
/* free(so); Not sofree() ??? free(NULL) == NOP */
return NULL;
}
-
+
/* Don't tcp_attach... we don't need so_snd nor so_rcv */
if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
free(so);
return NULL;
}
insque(so,&tcb);
-
- /*
+
+ /*
* SS_FACCEPTONCE sockets must time out.
*/
if (flags & SS_FACCEPTONCE)
so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
-
+
so->so_state = (SS_FACCEPTCONN|flags);
so->so_lport = lport; /* Kept in network format */
so->so_laddr.s_addr = laddr; /* Ditto */
-
+
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = port;
-
+
if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
(listen(s,1) < 0)) {
int tmperrno = errno; /* Don't clobber the real reason we failed */
-
+
close(s);
sofree(so);
/* Restore the real errno */
return NULL;
}
setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
-
+
getsockname(s,(struct sockaddr *)&addr,&addrlen);
so->so_fport = addr.sin_port;
if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
return so;
}
-/*
+/*
* Data is available in so_rcv
* Just write() the data to the socket
* XXX not yet...
/* sowrite(so); */
/* FD_CLR(so->s,&writefds); */
}
-
+
/*
* Data has been freed in so_snd
* We have room for a read() if we want to
/*
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
struct in_addr so_laddr; /* local host table entry */
u_int16_t so_fport; /* foreign port */
u_int16_t so_lport; /* local port */
-
+
u_int8_t so_iptos; /* Type of service */
u_int8_t so_emu; /* Is the socket emulated? */
-
+
u_char so_type; /* Type of socket, UDP or TCP */
int so_state; /* internal state flags SS_*, below */
-
+
struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */
u_int so_expire; /* When the socket will expire */
-
+
int so_queued; /* Number of packets queued from this socket */
int so_nqueued; /* Number of packets queued in a row
* Used to determine when to "downgrade" a session
* from fastq to batchq */
-
+
struct sbuf so_rcv; /* Receive buffer */
struct sbuf so_snd; /* Send buffer */
void * extra; /* Extra pointer */
/*
* Changes and additions relating to SLiRP
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
register struct tcpiphdr *q;
struct socket *so = tp->t_socket;
int flags;
-
+
/*
* Call with ti==0 after become established to
* force pre-ESTABLISHED data up to user socket.
/* int ts_present = 0; */
DEBUG_CALL("tcp_input");
- DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n",
+ DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n",
(long )m, iphlen, (long )inso ));
-
+
/*
* If called with m == 0, then we're continuing the connect
*/
if (m == NULL) {
so = inso;
-
+
/* Re-set a few variables */
tp = sototcpcb(so);
m = so->so_m;
ti = so->so_ti;
tiwin = ti->ti_win;
tiflags = ti->ti_flags;
-
+
goto cont_conn;
}
-
-
+
+
tcpstat.tcps_rcvtotal++;
/*
* Get IP and TCP header together in first mbuf.
iphlen=sizeof(struct ip );
}
/* XXX Check if too short */
-
+
/*
* Save a copy of the IP header in case we want restore it
* for sending an ICMP error message in response.
*/
ip=mtod(m, struct ip *);
- save_ip = *ip;
+ save_ip = *ip;
save_ip.ip_len+= iphlen;
/*
ti->ti_len = htons((u_int16_t)tlen);
len = sizeof(struct ip ) + tlen;
/* keep checksum for ICMP reply
- * ti->ti_sum = cksum(m, len);
+ * ti->ti_sum = cksum(m, len);
* if (ti->ti_sum) { */
if(cksum(m, len)) {
tcpstat.tcps_rcvbadsum++;
optlen = off - sizeof (struct tcphdr);
optp = mtod(m, caddr_t) + sizeof (struct tcpiphdr);
- /*
+ /*
* Do quick retrieval of timestamp options ("options
* prediction?"). If timestamp is the only option and it's
* formatted as recommended in RFC 1323 appendix A, we
*/
}
tiflags = ti->ti_flags;
-
+
/*
* Convert TCP protocol specific fields to host format.
*/
*/
m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
-
+
/*
* Locate pcb for segment.
*/
* but should either do a listen or a connect soon.
*
* state == CLOSED means we've done socreate() but haven't
- * attached it to a protocol yet...
- *
+ * attached it to a protocol yet...
+ *
* XXX If a TCB does not exist, and the TH_SYN flag is
* the only flag set, then create a session, mark it
* as if it was LISTENING, and continue...
if (so == 0) {
if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN)
goto dropwithreset;
-
+
if ((so = socreate()) == NULL)
goto dropwithreset;
if (tcp_attach(so) < 0) {
free(so); /* Not sofree (if it failed, it's not insqued) */
goto dropwithreset;
}
-
+
sbreserve(&so->so_snd, tcp_sndspace);
sbreserve(&so->so_rcv, tcp_rcvspace);
-
+
/* tcp_last_so = so; */ /* XXX ? */
/* tp = sototcpcb(so); */
-
+
so->so_laddr = ti->ti_src;
so->so_lport = ti->ti_sport;
so->so_faddr = ti->ti_dst;
so->so_fport = ti->ti_dport;
-
+
if ((so->so_iptos = tcp_tos(so)) == 0)
so->so_iptos = ((struct ip *)ti)->ip_tos;
-
+
tp = sototcpcb(so);
tp->t_state = TCPS_LISTEN;
}
-
+
/*
* If this is a still-connecting socket, this probably
* a retransmit of the SYN. Whether it's a retransmit SYN
goto drop;
tp = sototcpcb(so);
-
+
/* XXX Should never fail */
if (tp == 0)
goto dropwithreset;
if (tp->t_state == TCPS_CLOSED)
goto drop;
-
+
/* Unscale the window into a 32-bit value. */
/* if ((tiflags & TH_SYN) == 0)
* tiwin = ti->ti_win << tp->snd_scale;
* else do it below (after getting remote address).
*/
if (optp && tp->t_state != TCPS_LISTEN)
- tcp_dooptions(tp, (u_char *)optp, optlen, ti);
+ tcp_dooptions(tp, (u_char *)optp, optlen, ti);
/* , */
/* &ts_present, &ts_val, &ts_ecr); */
- /*
+ /*
* Header prediction: check for the two common cases
* of a uni-directional data xfer. If the packet has
* no control flags, is in-sequence, the window didn't
ti->ti_seq == tp->rcv_nxt &&
tiwin && tiwin == tp->snd_wnd &&
tp->snd_nxt == tp->snd_max) {
- /*
+ /*
* If last ACK falls within this segment's sequence numbers,
* record the timestamp.
*/
++tcpstat.tcps_predack;
/* if (ts_present)
* tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
- * else
+ * else
*/ if (tp->t_rtt &&
SEQ_GT(ti->ti_ack, tp->t_rtseq))
tcp_xmit_timer(tp, tp->t_rtt);
else if (tp->t_timer[TCPT_PERSIST] == 0)
tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
- /*
+ /*
* There's room in so_snd, sowwakup will read()
* from the socket if we can
*/
/* if (so->so_snd.sb_flags & SB_NOTIFY)
* sowwakeup(so);
*/
- /*
+ /*
* This is called because sowwakeup might have
* put data into so_snd. Since we don't so sowwakeup,
* we don't need this.. XXX???
if (tcp_emu(so,m)) sbappend(so, m);
} else
sbappend(so, m);
-
- /*
+
+ /*
* XXX This is called when data arrives. Later, check
* if we can actually write() to the socket
* XXX Need to check? It's be NON_BLOCKING
*/
/* sorwakeup(so); */
-
+
/*
* If this is a short packet, then ACK now - with Nagel
* congestion avoidance sender won't send more until
* he gets an ACK.
- *
+ *
* It is better to not delay acks at all to maximize
* TCP throughput. See RFC 2581.
- */
+ */
tp->t_flags |= TF_ACKNOW;
tcp_output(tp);
return;
goto dropwithreset;
if ((tiflags & TH_SYN) == 0)
goto drop;
-
+
/*
* This has way too many gotos...
* But a bit of spaghetti code never hurt anybody :)
*/
-
+
/*
* If this is destined for the control address, then flag to
* tcp_ctl once connected, otherwise connect
if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) {
/* Command or exec adress */
so->so_state |= SS_CTL;
- } else
+ } else
#endif
{
/* May be an add exec */
struct ex_list *ex_ptr;
for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
- if(ex_ptr->ex_fport == so->so_fport &&
+ if(ex_ptr->ex_fport == so->so_fport &&
lastbyte == ex_ptr->ex_addr) {
so->so_state |= SS_CTL;
break;
}
/* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */
}
-
+
if (so->so_emu & EMU_NOCONNECT) {
so->so_emu &= ~EMU_NOCONNECT;
goto cont_input;
}
-
+
if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) {
u_char code=ICMP_UNREACH_NET;
DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n",
if(errno == ECONNREFUSED) {
/* ACK the SYN, send RST to refuse the connection */
tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0,
- TH_RST|TH_ACK);
+ TH_RST|TH_ACK);
} else {
if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
HTONL(ti->ti_seq); /* restore tcp header */
}
return;
- cont_conn:
- /* m==NULL
+ cont_conn:
+ /* m==NULL
* Check if the connect succeeded
*/
if (so->so_state & SS_NOFDREF) {
tp = tcp_close(tp);
goto dropwithreset;
}
- cont_input:
+ cont_input:
tcp_template(tp);
-
+
if (optp)
tcp_dooptions(tp, (u_char *)optp, optlen, ti);
/* , */
/* &ts_present, &ts_val, &ts_ecr); */
-
+
if (iss)
tp->iss = iss;
- else
+ else
tp->iss = tcp_iss;
tcp_iss += TCP_ISSINCR/2;
tp->irs = ti->ti_seq;
tcpstat.tcps_accepts++;
goto trimthenstep6;
} /* case TCPS_LISTEN */
-
+
/*
* If the state is SYN_SENT:
* if seg contains an ACK, but not for our SYN, drop the input.
tcpstat.tcps_connects++;
soisfconnected(so);
tp->t_state = TCPS_ESTABLISHED;
-
+
/* Do window scaling on this connection? */
/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
* (TF_RCVD_SCALE|TF_REQ_SCALE)) {
/*
* States other than LISTEN or SYN_SENT.
* First check timestamp, if present.
- * Then check that at least some bytes of segment are within
+ * Then check that at least some bytes of segment are within
* receive window. If segment begins before rcv_nxt,
* drop leading data (and SYN); if nothing left, just ack.
- *
+ *
* RFC 1323 PAWS: If we have a timestamp reply on this segment
* and it's less than ts_recent, drop it.
*/
if (tiflags & TH_SYN) {
tiflags &= ~TH_SYN;
ti->ti_seq++;
- if (ti->ti_urp > 1)
+ if (ti->ti_urp > 1)
ti->ti_urp--;
else
tiflags &= ~TH_URG;
* of sequence; drop it.
*/
tiflags &= ~TH_FIN;
-
+
/*
* Send an ACK to resynchronize and drop any data.
* But keep on processing for RST or ACK.
goto dropwithreset;
tcpstat.tcps_connects++;
tp->t_state = TCPS_ESTABLISHED;
- /*
- * The sent SYN is ack'ed with our sequence number +1
- * The first data byte already in the buffer will get
+ /*
+ * The sent SYN is ack'ed with our sequence number +1
+ * The first data byte already in the buffer will get
* lost if no correction is made. This is only needed for
* SS_CTL since the buffer is empty otherwise.
- * tp->snd_una++; or:
+ * tp->snd_una++; or:
*/
tp->snd_una=ti->ti_ack;
if (so->so_state & SS_CTL) {
} else {
soisfconnected(so);
}
-
+
/* Do window scaling? */
/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
* (TF_RCVD_SCALE|TF_REQ_SCALE)) {
* the new ssthresh).
*
* Dup acks mean that packets have left the
- * network (they're now cached at the receiver)
+ * network (they're now cached at the receiver)
* so bump cwnd by the amount in the receiver
* to keep a constant cwnd packets in the
* network.
/* if (ts_present)
* tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
* else
- */
+ */
if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq))
tcp_xmit_timer(tp,tp->t_rtt);
}
/*
* XXX sowwakup is called when data is acked and there's room for
- * for more data... it should read() the socket
+ * for more data... it should read() the socket
*/
/* if (so->so_snd.sb_flags & SB_NOTIFY)
* sowwakeup(so);
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((tiflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, ti->ti_seq) ||
+ (SEQ_LT(tp->snd_wl1, ti->ti_seq) ||
(tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) ||
(tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) {
/* keep track of pure window updates */
* If this segment advances the known urgent pointer,
* then mark the data stream. This should not happen
* in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
- * a FIN has been received from the remote side.
+ * a FIN has been received from the remote side.
* In these states we ignore the URG.
*
* According to RFC961 (Assigned Protocols),
* the urgent pointer points to the last octet
* of urgent data. We continue, however,
* to consider it to indicate the first octet
- * of data past the urgent section as the original
+ * of data past the urgent section as the original
* spec states (in one of two places).
*/
if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) {
so->so_urgc = so->so_rcv.sb_cc +
(tp->rcv_up - tp->rcv_nxt); /* -1; */
tp->rcv_up = ti->ti_seq + ti->ti_urp;
-
+
}
} else
/*
*/
/* sofcantrcvmore(so); */
sofwdrain(so);
-
+
tp->t_flags |= TF_ACKNOW;
tp->rcv_nxt++;
}
case TCPS_ESTABLISHED:
if(so->so_emu == EMU_CTL) /* no shutdown on socket */
tp->t_state = TCPS_LAST_ACK;
- else
+ else
tp->t_state = TCPS_CLOSE_WAIT;
break;
/*
* In FIN_WAIT_2 state enter the TIME_WAIT state,
- * starting the time-wait timer, turning off the other
+ * starting the time-wait timer, turning off the other
* standard timers.
*/
case TCPS_FIN_WAIT_2:
* If this is a small packet, then ACK now - with Nagel
* congestion avoidance sender won't send more until
* he gets an ACK.
- *
+ *
* See above.
*/
/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) {
* memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr));
* NTOHL(*ts_ecr);
*
- */ /*
+ */ /*
* * A timestamp received in a SYN makes
* * it ok to send timestamp requests and replies.
* */
register struct mbuf *m;
{
int cnt = ti->ti_urp - 1;
-
+
while (cnt >= 0) {
if (m->m_len > cnt) {
char *cp = mtod(m, caddr_t) + cnt;
DEBUG_CALL("tcp_xmit_timer");
DEBUG_ARG("tp = %lx", (long)tp);
DEBUG_ARG("rtt = %d", rtt);
-
+
tcpstat.tcps_rttupdated++;
if (tp->t_srtt != 0) {
/*
if ((tp->t_rttvar += delta) <= 0)
tp->t_rttvar = 1;
} else {
- /*
+ /*
* No rtt measurement yet - use the unsmoothed rtt.
* Set the variance to half the rtt (so our first
* retransmit happens at 3*rtt).
*/
TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp),
(short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
-
+
/*
* We received an ack for a packet that wasn't retransmitted;
* it is probably safe to discard any error indications we've
{
struct socket *so = tp->t_socket;
int mss;
-
+
DEBUG_CALL("tcp_mss");
DEBUG_ARG("tp = %lx", (long)tp);
DEBUG_ARG("offer = %d", offer);
-
+
mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr);
if (offer)
mss = min(mss, offer);
mss = max(mss, 32);
if (mss < tp->t_maxseg || offer != 0)
tp->t_maxseg = mss;
-
+
tp->snd_cwnd = mss;
-
+
sbreserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0));
sbreserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0));
-
+
DEBUG_MISC((dfd, " returning mss = %d\n", mss));
-
+
return mss;
}
/*
* Changes and additions relating to SLiRP
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
u_char tcp_outflags[TCP_NSTATES] = {
TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
- TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
+ TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
TH_FIN|TH_ACK, TH_ACK, TH_ACK,
};
u_char opt[MAX_TCPOPTLEN];
unsigned optlen, hdrlen;
int idle, sendalot;
-
+
DEBUG_CALL("tcp_output");
DEBUG_ARG("tp = %lx", (long )tp);
-
+
/*
* Determine length of data that should be transmitted,
* and flags that will be used.
win = min(tp->snd_wnd, tp->snd_cwnd);
flags = tcp_outflags[tp->t_state];
-
+
DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags));
-
+
/*
* If in persist timeout with window of 0, send 1 byte.
* Otherwise, if window is small but nonzero
tp->snd_nxt = tp->snd_una;
}
}
-
+
if (len > tp->t_maxseg) {
len = tp->t_maxseg;
sendalot = 1;
* window, then want to send a window update to peer.
*/
if (win > 0) {
- /*
+ /*
* "adv" is the amount we can increase the window,
* taking into account that we are limited by
* TCP_MAXWIN << tp->rcv_scale.
* No reason to send a segment, just return.
*/
tcpstat.tcps_didnuttin++;
-
+
return (0);
send:
*/
}
}
-
+
/*
- * Send a timestamp and echo-reply if this is a SYN and our side
+ * Send a timestamp and echo-reply if this is a SYN and our side
* wants to use timestamps (TF_REQ_TSTMP is set) or both our side
* and our peer have sent timestamps in our SYN's.
*/
* }
*/
hdrlen += optlen;
-
+
/*
* Adjust data length if insertion of options will
* bump the packet length beyond the t_maxseg length.
}
m->m_data += if_maxlinkhdr;
m->m_len = hdrlen;
-
- /*
+
+ /*
* This will always succeed, since we make sure our mbufs
* are big enough to hold one MSS packet + header + ... etc.
*/
}
ti = mtod(m, struct tcpiphdr *);
-
+
memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr));
/*
* window for use in delaying messages about window sizes.
* If resending a FIN, be sure not to use a new sequence number.
*/
- if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
+ if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
tp->snd_nxt == tp->snd_max)
tp->snd_nxt--;
/*
if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
win = (long)(tp->rcv_adv - tp->rcv_nxt);
ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale));
-
+
if (SEQ_GT(tp->snd_up, tp->snd_una)) {
ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq)));
-#ifdef notdef
+#ifdef notdef
if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt));
#endif
* the template, but need a way to checksum without them.
*/
m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */
-
+
{
-
+
((struct ip *)ti)->ip_len = m->m_len;
((struct ip *)ti)->ip_ttl = ip_defttl;
((struct ip *)ti)->ip_tos = so->so_iptos;
-
+
/* #if BSD >= 43 */
/* Don't do IP options... */
/* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
error = ip_output(so, m);
/* #else
- * error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route,
+ * error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route,
* so->so_options & SO_DONTROUTE);
* #endif
*/
/*
* Changes and additions relating to SLiRP
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
{
tcp_iss = 1; /* wrong */
tcb.so_next = tcb.so_prev = &tcb;
-
+
/* tcp_rcvspace = our Window we advertise to the remote */
tcp_rcvspace = TCP_RCVSPACE;
tcp_sndspace = TCP_SNDSPACE;
-
+
/* Make sure tcp_sndspace is at least 2*MSS */
if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)))
tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr));
n->ti_dst = so->so_laddr;
n->ti_sport = so->so_fport;
n->ti_dport = so->so_lport;
-
+
n->ti_seq = 0;
n->ti_ack = 0;
n->ti_x2 = 0;
DEBUG_ARG("ack = %u", ack);
DEBUG_ARG("seq = %u", seq);
DEBUG_ARG("flags = %x", flags);
-
+
if (tp)
win = sbspace(&tp->t_socket->so_rcv);
if (m == 0) {
ti = mtod(m, struct tcpiphdr *);
flags = TH_ACK;
} else {
- /*
+ /*
* ti points into m so the next line is just making
* the mbuf point to ti
*/
m->m_data = (caddr_t)ti;
-
+
m->m_len = sizeof (struct tcpiphdr);
tlen = 0;
#define xchg(a,b,type) { type t; t=a; a=b; b=t; }
ti->ti_sum = cksum(m, tlen);
((struct ip *)ti)->ip_len = tlen;
- if(flags & TH_RST)
+ if(flags & TH_RST)
((struct ip *)ti)->ip_ttl = MAXTTL;
- else
+ else
((struct ip *)ti)->ip_ttl = ip_defttl;
-
+
(void) ip_output((struct socket *)0, m);
}
struct socket *so;
{
register struct tcpcb *tp;
-
+
tp = (struct tcpcb *)malloc(sizeof(*tp));
if (tp == NULL)
return ((struct tcpcb *)0);
-
+
memset((char *) tp, 0, sizeof(struct tcpcb));
tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
tp->t_maxseg = tcp_mssdflt;
-
+
tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
tp->t_socket = so;
-
+
/*
* Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
* rtt estimate. Set rttvar so that srtt + 2 * rttvar gives
tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
tp->t_rttmin = TCPTV_MIN;
- TCPT_RANGESET(tp->t_rxtcur,
+ TCPT_RANGESET(tp->t_rxtcur,
((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1,
TCPTV_MIN, TCPTV_REXMTMAX);
tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
tp->t_state = TCPS_CLOSED;
-
+
so->so_tcpcb = tp;
return (tp);
* the specified error. If connection is synchronized,
* then send a RST to peer.
*/
-struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
+struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
{
/* tcp_drop(tp, errno)
register struct tcpcb *tp;
DEBUG_CALL("tcp_drop");
DEBUG_ARG("tp = %lx", (long)tp);
DEBUG_ARG("errno = %d", errno);
-
+
if (TCPS_HAVERCVDSYN(tp->t_state)) {
tp->t_state = TCPS_CLOSED;
(void) tcp_output(tp);
DEBUG_CALL("tcp_close");
DEBUG_ARG("tp = %lx", (long )tp);
-
+
/* free the reassembly queue, if any */
t = (struct tcpiphdr *) tp->seg_next;
while (t != (struct tcpiphdr *)tp) {
DEBUG_CALL("tcp_sockclosed");
DEBUG_ARG("tp = %lx", (long)tp);
-
+
switch (tp->t_state) {
case TCPS_CLOSED:
tcp_output(tp);
}
-/*
+/*
* Connect to a host on the Internet
* Called by tcp_input
* Only do a connect, the tcp fields will be set in tcp_input
* return 0 if there's a result of the connect,
* else return -1 means we're still connecting
* The return value is almost always -1 since the socket is
- * nonblocking. Connect returns after the SYN is sent, and does
+ * nonblocking. Connect returns after the SYN is sent, and does
* not wait for ACK+SYN.
*/
int tcp_fconnect(so)
struct socket *so;
{
int ret=0;
-
+
DEBUG_CALL("tcp_fconnect");
DEBUG_ARG("so = %lx", (long )so);
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt ));
opt = 1;
setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt ));
-
+
addr.sin_family = AF_INET;
if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
/* It's an alias */
} else
addr.sin_addr = so->so_faddr;
addr.sin_port = so->so_fport;
-
+
DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, "
- "addr.sin_addr.s_addr=%.16s\n",
+ "addr.sin_addr.s_addr=%.16s\n",
ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
/* We don't care what port we get */
ret = connect(s,(struct sockaddr *)&addr,sizeof (addr));
-
+
/*
* If it's not in progress, it failed, so we just return 0,
* without clearing SS_NOFDREF
/*
* Accept the socket and connect to the local-host
- *
+ *
* We have a problem. The correct thing to do would be
* to first connect to the local-host, and only if the
* connection is accepted, then do an accept() here.
- * But, a) we need to know who's trying to connect
+ * But, a) we need to know who's trying to connect
* to the socket to be able to SYN the local-host, and
* b) we are already connected to the foreign host by
* the time it gets to accept(), so... We simply accept
* here and SYN the local-host.
- */
+ */
void
tcp_connect(inso)
struct socket *inso;
DEBUG_CALL("tcp_connect");
DEBUG_ARG("inso = %lx", (long)inso);
-
+
/*
* If it's an SS_ACCEPTONCE socket, no need to socreate()
* another socket, just use the accept() socket.
so->so_laddr = inso->so_laddr;
so->so_lport = inso->so_lport;
}
-
+
(void) tcp_mss(sototcpcb(so), 0);
if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) {
setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
opt = 1;
setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int));
-
+
so->so_fport = addr.sin_port;
so->so_faddr = addr.sin_addr;
/* Translate connections from localhost to the real hostname */
if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr)
so->so_faddr = alias_addr;
-
+
/* Close the accept() socket, set right state */
if (inso->so_state & SS_FACCEPTONCE) {
closesocket(so->s); /* If we only accept once, close the accept() socket */
/* if it's not FACCEPTONCE, it's already NOFDREF */
}
so->s = s;
-
+
so->so_iptos = tcp_tos(so);
tp = sototcpcb(so);
tcp_template(tp);
-
+
/* Compute window scaling to request. */
/* while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
* (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
/* soisconnecting(so); */ /* NOFDREF used instead */
tcpstat.tcps_connattempt++;
-
+
tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->iss = tcp_iss;
+ tp->iss = tcp_iss;
tcp_iss += TCP_ISSINCR/2;
tcp_sendseqinit(tp);
tcp_output(tp);
{
if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
return -1;
-
+
insque(so, &tcb);
return 0;
};
struct emu_t *tcpemu = 0;
-
+
/*
* Return TOS according to the above table
*/
{
int i = 0;
struct emu_t *emup;
-
+
while(tcptos[i].tos) {
if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) ||
(tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) {
}
i++;
}
-
+
/* Nope, lets see if there's a user-added one */
for (emup = tcpemu; emup; emup = emup->next) {
if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) ||
return emup->tos;
}
}
-
+
return 0;
}
* This includes ftp (the data connection is
* initiated by the server) and IRC (DCC CHAT and
* DCC SEND) for now
- *
+ *
* NOTE: It's possible to crash SLiRP by sending it
* unstandard strings to emulate... if this is a problem,
* more checks are needed here
*
* XXX Assumes the whole command came in one packet
- *
+ *
* XXX Some ftp clients will have their TOS set to
* LOWDELAY and so Nagel will kick in. Because of this,
* we'll get the first letter, followed by the rest, so
* we simply scan for ORT instead of PORT...
* DCC doesn't have this problem because there's other stuff
* in the packet before the DCC command.
- *
- * Return 1 if the mbuf m is still valid and should be
+ *
+ * Return 1 if the mbuf m is still valid and should be
* sbappend()ed
- *
+ *
* NOTE: if you return 0 you MUST m_free() the mbuf!
*/
int
u_int32_t laddr;
u_int lport;
char *bptr;
-
+
DEBUG_CALL("tcp_emu");
DEBUG_ARG("so = %lx", (long)so);
DEBUG_ARG("m = %lx", (long)m);
-
+
switch(so->so_emu) {
int x, i;
-
+
case EMU_IDENT:
/*
* Identification protocol as per rfc-1413
*/
-
+
{
struct socket *tmpso;
struct sockaddr_in addr;
int addrlen = sizeof(struct sockaddr_in);
struct sbuf *so_rcv = &so->so_rcv;
-
+
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
so_rcv->sb_wptr += m->m_len;
so_rcv->sb_rptr += m->m_len;
m_free(m);
return 0;
}
-
+
#if 0
case EMU_RLOGIN:
/*
char term[100];
struct sbuf *so_snd = &so->so_snd;
struct sbuf *so_rcv = &so->so_rcv;
-
+
/* First check if they have a priveladged port, or too much data has arrived */
if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 ||
(m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) {
m_free(m);
return 0;
}
-
+
/* Append the current data */
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
so_rcv->sb_wptr += m->m_len;
so_rcv->sb_rptr += m->m_len;
m_free(m);
-
+
/*
* Check if we have all the initial options,
* and build argument list to rlogin while we're here
}
}
}
-
+
if (n != 4)
return 0;
-
+
/* We have it, set our term variable and fork_exec() */
#ifdef HAVE_SETENV
setenv("TERM", term, 1);
fork_exec(so, args, 2);
term[0] = 0;
so->so_emu = 0;
-
+
/* And finally, send the client a 0 character */
so_snd->sb_wptr[0] = 0;
so_snd->sb_wptr++;
so_snd->sb_cc++;
-
+
return 0;
}
-
+
case EMU_RSH:
/*
* rsh emulation
char *args;
struct sbuf *so_snd = &so->so_snd;
struct sbuf *so_rcv = &so->so_rcv;
-
+
/* First check if they have a priveladged port, or too much data has arrived */
if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 ||
(m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) {
m_free(m);
return 0;
}
-
+
/* Append the current data */
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
so_rcv->sb_wptr += m->m_len;
so_rcv->sb_rptr += m->m_len;
m_free(m);
-
+
/*
* Check if we have all the initial options,
* and build argument list to rlogin while we're here
ns->so_faddr=so->so_faddr;
ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */
- if (ns->so_faddr.s_addr == 0 ||
+ if (ns->so_faddr.s_addr == 0 ||
ns->so_faddr.s_addr == loopback_addr.s_addr)
ns->so_faddr = alias_addr;
ns->so_iptos = tcp_tos(ns);
tp = sototcpcb(ns);
-
+
tcp_template(tp);
-
+
/* Compute window scaling to request. */
/* while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
* (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
/*soisfconnecting(ns);*/
tcpstat.tcps_connattempt++;
-
+
tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->iss = tcp_iss;
+ tp->iss = tcp_iss;
tcp_iss += TCP_ISSINCR/2;
tcp_sendseqinit(tp);
tcp_output(tp);
}
}
}
-
+
if (n != 4)
return 0;
-
+
rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args);
so->so_emu = 0;
so->extra=NULL;
-
+
/* And finally, send the client a 0 character */
so_snd->sb_wptr[0] = 0;
so_snd->sb_wptr++;
so_snd->sb_cc++;
-
+
return 0;
}
int num;
struct sbuf *so_snd = &so->so_snd;
struct sbuf *so_rcv = &so->so_rcv;
-
+
/*
* If there is binary data here, we save it in so->so_m
*/
}
}
} /* if(so->so_m==NULL) */
-
+
/*
* Append the line
*/
sbappendsb(so_rcv, m);
-
+
/* To avoid going over the edge of the buffer, we reset it */
if (so_snd->sb_cc == 0)
so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data;
-
+
/*
* A bit of a hack:
* If the first packet we get here is 1 byte long, then it
tcp_output(sototcpcb(so)); /* XXX */
} else
m_free(m);
-
+
num = 0;
while (num < so->so_rcv.sb_cc) {
if (*(so->so_rcv.sb_rptr + num) == '\n' ||
*(so->so_rcv.sb_rptr + num) == '\r') {
int n;
-
+
*(so_rcv->sb_rptr + num) = 0;
if (ctl_password && !ctl_password_ok) {
/* Need a password */
}
return 0;
}
-#endif
+#endif
case EMU_FTP: /* ftp */
*(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */
if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) {
/*
* Need to emulate the PORT command
- */
- x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]",
+ */
+ x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]",
&n1, &n2, &n3, &n4, &n5, &n6, buff);
if (x < 6)
return 1;
-
+
laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
lport = htons((n5 << 8) | (n6));
-
+
if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
return 1;
-
+
n6 = ntohs(so->so_fport);
-
+
n5 = (n6 >> 8) & 0xff;
n6 &= 0xff;
-
+
laddr = ntohl(so->so_faddr.s_addr);
-
+
n1 = ((laddr >> 24) & 0xff);
n2 = ((laddr >> 16) & 0xff);
n3 = ((laddr >> 8) & 0xff);
n4 = (laddr & 0xff);
-
+
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s",
+ m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s",
n1, n2, n3, n4, n5, n6, x==7?buff:"");
return 1;
} else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) {
&n1, &n2, &n3, &n4, &n5, &n6, buff);
if (x < 6)
return 1;
-
+
laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
lport = htons((n5 << 8) | (n6));
-
+
if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
return 1;
-
+
n6 = ntohs(so->so_fport);
-
+
n5 = (n6 >> 8) & 0xff;
n6 &= 0xff;
-
+
laddr = ntohl(so->so_faddr.s_addr);
-
+
n1 = ((laddr >> 24) & 0xff);
n2 = ((laddr >> 16) & 0xff);
n3 = ((laddr >> 8) & 0xff);
n4 = (laddr & 0xff);
-
+
m->m_len = bptr - m->m_data; /* Adjust length */
m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
n1, n2, n3, n4, n5, n6, x==7?buff:"");
-
+
return 1;
}
-
+
return 1;
-
+
case EMU_KSH:
/*
* The kshell (Kerberos rsh) and shell services both pass
(so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1;
return 1;
-
+
case EMU_IRC:
/*
* Need to emulate DCC CHAT, DCC SEND and DCC MOVE
*(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */
if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL)
return 1;
-
+
/* The %256s is for the broken mIRC */
if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) {
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
return 1;
-
+
m->m_len = bptr - m->m_data; /* Adjust length */
m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n",
(unsigned long)ntohl(so->so_faddr.s_addr),
} else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
return 1;
-
+
m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n",
+ m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n",
buff, (unsigned long)ntohl(so->so_faddr.s_addr),
ntohs(so->so_fport), n1, 1);
} else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
return 1;
-
+
m->m_len = bptr - m->m_data; /* Adjust length */
m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n",
buff, (unsigned long)ntohl(so->so_faddr.s_addr),
return 1;
case EMU_REALAUDIO:
- /*
+ /*
* RealAudio emulation - JP. We must try to parse the incoming
* data and try to find the two characters that contain the
* port number. Then we redirect an udp port and replace the
*
* The 1.0 beta versions of the player are not supported
* any more.
- *
+ *
* A typical packet for player version 1.0 (release version):
- *
- * 0000:50 4E 41 00 05
+ *
+ * 0000:50 4E 41 00 05
* 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P
* 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH
* 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v
* 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB
- *
+ *
* Now the port number 0x1BD7 is found at offset 0x04 of the
* Now the port number 0x1BD7 is found at offset 0x04 of the
* second packet. This time we received five bytes first and
* then the rest. You never know how many bytes you get.
*
* A typical packet for player version 2.0 (beta):
- *
+ *
* 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á.
* 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0
* 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/
* 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas
* 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B
- *
+ *
* Port number 0x1BC1 is found at offset 0x0d.
- *
+ *
* This is just a horrible switch statement. Variable ra tells
* us where we're going.
*/
-
+
bptr = m->m_data;
while (bptr < m->m_data + m->m_len) {
u_short p;
static int ra = 0;
- char ra_tbl[4];
-
+ char ra_tbl[4];
+
ra_tbl[0] = 0x50;
ra_tbl[1] = 0x4e;
ra_tbl[2] = 0x41;
ra_tbl[3] = 0;
-
+
switch (ra) {
case 0:
case 2:
continue;
}
break;
-
+
case 1:
/*
* We may get 0x50 several times, ignore them
continue;
}
break;
-
- case 4:
- /*
+
+ case 4:
+ /*
* skip version number
*/
bptr++;
break;
-
- case 5:
+
+ case 5:
/*
* The difference between versions 1.0 and
* 2.0 is here. For future versions of
bptr += 8;
else
bptr += 4;
- break;
-
+ break;
+
case 6:
/* This is the field containing the port
* number that RA-player is listening to.
*/
- lport = (((u_char*)bptr)[0] << 8)
+ lport = (((u_char*)bptr)[0] << 8)
+ ((u_char *)bptr)[1];
- if (lport < 6970)
+ if (lport < 6970)
lport += 256; /* don't know why */
if (lport < 6970 || lport > 7170)
return 1; /* failed */
-
+
/* try to get udp port between 6970 - 7170 */
for (p = 6970; p < 7071; p++) {
if (udp_listen( htons(p),
p = 0;
*(u_char *)bptr++ = (p >> 8) & 0xff;
*(u_char *)bptr++ = p & 0xff;
- ra = 0;
+ ra = 0;
return 1; /* port redirected, we're done */
- break;
-
+ break;
+
default:
- ra = 0;
+ ra = 0;
}
ra++;
}
- return 1;
-
+ return 1;
+
default:
/* Ooops, not emulated, won't call tcp_emu again */
so->so_emu = 0;
struct ex_list *ex_ptr;
int do_pty;
// struct socket *tmpso;
-
+
DEBUG_CALL("tcp_ctl");
DEBUG_ARG("so = %lx", (long )so);
-
+
#if 0
/*
* Check if they're authorised
sb->sb_wptr += sb->sb_cc;
return 0;
}
-#endif
+#endif
command = (ntohl(so->so_faddr.s_addr) & 0xff);
-
+
switch(command) {
default: /* Check for exec's */
-
+
/*
* Check if it's pty_exec
*/
goto do_exec;
}
}
-
+
/*
* Nothing bound..
*/
/* tcp_fconnect(so); */
-
+
/* FALLTHROUGH */
case CTL_ALIAS:
sb->sb_cc = sprintf(sb->sb_wptr,
do_exec:
DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec));
return(fork_exec(so, ex_ptr->ex_exec, do_pty));
-
+
#if 0
case CTL_CMD:
for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {
- if (tmpso->so_emu == EMU_CTL &&
- !(tmpso->so_tcpcb?
+ if (tmpso->so_emu == EMU_CTL &&
+ !(tmpso->so_tcpcb?
(tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK))
:0)) {
/* Ooops, control connection already active */
register struct tcpcb *tp;
DEBUG_CALL("tcp_fasttimo");
-
+
so = tcb.so_next;
if (so)
for (; so != &tcb; so = so->so_next)
register int i;
DEBUG_CALL("tcp_slowtimo");
-
+
tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl;
/*
* Search through tcb's and update active timers.
int timer;
{
register int rexmt;
-
+
DEBUG_CALL("tcp_timers");
-
+
switch (timer) {
/*
* to a longer retransmit interval and retransmit one segment.
*/
case TCPT_REXMT:
-
+
/*
* XXXXX If a packet has timed out, then remove all the queued
* packets for that session.
*/
-
+
if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
/*
* This is a hack to suit our terminal server here at the uni of canberra
* keep retransmitting it, it'll keep eating the zeroes, so we keep
* retransmitting, and eventually the connection dies...
* (this only happens on incoming data)
- *
+ *
* So, if we were gonna drop the connection from too many retransmits,
* don't... instead halve the t_maxseg, which might break up the NULLs and
* let them through
- *
+ *
* *sigh*
*/
-
+
tp->t_maxseg >>= 1;
if (tp->t_maxseg < 32) {
/*
/* tp->t_softerror : ETIMEDOUT); */ /* XXX */
return (tp); /* XXX */
}
-
+
/*
* Set rxtshift to 6, which is still at the maximum
* backoff time
* size increase exponentially with time. If the
* window is larger than the path can handle, this
* exponential growth results in dropped packet(s)
- * almost immediately. To get more time between
+ * almost immediately. To get more time between
* drops but still "push" the network to take advantage
* of improving conditions, we switch from exponential
* to linear window opening at some threshold size.
/*
* tftp.c - a simple, read-only tftp server for qemu
- *
+ *
* Copyright (c) 2004 Magnus Damm <damm@opensource.se>
- *
+ *
* 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
struct tftp_session {
int in_use;
unsigned char filename[TFTP_FILENAME_MAX];
-
+
struct in_addr client_ip;
u_int16_t client_port;
-
+
int timestamp;
};
return bytes_read;
}
-static int tftp_send_error(struct tftp_session *spt,
+static int tftp_send_error(struct tftp_session *spt,
u_int16_t errorcode, const char *msg,
struct tftp_t *recv_tp)
{
m->m_data += if_maxlinkhdr;
tp = (void *)m->m_data;
m->m_data += sizeof(struct udpiphdr);
-
+
tp->tp_op = htons(TFTP_ERROR);
tp->x.tp_error.tp_error_code = htons(errorcode);
strcpy(tp->x.tp_error.tp_msg, msg);
nobytes = 2;
- m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
+ m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
sizeof(struct ip) - sizeof(struct udphdr);
udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
return 0;
}
-static int tftp_send_data(struct tftp_session *spt,
+static int tftp_send_data(struct tftp_session *spt,
u_int16_t block_nr,
struct tftp_t *recv_tp)
{
m->m_data += if_maxlinkhdr;
tp = (void *)m->m_data;
m->m_data += sizeof(struct udpiphdr);
-
+
tp->tp_op = htons(TFTP_DATA);
tp->x.tp_data.tp_block_nr = htons(block_nr);
return -1;
}
- m->m_len = sizeof(struct tftp_t) - (512 - nobytes) -
+ m->m_len = sizeof(struct tftp_t) - (512 - nobytes) -
sizeof(struct ip) - sizeof(struct udphdr);
udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
else {
return;
}
-
+
if (src[k] == '\0') {
break;
}
}
-
+
if (k >= n) {
return;
}
-
+
k++;
-
+
/* check mode */
if ((n - k) < 6) {
return;
}
-
+
if (memcmp(&src[k], "octet\0", 6) != 0) {
tftp_send_error(spt, 4, "Unsupported transfer mode", tp);
return;
}
/* check if the file exists */
-
+
if (tftp_read_data(spt, 0, spt->filename, 0) < 0) {
tftp_send_error(spt, 1, "File not found", tp);
return;
return;
}
- if (tftp_send_data(&tftp_sessions[s],
- ntohs(tp->x.tp_data.tp_block_nr) + 1,
+ if (tftp_send_data(&tftp_sessions[s],
+ ntohs(tp->x.tp_data.tp_block_nr) + 1,
tp) < 0) {
return;
}
struct udphdr udp;
u_int16_t tp_op;
union {
- struct {
+ struct {
u_int16_t tp_block_nr;
u_int8_t tp_buf[512];
} tp_data;
- struct {
+ struct {
u_int16_t tp_error_code;
u_int8_t tp_msg[512];
} tp_error;
/*
* Changes and additions relating to SLiRP
* Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
+ *
+ * Please read the file COPYRIGHT for the
* terms and conditions of the copyright.
*/
{
udb.so_next = udb.so_prev = &udb;
}
-/* m->m_data points at ip packet header
- * m->m_len length ip packet
+/* m->m_data points at ip packet header
+ * m->m_len length ip packet
* ip->ip_len length data (IPDU)
*/
void
register struct udphdr *uh;
/* struct mbuf *opts = 0;*/
int len;
- struct ip save_ip;
+ struct ip save_ip;
struct socket *so;
-
+
DEBUG_CALL("udp_input");
DEBUG_ARG("m = %lx", (long)m);
DEBUG_ARG("iphlen = %d", iphlen);
-
+
udpstat.udps_ipackets++;
/*
m_adj(m, len - ip->ip_len);
ip->ip_len = len;
}
-
+
/*
* Save a copy of the IP header in case we want restore it
* for sending an ICMP error message in response.
*/
- save_ip = *ip;
+ save_ip = *ip;
save_ip.ip_len+= iphlen; /* tcp_input subtracts this */
/*
((struct ipovly *)ip)->ih_x1 = 0;
((struct ipovly *)ip)->ih_len = uh->uh_ulen;
/* keep uh_sum for ICMP reply
- * uh->uh_sum = cksum(m, len + sizeof (struct ip));
- * if (uh->uh_sum) {
+ * uh->uh_sum = cksum(m, len + sizeof (struct ip));
+ * if (uh->uh_sum) {
*/
if(cksum(m, len + sizeof(struct ip))) {
udpstat.udps_badsum++;
if (so->so_lport != uh->uh_sport ||
so->so_laddr.s_addr != ip->ip_src.s_addr) {
struct socket *tmp;
-
+
for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) {
if (tmp->so_lport == uh->uh_sport &&
tmp->so_laddr.s_addr == ip->ip_src.s_addr) {
udp_last_so = so;
}
}
-
+
if (so == NULL) {
/*
* If there's no socket for this packet,
*/
if ((so = socreate()) == NULL) goto bad;
if(udp_attach(so) == -1) {
- DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
+ DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
errno,strerror(errno)));
sofree(so);
goto bad;
}
-
+
/*
* Setup fields
*/
/* udp_last_so = so; */
so->so_laddr = ip->ip_src;
so->so_lport = uh->uh_sport;
-
+
if ((so->so_iptos = udp_tos(so)) == 0)
so->so_iptos = ip->ip_tos;
-
+
/*
* XXXXX Here, check if it's in udpexec_list,
* and if it is, do the fork_exec() etc.
m->m_data -= iphlen;
*ip=save_ip;
DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno)));
- icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
+ icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
}
m_free(so->so_m); /* used for ICMP if error on sorecvfrom */
return;
}
-int udp_output2(struct socket *so, struct mbuf *m,
+int udp_output2(struct socket *so, struct mbuf *m,
struct sockaddr_in *saddr, struct sockaddr_in *daddr,
int iptos)
{
*/
m->m_data -= sizeof(struct udpiphdr);
m->m_len += sizeof(struct udpiphdr);
-
+
/*
* Fill in mbuf with extended UDP header
* and addresses and length put into network format.
((struct ip *)ui)->ip_ttl = ip_defttl;
((struct ip *)ui)->ip_tos = iptos;
-
+
udpstat.udps_opackets++;
-
+
error = ip_output(so, m);
-
+
return (error);
}
-int udp_output(struct socket *so, struct mbuf *m,
+int udp_output(struct socket *so, struct mbuf *m,
struct sockaddr_in *addr)
{
}
daddr.sin_addr = so->so_laddr;
daddr.sin_port = so->so_lport;
-
+
return udp_output2(so, m, &saddr, &daddr, so->so_iptos);
}
struct socket *so;
{
struct sockaddr_in addr;
-
+
if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
/*
* Here, we bind() the socket. Although not really needed
struct socket *so;
{
int i = 0;
-
+
while(udptos[i].tos) {
if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) ||
(udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) {
}
i++;
}
-
+
return 0;
}
CTL_MSG *nmsg;
char buff[sizeof(CTL_MSG)];
u_char type;
-
+
struct talk_request {
struct talk_request *next;
struct socket *udp_so;
struct socket *tcp_so;
} *req;
-
- static struct talk_request *req_tbl = 0;
-
+
+ static struct talk_request *req_tbl = 0;
+
#endif
-
+
struct cu_header {
uint16_t d_family; // destination family
uint16_t d_port; // destination port
*/
if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0)
return;
-
+
#define IS_OLD (so->so_emu == EMU_TALK)
#define COPY_MSG(dest, src) { dest->type = src->type; \
OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port;
OTOSIN(omsg, ctl_addr)->sin_addr = our_addr;
strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD);
- } else { /* new talk */
+ } else { /* new talk */
omsg = (CTL_MSG_OLD *) buff;
nmsg = mtod(m, CTL_MSG *);
type = nmsg->type;
OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr;
strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD);
}
-
- if (type == LOOK_UP)
+
+ if (type == LOOK_UP)
return; /* for LOOK_UP this is enough */
-
+
if (IS_OLD) { /* make a copy of the message */
COPY_MSG(nmsg, omsg);
nmsg->vers = 1;
* ports, 517 and 518. This is why we have two copies
* of the message, one in old talk and one in new talk
* format.
- */
+ */
if (type == ANNOUNCE) {
int s;
u_short temp_port;
-
+
for(req = req_tbl; req; req = req->next)
if (so == req->udp_so)
break; /* found it */
-
+
if (!req) { /* no entry for so, create new */
req = (struct talk_request *)
malloc(sizeof(struct talk_request));
req->udp_so = so;
- req->tcp_so = solisten(0,
- OTOSIN(omsg, addr)->sin_addr.s_addr,
+ req->tcp_so = solisten(0,
+ OTOSIN(omsg, addr)->sin_addr.s_addr,
OTOSIN(omsg, addr)->sin_port,
SS_FACCEPTONCE);
req->next = req_tbl;
req_tbl = req;
- }
-
+ }
+
/* replace port number in addr field */
addrlen = sizeof(addr);
- getsockname(req->tcp_so->s,
+ getsockname(req->tcp_so->s,
(struct sockaddr *) &addr,
- &addrlen);
+ &addrlen);
OTOSIN(omsg, addr)->sin_port = addr.sin_port;
OTOSIN(omsg, addr)->sin_addr = our_addr;
OTOSIN(nmsg, addr)->sin_port = addr.sin_port;
- OTOSIN(nmsg, addr)->sin_addr = our_addr;
-
+ OTOSIN(nmsg, addr)->sin_addr = our_addr;
+
/* send LEAVE_INVITEs */
temp_port = OTOSIN(omsg, ctl_addr)->sin_port;
OTOSIN(omsg, ctl_addr)->sin_port = 0;
OTOSIN(nmsg, ctl_addr)->sin_port = 0;
- omsg->type = nmsg->type = LEAVE_INVITE;
-
+ omsg->type = nmsg->type = LEAVE_INVITE;
+
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
addr.sin_addr = our_addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(517);
- sendto(s, (char *)omsg, sizeof(*omsg), 0,
+ sendto(s, (char *)omsg, sizeof(*omsg), 0,
(struct sockaddr *)&addr, sizeof(addr));
addr.sin_port = htons(518);
sendto(s, (char *)nmsg, sizeof(*nmsg), 0,
(struct sockaddr *) &addr, sizeof(addr));
closesocket(s) ;
- omsg->type = nmsg->type = ANNOUNCE;
+ omsg->type = nmsg->type = ANNOUNCE;
OTOSIN(omsg, ctl_addr)->sin_port = temp_port;
OTOSIN(nmsg, ctl_addr)->sin_port = temp_port;
}
-
- /*
+
+ /*
* If it is a DELETE message, we send a copy to the
* local daemons. Then we delete the entry corresponding
* to our socket from the request table.
*/
-
+
if (type == DELETE) {
struct talk_request *temp_req, *req_next;
int s;
u_short temp_port;
-
+
temp_port = OTOSIN(omsg, ctl_addr)->sin_port;
OTOSIN(omsg, ctl_addr)->sin_port = 0;
OTOSIN(nmsg, ctl_addr)->sin_port = 0;
-
+
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
addr.sin_addr = our_addr;
addr.sin_family = AF_INET;
sendto(s, (char *)nmsg, sizeof(*nmsg), 0,
(struct sockaddr *)&addr, sizeof(addr));
closesocket(s);
-
+
OTOSIN(omsg, ctl_addr)->sin_port = temp_port;
OTOSIN(nmsg, ctl_addr)->sin_port = temp_port;
}
}
}
-
- return;
+
+ return;
#endif
-
+
case EMU_CUSEEME:
-
+
/*
* Cu-SeeMe emulation.
* Hopefully the packet is more that 16 bytes long. We don't
* do any other tests, just replace the address and port
* fields.
- */
+ */
if (m->m_len >= sizeof (*cu_head)) {
if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0)
return;
cu_head->s_port = addr.sin_port;
cu_head->so_addr = our_addr.s_addr;
}
-
+
return;
}
}
struct sockaddr_in addr;
struct socket *so;
int addrlen = sizeof(struct sockaddr_in), opt = 1;
-
+
if ((so = socreate()) == NULL) {
free(so);
return NULL;
}
setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
/* setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); */
-
+
getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
so->so_fport = addr.sin_port;
if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
so->so_faddr = alias_addr;
else
so->so_faddr = addr.sin_addr;
-
+
so->so_lport = lport;
so->so_laddr.s_addr = laddr;
if (flags != SS_FACCEPTONCE)
so->so_expire = 0;
-
+
so->so_state = SS_ISFCONNECTED;
-
+
return so;
}
u_int8_t udp_tos _P((struct socket *));
void udp_emu _P((struct socket *, struct mbuf *));
struct socket * udp_listen _P((u_int, u_int32_t, u_int, int));
-int udp_output2(struct socket *so, struct mbuf *m,
+int udp_output2(struct socket *so, struct mbuf *m,
struct sockaddr_in *saddr, struct sockaddr_in *daddr,
int iptos);
#endif
/*
* Software MMU support
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
#endif
"2:\n"
: "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
+ : "r" (ptr),
+ "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
+ "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
"i" (CPU_MEM_INDEX),
#endif
"2:\n"
: "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
+ : "r" (ptr),
+ "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
+ "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
"i" (CPU_MEM_INDEX),
#error unsupported size
#endif
"2:\n"
- :
- : "r" (ptr),
+ :
+ : "r" (ptr),
/* NOTE: 'q' would be needed as constraint, but we could not use it
with T1 ! */
- "r" (v),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
+ "r" (v),
+ "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
+ "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
"i" (CPU_MEM_INDEX),
addr = ptr;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
is_user = CPU_MEM_INDEX;
- if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+ if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
} else {
addr = ptr;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
is_user = CPU_MEM_INDEX;
- if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
+ if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
} else {
addr = ptr;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
is_user = CPU_MEM_INDEX;
- if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
+ if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
} else {
/*
* Software MMU support
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
#define ADDR_READ addr_read
#endif
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
+static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user,
void *retaddr);
-static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
+static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
target_ulong tlb_addr)
{
DATA_TYPE res;
target_ulong tlb_addr;
target_phys_addr_t physaddr;
void *retaddr;
-
+
/* test if there is match for unaligned or IO access */
/* XXX: could done more in memory macro in a non portable way */
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
#ifdef ALIGNED_ONLY
do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
#endif
- res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
+ res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
is_user, retaddr);
} else {
/* unaligned/aligned access in the same page */
}
/* handle all unaligned cases */
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
+static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user,
void *retaddr)
{
/* slow unaligned access (it spans two pages) */
addr1 = addr & ~(DATA_SIZE - 1);
addr2 = addr1 + DATA_SIZE;
- res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
+ res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
is_user, retaddr);
- res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
+ res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
is_user, retaddr);
shift = (addr & (DATA_SIZE - 1)) * 8;
#ifdef TARGET_WORDS_BIGENDIAN
#ifndef SOFTMMU_CODE_ACCESS
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
- DATA_TYPE val,
+static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
+ DATA_TYPE val,
int is_user,
void *retaddr);
-static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
+static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
DATA_TYPE val,
target_ulong tlb_addr,
void *retaddr)
#endif
}
-void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
+void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE val,
int is_user)
{
target_ulong tlb_addr;
void *retaddr;
int index;
-
+
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
redo:
tlb_addr = env->tlb_table[is_user][index].addr_write;
#ifdef ALIGNED_ONLY
do_unaligned_access(addr, 1, is_user, retaddr);
#endif
- glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
+ glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
is_user, retaddr);
} else {
/* aligned/unaligned access in the same page */
}
/* handles all unaligned cases */
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
+static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE val,
int is_user,
void *retaddr)
/* XXX: not efficient, but simple */
for(i = 0;i < DATA_SIZE; i++) {
#ifdef TARGET_WORDS_BIGENDIAN
- glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
+ glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
is_user, retaddr);
#else
- glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
+ glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
is_user, retaddr);
#endif
}
#define FBFCC(x) (((x)&0x3)<<20) /* v9 */
\f
/* The order of the opcodes in the table is significant:
-
+
* The assembler requires that all instances of the same mnemonic must
be consecutive. If they aren't, the assembler will bomb at runtime.
>> ((8 * sizeof (int)) - bits) )
static char *reg_names[] =
-{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
- "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
- "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
- "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
- "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
+ "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
+ "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
"f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
"f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
/* psr, wim, tbr, fpsr, cpsr are v8 only. */
/* Nonzero means that we have found a plus sign in the args
field of the opcode table. */
int found_plus = 0;
-
+
/* Nonzero means we have an annulled branch. */
int is_annulled = 0;
} /* while there are comma started args */
(*info->fprintf_func) (stream, " ");
-
+
switch (*s)
{
case '+':
not before it. */
if (found_plus)
imm_added_to_rs1 = 1;
-
+
if (imm <= 9)
(*info->fprintf_func) (stream, "%d", imm);
else
case 'o':
(*info->fprintf_func) (stream, "%%asi");
break;
-
+
case 'W':
(*info->fprintf_func) (stream, "%%tick");
break;
(*info->fprintf_func) (stream, "%d", X_RD (insn));
break;
}
-
+
case 'M':
(*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
break;
-
+
case 'm':
(*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
break;
-
+
case 'L':
info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
(*info->print_address_func) (info->target, info);
&& X_RD (prev_insn) == X_RS1 (insn))
{
(*info->fprintf_func) (stream, "\t! ");
- info->target =
+ info->target =
((unsigned) 0xFFFFFFFF
& ((int) X_IMM22 (prev_insn) << 10));
if (imm_added_to_rs1)
static tap_win32_overlapped_t tap_overlapped;
-static tun_buffer_t* get_buffer_from_free_list(tap_win32_overlapped_t* const overlapped)
+static tun_buffer_t* get_buffer_from_free_list(tap_win32_overlapped_t* const overlapped)
{
tun_buffer_t* buffer = NULL;
WaitForSingleObject(overlapped->free_list_semaphore, INFINITE);
ReleaseSemaphore(overlapped->free_list_semaphore, 1, NULL);
}
-static tun_buffer_t* get_buffer_from_output_queue(tap_win32_overlapped_t* const overlapped, const int block)
+static tun_buffer_t* get_buffer_from_output_queue(tap_win32_overlapped_t* const overlapped, const int block)
{
tun_buffer_t* buffer = NULL;
DWORD result, timeout = block ? INFINITE : 0L;
// Non-blocking call
- result = WaitForSingleObject(overlapped->output_queue_semaphore, timeout);
+ result = WaitForSingleObject(overlapped->output_queue_semaphore, timeout);
- switch (result)
- {
+ switch (result)
+ {
// The semaphore object was signaled.
- case WAIT_OBJECT_0:
+ case WAIT_OBJECT_0:
EnterCriticalSection(&overlapped->output_queue_cs);
buffer = overlapped->output_queue_front;
}
LeaveCriticalSection(&overlapped->output_queue_cs);
- break;
+ break;
// Semaphore was nonsignaled, so a time-out occurred.
- case WAIT_TIMEOUT:
+ case WAIT_TIMEOUT:
// Cannot open another window.
- break;
+ break;
}
return buffer;
}
-static tun_buffer_t* get_buffer_from_output_queue_immediate (tap_win32_overlapped_t* const overlapped)
+static tun_buffer_t* get_buffer_from_output_queue_immediate (tap_win32_overlapped_t* const overlapped)
{
return get_buffer_from_output_queue(overlapped, 0);
}
return -1;
}
- snprintf(connection_string,
+ snprintf(connection_string,
sizeof(connection_string),
"%s\\%s\\Connection",
NETWORK_CONNECTIONS_KEY, enum_name);
0,
KEY_READ,
&connection_key);
-
+
if (status == ERROR_SUCCESS) {
len = sizeof (name_data);
status = RegQueryValueEx(
InitializeCriticalSection(&overlapped->output_queue_cs);
InitializeCriticalSection(&overlapped->free_list_cs);
- overlapped->output_queue_semaphore = CreateSemaphore(
+ overlapped->output_queue_semaphore = CreateSemaphore(
NULL, // default security attributes
0, // initial count
TUN_MAX_BUFFER_COUNT, // maximum count
fprintf(stderr, "error creating output queue semaphore!\n");
}
- overlapped->free_list_semaphore = CreateSemaphore(
+ overlapped->free_list_semaphore = CreateSemaphore(
NULL, // default security attributes
TUN_MAX_BUFFER_COUNT, // initial count
TUN_MAX_BUFFER_COUNT, // maximum count
fprintf(stderr, "error creating tap_semaphore.\n");
}
-static int tap_win32_write(tap_win32_overlapped_t *overlapped,
+static int tap_win32_write(tap_win32_overlapped_t *overlapped,
const void *buffer, unsigned long size)
{
unsigned long write_size;
result = WriteFile(overlapped->handle, buffer, size,
&write_size, &overlapped->write_overlapped);
-
- if (!result) {
+
+ if (!result) {
switch (error = GetLastError())
- {
- case ERROR_IO_PENDING:
+ {
+ case ERROR_IO_PENDING:
#ifndef TUN_ASYNCHRONOUS_WRITES
WaitForSingleObject(overlapped->write_event, INFINITE);
#endif
break;
default:
return -1;
- }
+ }
}
return 0;
return 0;
}
-static int tap_win32_read(tap_win32_overlapped_t *overlapped,
+static int tap_win32_read(tap_win32_overlapped_t *overlapped,
uint8_t **pbuf, int max_size)
{
int size = 0;
return size;
}
-static void tap_win32_free_buffer(tap_win32_overlapped_t *overlapped,
- char* pbuf)
+static void tap_win32_free_buffer(tap_win32_overlapped_t *overlapped,
+ char* pbuf)
{
tun_buffer_t* buffer = (tun_buffer_t*)pbuf;
put_buffer_on_free_list(overlapped, buffer);
}
-static int tap_win32_open(tap_win32_overlapped_t **phandle,
+static int tap_win32_open(tap_win32_overlapped_t **phandle,
const char *prefered_name)
{
char device_path[256];
int tap_win32_init(VLANState *vlan, const char *ifname)
{
TAPState *s;
-
+
s = qemu_mallocz(sizeof(TAPState));
if (!s)
return -1;
}
s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
-
+
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"tap: ifname=%s", ifname);
/*
* ARM virtual CPU header
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
uint32_t banked_spsr[6];
uint32_t banked_r13[6];
uint32_t banked_r14[6];
-
+
/* These hold r8-r12. */
uint32_t usr_regs[5];
uint32_t fiq_regs[5];
-
+
/* cpsr flag cache for faster execution */
uint32_t CF; /* 0 or 1 */
uint32_t VF; /* V is the bit 31. All other bits are undefined */
/* Temporary variables if we don't have spare fp regs. */
float32 tmp0s, tmp1s;
float64 tmp0d, tmp1d;
-
+
float_status fp_status;
} vfp;
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
-int cpu_arm_signal_handler(int host_signum, void *pinfo,
+int cpu_arm_signal_handler(int host_signum, void *pinfo,
void *puc);
#define CPSR_M (0x1f)
{
int ZF;
ZF = (env->NZF == 0);
- return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
+ return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
(env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
| (env->thumb << 5);
}
/*
* ARM execution defines
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
free(env);
}
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
void do_interrupt (CPUState *env)
{
unsigned int Fd, Fm, Fn, nRc = 1;
//printk("DoubleCPDO(0x%08x)\n",opcode);
-
+
Fm = getFm(opcode);
if (CONSTANT_FM(opcode))
{
rFm = getDoubleConstant(Fm);
}
else
- {
+ {
switch (fpa11->fType[Fm])
{
case typeSingle:
case typeDouble:
rFn = fpa11->fpreg[Fn].fDouble;
break;
-
+
default: return 0;
}
}
case NRM_CODE:
break;
-
+
default:
{
nRc = 0;
float64 float64_pow(float64 rFn,float64 rFm)
{
- return float64_exp(float64_mul(rFm,float64_ln(rFn)));
+ return float64_exp(float64_mul(rFm,float64_ln(rFn)));
}
float64 float64_pol(float64 rFn,float64 rFm)
{
- return float64_arctan(float64_div(rFn,rFm));
+ return float64_arctan(float64_div(rFn,rFm));
}
#endif
unsigned int Fd, Fm, Fn, nRc = 1;
//printk("ExtendedCPDO(0x%08x)\n",opcode);
-
+
Fm = getFm(opcode);
if (CONSTANT_FM(opcode))
{
rFm = getExtendedConstant(Fm);
}
else
- {
+ {
switch (fpa11->fType[Fm])
{
case typeSingle:
case typeDouble:
rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status);
break;
-
+
case typeExtended:
rFm = fpa11->fpreg[Fm].fExtended;
break;
-
+
default: return 0;
}
}
-
+
if (!MONADIC_INSTRUCTION(opcode))
{
Fn = getFn(opcode);
case typeDouble:
rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
break;
-
+
case typeExtended:
rFn = fpa11->fpreg[Fn].fExtended;
break;
-
+
default: return 0;
}
}
case NRM_CODE:
break;
-
+
default:
{
nRc = 0;
}
}
-
+
if (0 != nRc) fpa11->fType[Fd] = typeExtended;
return nRc;
}
floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
{
- return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn)));
+ return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn)));
}
floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
{
- return floatx80_arctan(floatx80_div(rFn,rFm));
+ return floatx80_arctan(floatx80_div(rFn,rFm));
}
#endif
{
int i;
FPA11 *fpa11 = GET_FPA11();
-
+
/* initialize the register type array */
for (i=0;i<=7;i++)
{
fpa11->fType[i] = typeNone;
}
-
+
/* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
fpa11->fpsr = FP_EMULATOR | BIT_AC;
-
+
/* FPCR: set SB, AB and DA bits, clear all others */
#if MAINTAIN_FPCR
fpa11->fpcr = MASK_RESET;
#if MAINTAIN_FPCR
fpa11->fpcr &= ~MASK_ROUNDING_MODE;
-#endif
+#endif
switch (opcode & MASK_ROUNDING_MODE)
{
default:
case ROUND_TO_NEAREST:
rounding_mode = float_round_nearest_even;
-#if MAINTAIN_FPCR
+#if MAINTAIN_FPCR
fpa11->fpcr |= ROUND_TO_NEAREST;
-#endif
+#endif
break;
-
+
case ROUND_TO_PLUS_INFINITY:
rounding_mode = float_round_up;
-#if MAINTAIN_FPCR
+#if MAINTAIN_FPCR
fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
-#endif
+#endif
break;
-
+
case ROUND_TO_MINUS_INFINITY:
rounding_mode = float_round_down;
-#if MAINTAIN_FPCR
+#if MAINTAIN_FPCR
fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
-#endif
+#endif
break;
-
+
case ROUND_TO_ZERO:
rounding_mode = float_round_to_zero;
-#if MAINTAIN_FPCR
+#if MAINTAIN_FPCR
fpa11->fpcr |= ROUND_TO_ZERO;
-#endif
+#endif
break;
}
set_float_rounding_mode(rounding_mode, &fpa11->fp_status);
FPA11 *fpa11 = GET_FPA11();
#if MAINTAIN_FPCR
fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
-#endif
+#endif
switch (opcode & MASK_ROUNDING_PRECISION)
{
case ROUND_SINGLE:
rounding_precision = 32;
-#if MAINTAIN_FPCR
+#if MAINTAIN_FPCR
fpa11->fpcr |= ROUND_SINGLE;
-#endif
+#endif
break;
-
+
case ROUND_DOUBLE:
rounding_precision = 64;
-#if MAINTAIN_FPCR
+#if MAINTAIN_FPCR
fpa11->fpcr |= ROUND_DOUBLE;
-#endif
+#endif
break;
-
+
case ROUND_EXTENDED:
rounding_precision = 80;
-#if MAINTAIN_FPCR
+#if MAINTAIN_FPCR
fpa11->fpcr |= ROUND_EXTENDED;
-#endif
+#endif
break;
-
+
default: rounding_precision = 80;
}
set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status);
{
unsigned int nRc = 0;
// unsigned long flags;
- FPA11 *fpa11;
+ FPA11 *fpa11;
// save_flags(flags); sti();
qemufpa=qfpa;
user_registers=qregs;
-
+
#if 0
fprintf(stderr,"emulating FP insn 0x%08x, PC=0x%08x\n",
opcode, qregs[REG_PC]);
}
}
break;
-
- case 0xe:
+
+ case 0xe:
if (opcode & 0x10)
return EmulateCPDO(opcode);
else
return EmulateCPRT(opcode);
break;
-
+
default: return 0;
}
}
/*
NetWinder Floating Point Emulator
(c) Rebel.com, 1998-1999
-
+
Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
This program is free software; you can redistribute it and/or modify
{
FPA11 *fpa11 = GET_FPA11();
unsigned int Fd, nType, nDest, nRc = 1;
-
+
//printk("EmulateCPDO(0x%08x)\n",opcode);
/* Get the destination size. If not valid let Linux perform
an invalid instruction trap. */
nDest = getDestinationSize(opcode);
if (typeNone == nDest) return 0;
-
+
SetRoundingMode(opcode);
-
+
/* Compare the size of the operands in Fn and Fm.
Choose the largest size and perform operations in that size,
- in order to make use of all the precision of the operands.
- If Fm is a constant, we just grab a constant of a size
+ in order to make use of all the precision of the operands.
+ If Fm is a constant, we just grab a constant of a size
matching the size of the operand in Fn. */
if (MONADIC_INSTRUCTION(opcode))
nType = nDest;
else
nType = fpa11->fType[getFn(opcode)];
-
+
if (!CONSTANT_FM(opcode))
{
register unsigned int Fm = getFm(opcode);
case typeSingle:
{
if (typeDouble == nType)
- fpa11->fpreg[Fd].fSingle =
+ fpa11->fpreg[Fd].fSingle =
float64_to_float32(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status);
else
- fpa11->fpreg[Fd].fSingle =
+ fpa11->fpreg[Fd].fSingle =
floatx80_to_float32(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
}
break;
-
+
case typeDouble:
{
if (typeSingle == nType)
- fpa11->fpreg[Fd].fDouble =
+ fpa11->fpreg[Fd].fDouble =
float32_to_float64(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status);
else
- fpa11->fpreg[Fd].fDouble =
+ fpa11->fpreg[Fd].fDouble =
floatx80_to_float64(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
}
break;
-
+
case typeExtended:
{
if (typeSingle == nType)
- fpa11->fpreg[Fd].fExtended =
+ fpa11->fpreg[Fd].fExtended =
float32_to_floatx80(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status);
else
- fpa11->fpreg[Fd].fExtended =
+ fpa11->fpreg[Fd].fExtended =
float64_to_floatx80(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status);
}
break;
}
-
+
fpa11->fType[Fd] = nDest;
}
-
+
return nRc;
}
p[0] = tget32(addr + 4);
p[1] = tget32(addr); /* sign & exponent */
#endif
-}
+}
static inline
void loadExtended(const unsigned int Fn,const unsigned int *pMem)
p[0] = tget32(addr); /* sign & exponent */
p[1] = tget32(addr + 8); /* ls bits */
p[2] = tget32(addr + 4); /* ms bits */
-}
+}
static inline
void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
p = (unsigned int*)&(fpa11->fpreg[Fn]);
x = tget32(addr);
fpa11->fType[Fn] = (x >> 14) & 0x00000003;
-
+
switch (fpa11->fType[Fn])
{
case typeSingle:
p[1] = tget32(addr + 4); /* double msw */
p[2] = 0; /* empty */
}
- break;
-
+ break;
+
case typeExtended:
{
p[1] = tget32(addr + 8);
p[2] = tget32(addr + 4); /* msw */
- p[0] = (x & 0x80003fff);
+ p[0] = (x & 0x80003fff);
}
break;
}
FPA11 *fpa11 = GET_FPA11();
float32 val;
register unsigned int *p = (unsigned int*)&val;
-
+
switch (fpa11->fType[Fn])
{
- case typeDouble:
+ case typeDouble:
val = float64_to_float32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
break;
- case typeExtended:
+ case typeExtended:
val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
break;
default: val = fpa11->fpreg[Fn].fSingle;
}
-
+
tput32(addr, p[0]);
-}
+}
static inline
void storeDouble(const unsigned int Fn,unsigned int *pMem)
switch (fpa11->fType[Fn])
{
- case typeSingle:
+ case typeSingle:
val = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
break;
tput32(addr, p[1]); /* msw */
tput32(addr + 4, p[0]); /* lsw */
#endif
-}
+}
static inline
void storeExtended(const unsigned int Fn,unsigned int *pMem)
FPA11 *fpa11 = GET_FPA11();
floatx80 val;
register unsigned int *p = (unsigned int*)&val;
-
+
switch (fpa11->fType[Fn])
{
- case typeSingle:
+ case typeSingle:
val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
break;
- case typeDouble:
+ case typeDouble:
val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
break;
default: val = fpa11->fpreg[Fn].fExtended;
}
-
+
tput32(addr, p[0]); /* sign & exp */
tput32(addr + 8, p[1]);
tput32(addr + 4, p[2]); /* msw */
-}
+}
static inline
void storeMultiple(const unsigned int Fn,unsigned int *pMem)
target_ulong addr = (target_ulong)(long)pMem;
FPA11 *fpa11 = GET_FPA11();
register unsigned int nType, *p;
-
+
p = (unsigned int*)&(fpa11->fpreg[Fn]);
nType = fpa11->fType[Fn];
-
+
switch (nType)
{
case typeSingle:
tput32(addr + 4, p[1]); /* double msw */
tput32(addr, nType << 14);
}
- break;
-
+ break;
+
case typeExtended:
{
tput32(addr + 4, p[2]); /* msw */
case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
default: nRc = 0;
}
-
+
if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
return nRc;
}
{
unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
write_back = WRITE_BACK(opcode);
-
+
//printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
SetRoundingMode(ROUND_TO_NEAREST);
-
+
pBase = (unsigned int*)readRegister(getRn(opcode));
if (REG_PC == getRn(opcode))
{
case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
default: nRc = 0;
}
-
+
if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
return nRc;
}
{
unsigned int i, Fd, *pBase, *pAddress, *pFinal,
write_back = WRITE_BACK(opcode);
-
+
pBase = (unsigned int*)readRegister(getRn(opcode));
if (REG_PC == getRn(opcode))
{
pBase += 2;
write_back = 0;
}
-
+
pFinal = pBase;
if (BIT_UP_SET(opcode))
pFinal += getOffset(opcode);
unsigned int nRc = 0;
//printk("EmulateCPDT(0x%08x)\n",opcode);
-
+
if (LDF_OP(opcode))
{
nRc = PerformLDF(opcode);
else if (STF_OP(opcode))
{
nRc = PerformSTF(opcode);
- }
+ }
else if (SFM_OP(opcode))
{
nRc = PerformSFM(opcode);
{
nRc = 0;
}
-
+
return nRc;
}
#endif
{
case FLT_CODE >> 20: nRc = PerformFLT(opcode); break;
case FIX_CODE >> 20: nRc = PerformFIX(opcode); break;
-
+
case WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break;
case RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break;
default: nRc = 0;
}
-
+
return nRc;
}
unsigned int PerformFLT(const unsigned int opcode)
{
FPA11 *fpa11 = GET_FPA11();
-
+
unsigned int nRc = 1;
SetRoundingMode(opcode);
int32_to_float64(readRegister(getRd(opcode)), &fpa11->fp_status);
}
break;
-
+
case ROUND_EXTENDED:
{
fpa11->fType[getFn(opcode)] = typeExtended;
int32_to_floatx80(readRegister(getRd(opcode)), &fpa11->fp_status);
}
break;
-
+
default: nRc = 0;
}
-
+
return nRc;
}
FPA11 *fpa11 = GET_FPA11();
unsigned int nRc = 1;
unsigned int Fn = getFm(opcode);
-
+
SetRoundingMode(opcode);
switch (fpa11->fType[Fn])
float64_to_int32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status));
}
break;
-
+
case typeExtended:
{
writeRegister(getRd(opcode),
floatx80_to_int32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status));
}
break;
-
+
default: nRc = 0;
}
-
+
return nRc;
}
-
+
static unsigned int __inline__
PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
{
{
flags |= CC_NEGATIVE;
}
-
+
/* test for equal condition */
if (floatx80_eq(Fn,Fm, &fpa11->fp_status))
{
{
flags |= CC_CARRY;
}
-
+
writeConditionCodes(flags);
return 1;
}
/* This instruction sets the flags N, Z, C, V in the FPSR. */
-
+
static unsigned int PerformComparison(const unsigned int opcode)
{
FPA11 *fpa11 = GET_FPA11();
comparison (cheaper than an 80-bit one). */
switch (fpa11->fType[Fn])
{
- case typeSingle:
+ case typeSingle:
//printk("single.\n");
if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
goto unordered;
rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
break;
- case typeDouble:
+ case typeDouble:
//printk("double.\n");
if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
goto unordered;
rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
break;
-
- case typeExtended:
+
+ case typeExtended:
//printk("extended.\n");
if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
goto unordered;
rFn = fpa11->fpreg[Fn].fExtended;
break;
-
+
default: return 0;
}
//printk("Fm = r%d which contains a ",Fm);
switch (fpa11->fType[Fm])
{
- case typeSingle:
+ case typeSingle:
//printk("single.\n");
if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
goto unordered;
rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
break;
- case typeDouble:
+ case typeDouble:
//printk("double.\n");
if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
goto unordered;
rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status);
break;
-
- case typeExtended:
+
+ case typeExtended:
//printk("extended.\n");
if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
goto unordered;
rFm = fpa11->fpreg[Fm].fExtended;
break;
-
+
default: return 0;
}
}
{ 0xa000000000000000ULL, 0x4001}, /* extended 5.0 */
{ 0x8000000000000000ULL, 0x3ffe}, /* extended 0.5 */
{ 0xa000000000000000ULL, 0x4002} /* extended 10.0 */
-};
+};
const float64 float64Constant[] = {
0x0000000000000000ULL, /* double 0.0 */
0x4014000000000000ULL, /* double 5.0 */
0x3fe0000000000000ULL, /* double 0.5 */
0x4024000000000000ULL /* double 10.0 */
-};
+};
const float32 float32Constant[] = {
0x00000000, /* single 0.0 */
0x40a00000, /* single 5.0 */
0x3f000000, /* single 0.5 */
0x41200000 /* single 10.0 */
-};
+};
unsigned int getTransferLength(const unsigned int opcode)
{
unsigned int nRc;
-
+
switch (opcode & MASK_TRANSFER_LENGTH)
{
case 0x00000000: nRc = 1; break; /* single precision */
case 0x00400000: nRc = 3; break; /* extended precision */
default: nRc = 0;
}
-
+
return(nRc);
}
unsigned int getRegisterCount(const unsigned int opcode)
{
unsigned int nRc;
-
+
switch (opcode & MASK_REGISTER_COUNT)
{
case 0x00000000: nRc = 4; break;
case 0x00408000: nRc = 3; break;
default: nRc = 0;
}
-
+
return(nRc);
}
unsigned int getRoundingPrecision(const unsigned int opcode)
{
unsigned int nRc;
-
+
switch (opcode & MASK_ROUNDING_PRECISION)
{
case 0x00000000: nRc = 1; break;
case 0x00080000: nRc = 3; break;
default: nRc = 0;
}
-
+
return(nRc);
}
unsigned int getDestinationSize(const unsigned int opcode)
{
unsigned int nRc;
-
+
switch (opcode & MASK_DESTINATION_SIZE)
{
case 0x00000000: nRc = typeSingle; break;
case 0x00080000: nRc = typeExtended; break;
default: nRc = typeNone;
}
-
+
return(nRc);
}
/*
ARM Floating Point Instruction Classes
-| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|c o n d|1 1 0 P|U|u|W|L| Rn |v| Fd |0|0|0|1| o f f s e t | CPDT
|c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|0|1| o f f s e t | CPDT
-| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|c o n d|1 1 1 0|a|b|c|d|e| Fn |j| Fd |0|0|0|1|f|g|h|0|i| Fm | CPDO
|c o n d|1 1 1 0|a|b|c|L|e| Fn | Rd |0|0|0|1|f|g|h|1|i| Fm | CPRT
|c o n d|1 1 1 0|a|b|c|1|e| Fn |1|1|1|1|0|0|0|1|f|g|h|1|i| Fm | comparisons
-| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
CPDT data transfer instructions
LDF, STF, LFM, SFM
-
+
CPDO dyadic arithmetic instructions
ADF, MUF, SUF, RSF, DVF, RDF,
POW, RPW, RMF, FML, FDV, FRD, POL
CPDO monadic arithmetic instructions
MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
SIN, COS, TAN, ASN, ACS, ATN, URD, NRM
-
+
CPRT joint arithmetic/data transfer instructions
FIX (arithmetic followed by load/store)
FLT (load/store followed by arithmetic)
W write back bit: 1 = update base register (Rn)
L load/store bit: 0 = store, 1 = load
Rn base register
-Rd destination/source register
+Rd destination/source register
Fd floating point destination register
Fn floating point source register
Fm floating point source register or floating point constant
{
extern const floatx80 floatx80Constant[];
return floatx80Constant[nIndex];
-}
+}
static inline const float64 getDoubleConstant(const unsigned int nIndex)
{
extern const float64 float64Constant[];
return float64Constant[nIndex];
-}
+}
static inline const float32 getSingleConstant(const unsigned int nIndex)
{
extern const float32 float32Constant[];
return float32Constant[nIndex];
-}
+}
extern unsigned int getRegisterCount(const unsigned int opcode);
extern unsigned int getDestinationSize(const unsigned int opcode);
EXCEPTION TRAP ENABLE BYTE
SYSTEM CONTROL BYTE
CUMULATIVE EXCEPTION FLAGS BYTE
-
+
The FPCR is a 32 bit register consisting of bit flags.
*/
#define MASK_SYSID 0xff000000
#define BIT_HARDWARE 0x80000000
-#define FP_EMULATOR 0x01000000 /* System ID for emulator */
+#define FP_EMULATOR 0x01000000 /* System ID for emulator */
#define FP_ACCELERATOR 0x81000000 /* System ID for FPA11 */
/* EXCEPTION TRAP ENABLE BYTE
rFm = getSingleConstant(Fm);
}
else
- {
+ {
switch (fpa11->fType[Fm])
{
case typeSingle:
rFm = fpa11->fpreg[Fm].fSingle;
break;
-
+
default: return 0;
}
}
case NRM_CODE:
break;
-
+
default:
{
nRc = 0;
float32 float32_pow(float32 rFn,float32 rFm)
{
- return float32_exp(float32_mul(rFm,float32_ln(rFn)));
+ return float32_exp(float32_mul(rFm,float32_ln(rFn)));
}
float32 float32_pol(float32 rFn,float32 rFm)
{
- return float32_arctan(float32_div(rFn,rFm));
+ return float32_arctan(float32_div(rFn,rFm));
}
#endif
/*
* ARM micro operations
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2005 CodeSourcery, LLC
*
}
else
T0 = res;
-
+
FORCE_RET();
}
}
else
T0 = res;
-
+
FORCE_RET();
}
void OPPROTO op_vfp_mrrd(void)
{
CPU_DoubleU u;
-
+
u.d = FT0d;
T0 = u.l.lower;
T1 = u.l.upper;
void OPPROTO op_vfp_mdrr(void)
{
CPU_DoubleU u;
-
+
u.l.lower = T0;
u.l.upper = T1;
FT0d = u.d;
/*
* ARM helper routines
- *
+ *
* Copyright (c) 2005 CodeSourcery, LLC
*
* This library is free software; you can redistribute it and/or
/*
* ARM micro operations (templates for various register related
* operations)
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
/*
* ARM translation
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2005 CodeSourcery, LLC
*
1, /* bic */
1, /* mvn */
};
-
+
static GenOpFunc1 *gen_shift_T1_im[4] = {
gen_op_shll_T1_im,
gen_op_shrl_T1_im,
int extra)
{
int val, rm;
-
+
if (insn & (1 << 22)) {
/* immediate */
val = (insn & 0xf) | ((insn >> 4) & 0xf0);
delta_m = 0;
delta_d = 0;
bank_mask = 0;
-
+
if (veclen > 0) {
if (dp)
bank_mask = 0xc;
static void disas_arm_insn(CPUState * env, DisasContext *s)
{
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
-
+
insn = ldl_code(s->pc);
s->pc += 4;
-
+
cond = insn >> 28;
if (cond == 0xf){
/* Unconditional instructions. */
(insn & 0x00000090) != 0x90) ||
((insn & 0x0e000000) == (1 << 25))) {
int set_cc, logic_cc, shiftop;
-
+
op1 = (insn >> 21) & 0xf;
set_cc = (insn >> 20) & 1;
logic_cc = table_logic_cc[op1] & set_cc;
gen_movl_T1_reg(s, rn);
gen_op_addl_T0_T1();
}
- if (insn & (1 << 20))
+ if (insn & (1 << 20))
gen_op_logic_T0_cc();
gen_movl_reg_T0(s, rd);
} else {
/* 64 bit mul */
gen_movl_T0_reg(s, rs);
gen_movl_T1_reg(s, rm);
- if (insn & (1 << 22))
+ if (insn & (1 << 22))
gen_op_imull_T0_T1();
else
gen_op_mull_T0_T1();
gen_op_addq_lo_T0_T1(rn);
gen_op_addq_lo_T0_T1(rd);
}
- if (insn & (1 << 20))
+ if (insn & (1 << 20))
gen_op_logicq_cc();
gen_movl_reg_T0(s, rn);
gen_movl_reg_T1(s, rd);
} else {
/* SWP instruction */
rm = (insn) & 0xf;
-
+
gen_movl_T0_reg(s, rm);
gen_movl_T1_reg(s, rn);
if (insn & (1 << 22)) {
}
rn = (insn >> 16) & 0xf;
gen_movl_T1_reg(s, rn);
-
+
/* compute total size */
loaded_base = 0;
n = 0;
case 0xb:
{
int32_t offset;
-
+
/* branch (and link) */
val = (int32_t)s->pc;
if (insn & (1 << 24)) {
val = (uint32_t)s->pc + 2;
gen_op_movl_T1_im(val | 1);
gen_movl_reg_T1(s, 14);
-
+
val += offset << 1;
if (insn & (1 << 12)) {
/* bl */
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
basic block 'tb'. If search_pc is TRUE, also generate PC
information for each intermediate instruction. */
-static inline int gen_intermediate_code_internal(CPUState *env,
- TranslationBlock *tb,
+static inline int gen_intermediate_code_internal(CPUState *env,
+ TranslationBlock *tb,
int search_pc)
{
DisasContext dc1, *dc = &dc1;
int j, lj;
target_ulong pc_start;
uint32_t next_page_start;
-
+
/* generate intermediate code */
pc_start = tb->pc;
-
+
dc->tb = tb;
gen_opc_ptr = gen_opc_buf;
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
"???", "???", "???", "und", "???", "???", "???", "sys"
};
-void cpu_dump_state(CPUState *env, FILE *f,
+void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
{
cpu_fprintf(f, " ");
}
psr = cpsr_read(env);
- cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d %x\n",
- psr,
+ cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d %x\n",
+ psr,
psr & (1 << 31) ? 'N' : '-',
psr & (1 << 30) ? 'Z' : '-',
psr & (1 << 29) ? 'C' : '-',
psr & (1 << 28) ? 'V' : '-',
- psr & CPSR_T ? 'T' : 'A',
+ psr & CPSR_T ? 'T' : 'A',
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
for (i = 0; i < 16; i++) {
/*
* i386 virtual CPU header
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
#define NT_MASK 0x00004000
#define RF_MASK 0x00010000
#define VM_MASK 0x00020000
-#define AC_MASK 0x00040000
+#define AC_MASK 0x00040000
#define VIF_MASK 0x00080000
#define VIP_MASK 0x00100000
#define ID_MASK 0x00200000
int i32;
int64_t i64;
} fp_convert;
-
+
float_status sse_status;
uint32_t mxcsr;
XMMReg xmm_regs[CPU_NB_REGS];
uint32_t saved_esp;
int native_fp_regs; /* if true, the FPU state is in the native CPU regs */
#endif
-
+
/* exception/interrupt handling */
jmp_buf jmp_env;
int exception_index;
target_ulong exception_next_eip;
target_ulong dr[8]; /* debug registers */
uint32_t smbase;
- int interrupt_request;
+ int interrupt_request;
int user_mode_only; /* user mode only simulation */
CPU_COMMON
uint32_t cpuid_xlevel;
uint32_t cpuid_model[12];
uint32_t cpuid_ext2_features;
-
+
#ifdef USE_KQEMU
int kqemu_enabled;
int last_io_time;
/* this function must always be used to load data in the segment
cache: it synchronizes the hflags with the segment cache values */
-static inline void cpu_x86_load_seg_cache(CPUX86State *env,
+static inline void cpu_x86_load_seg_cache(CPUX86State *env,
int seg_reg, unsigned int selector,
target_ulong base,
- unsigned int limit,
+ unsigned int limit,
unsigned int flags)
{
SegmentCache *sc;
unsigned int new_hflags;
-
+
sc = &env->segs[seg_reg];
sc->selector = selector;
sc->base = base;
/* long mode */
env->hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
env->hflags &= ~(HF_ADDSEG_MASK);
- } else
+ } else
#endif
{
/* legacy / compatibility case */
>> (DESC_B_SHIFT - HF_SS32_SHIFT);
if (env->hflags & HF_CS64_MASK) {
/* zero base assumed for DS, ES and SS in long mode */
- } else if (!(env->cr[0] & CR0_PE_MASK) ||
+ } else if (!(env->cr[0] & CR0_PE_MASK) ||
(env->eflags & VM_MASK) ||
!(env->hflags & HF_CS32_MASK)) {
/* XXX: try to avoid this test. The problem comes from the
translate-i386.c. */
new_hflags |= HF_ADDSEG_MASK;
} else {
- new_hflags |= ((env->segs[R_DS].base |
+ new_hflags |= ((env->segs[R_DS].base |
env->segs[R_ES].base |
- env->segs[R_SS].base) != 0) <<
+ env->segs[R_SS].base) != 0) <<
HF_ADDSEG_SHIFT;
}
- env->hflags = (env->hflags &
+ env->hflags = (env->hflags &
~(HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags;
}
}
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
-int cpu_x86_signal_handler(int host_signum, void *pinfo,
+int cpu_x86_signal_handler(int host_signum, void *pinfo,
void *puc);
void cpu_x86_set_a20(CPUX86State *env, int a20_state);
/*
- * i386 execution defines
+ * i386 execution defines
*
* Copyright (c) 2003 Fabrice Bellard
*
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
+int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
int is_write, int is_user, int is_softmmu);
-void tlb_fill(target_ulong addr, int is_write, int is_user,
+void tlb_fill(target_ulong addr, int is_write, int is_user,
void *retaddr);
void __hidden cpu_lock(void);
void __hidden cpu_unlock(void);
-void do_interrupt(int intno, int is_int, int error_code,
+void do_interrupt(int intno, int is_int, int error_code,
target_ulong next_eip, int is_hw);
-void do_interrupt_user(int intno, int is_int, int error_code,
+void do_interrupt_user(int intno, int is_int, int error_code,
target_ulong next_eip);
-void raise_interrupt(int intno, int is_int, int error_code,
+void raise_interrupt(int intno, int is_int, int error_code,
int next_eip_addend);
void raise_exception_err(int exception_index, int error_code);
void raise_exception(int exception_index);
static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
{
CPU86_LDoubleU temp;
-
+
temp.d = f;
stq(ptr, temp.l.lower);
stw(ptr + 8, temp.l.upper);
{
CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
DF = 1 - (2 * ((eflags >> 10) & 1));
- env->eflags = (env->eflags & ~update_mask) |
+ env->eflags = (env->eflags & ~update_mask) |
(eflags & update_mask);
}
/*
* i386 helpers
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
/* modulo 17 table */
const uint8_t rclw_table[32] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7,
8, 9,10,11,12,13,14,15,
16, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9,10,11,12,13,14,
/* modulo 9 table */
const uint8_t rclb_table[32] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7,
8, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 0, 1, 2, 3, 4, 5,
+ 7, 8, 0, 1, 2, 3, 4, 5,
6, 7, 8, 0, 1, 2, 3, 4,
};
1.44269504088896340739L, /*l2e*/
3.32192809488736234781L, /*l2t*/
};
-
+
/* thread support */
spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
*e2_ptr = ldl_kernel(ptr + 4);
return 0;
}
-
+
static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2)
{
unsigned int limit;
static inline void load_seg_vm(int seg, int selector)
{
selector &= 0xffff;
- cpu_x86_load_seg_cache(env, seg, selector,
+ cpu_x86_load_seg_cache(env, seg, selector,
(selector << 4), 0xffff, 0);
}
-static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
+static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
uint32_t *esp_ptr, int dpl)
{
int type, index, shift;
-
+
#if 0
{
int i;
}
if (!(e2 & DESC_P_MASK))
raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
- cpu_x86_load_seg_cache(env, seg_reg, selector,
+ cpu_x86_load_seg_cache(env, seg_reg, selector,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
} else {
- if (seg_reg == R_SS || seg_reg == R_CS)
+ if (seg_reg == R_SS || seg_reg == R_CS)
raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
}
}
#define SWITCH_TSS_CALL 2
/* XXX: restore CPU state in registers (PowerPC case) */
-static void switch_tss(int tss_selector,
+static void switch_tss(int tss_selector,
uint32_t e1, uint32_t e2, int source,
uint32_t next_eip)
{
tss_limit_max = 43;
tss_limit = get_seg_limit(e1, e2);
tss_base = get_seg_base(e1, e2);
- if ((tss_selector & 4) != 0 ||
+ if ((tss_selector & 4) != 0 ||
tss_limit < tss_limit_max)
raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
new_segs[R_GS] = 0;
new_trap = 0;
}
-
+
/* NOTE: we must avoid memory exceptions during the task switch,
so we make dummy accesses before */
/* XXX: it can still fail in some cases, so a bigger hack is
v2 = ldub_kernel(env->tr.base + old_tss_limit_max);
stb_kernel(env->tr.base, v1);
stb_kernel(env->tr.base + old_tss_limit_max, v2);
-
+
/* clear busy bit (it is restartable) */
if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) {
target_ulong ptr;
old_eflags = compute_eflags();
if (source == SWITCH_TSS_IRET)
old_eflags &= ~NT_MASK;
-
+
/* save the current state in the old TSS */
if (type & 8) {
/* 32 bit */
for(i = 0; i < 4; i++)
stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector);
}
-
+
/* now if an exception occurs, it will occurs in the next task
context */
env->tr.base = tss_base;
env->tr.limit = tss_limit;
env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK;
-
+
if ((type & 8) && (env->cr[0] & CR0_PG_MASK)) {
cpu_x86_update_cr3(env, new_cr3);
}
-
+
/* load all registers without an exception, then reload them with
possible exception */
env->eip = new_eip;
- eflags_mask = TF_MASK | AC_MASK | ID_MASK |
+ eflags_mask = TF_MASK | AC_MASK | ID_MASK |
IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK;
if (!(type & 8))
eflags_mask &= 0xffff;
ESI = new_regs[6];
EDI = new_regs[7];
if (new_eflags & VM_MASK) {
- for(i = 0; i < 6; i++)
+ for(i = 0; i < 6; i++)
load_seg_vm(i, new_segs[i]);
/* in vm86, CPL is always 3 */
cpu_x86_set_cpl(env, 3);
for(i = 0; i < 6; i++)
cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0);
}
-
+
env->ldt.selector = new_ldt & ~4;
env->ldt.base = 0;
env->ldt.limit = 0;
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
load_seg_cache_raw_dt(&env->ldt, e1, e2);
}
-
+
/* load the segments */
if (!(new_eflags & VM_MASK)) {
tss_load_seg(R_CS, new_segs[R_CS]);
tss_load_seg(R_FS, new_segs[R_FS]);
tss_load_seg(R_GS, new_segs[R_GS]);
}
-
+
/* check that EIP is in the CS segment limits */
if (new_eip > env->segs[R_CS].limit) {
/* XXX: different exception if CALL ? */
static inline void check_io(int addr, int size)
{
int io_offset, val, mask;
-
+
/* TSS must be a valid 32 bit one */
if (!(env->tr.flags & DESC_P_MASK) ||
((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
PUSHW(ssp, esp, sp_mask, error_code);
}
}
-
+
if (new_stack) {
if (env->eflags & VM_MASK) {
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0);
}
ss = (ss & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_SS, ss,
+ cpu_x86_load_seg_cache(env, R_SS, ss,
ssp, get_seg_limit(ss_e1, ss_e2), ss_e2);
}
SET_ESP(esp, sp_mask);
selector = (selector & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_CS, selector,
+ cpu_x86_load_seg_cache(env, R_CS, selector,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
static inline target_ulong get_rsp_from_tss(int level)
{
int index;
-
+
#if 0
- printf("TR: base=" TARGET_FMT_lx " limit=%x\n",
+ printf("TR: base=" TARGET_FMT_lx " limit=%x\n",
env->tr.base, env->tr.limit);
#endif
if (has_error_code) {
PUSHQ(esp, error_code);
}
-
+
if (new_stack) {
ss = 0 | dpl;
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
ESP = esp;
selector = (selector & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_CS, selector,
+ cpu_x86_load_seg_cache(env, R_CS, selector,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
ECX = env->eip + next_eip_addend;
env->regs[11] = compute_eflags();
-
+
code64 = env->hflags & HF_CS64_MASK;
cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_P_MASK |
DESC_S_MASK |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
+ cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
env->eip = env->lstar;
else
env->eip = env->cstar;
- } else
+ } else
#endif
{
ECX = (uint32_t)(env->eip + next_eip_addend);
-
+
cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
+ cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
if (dflag == 2) {
- cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
+ DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
DESC_L_MASK);
env->eip = ECX;
} else {
- cpu_x86_load_seg_cache(env, R_CS, selector | 3,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, selector | 3,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
env->eip = (uint32_t)ECX;
}
- cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+ cpu_x86_load_seg_cache(env, R_SS, selector + 8,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_W_MASK | DESC_A_MASK);
- load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK |
+ load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK |
IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK);
cpu_x86_set_cpl(env, 3);
- } else
+ } else
#endif
{
- cpu_x86_load_seg_cache(env, R_CS, selector | 3,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, selector | 3,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
env->eip = (uint32_t)ECX;
- cpu_x86_load_seg_cache(env, R_SS, selector + 8,
+ cpu_x86_load_seg_cache(env, R_SS, selector + 8,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
PUSHW(ssp, esp, 0xffff, compute_eflags());
PUSHW(ssp, esp, 0xffff, old_cs);
PUSHW(ssp, esp, 0xffff, old_eip);
-
+
/* update processor state */
ESP = (ESP & ~0xffff) | (esp & 0xffff);
env->eip = offset;
}
/* fake user mode interrupt */
-void do_interrupt_user(int intno, int is_int, int error_code,
+void do_interrupt_user(int intno, int is_int, int error_code,
target_ulong next_eip)
{
SegmentCache *dt;
dt = &env->idt;
ptr = dt->base + (intno * 8);
e2 = ldl_kernel(ptr + 4);
-
+
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK;
/* check privledge if software int */
/*
* Begin execution of an interruption. is_int is TRUE if coming from
* the int instruction. next_eip is the EIP value AFTER the interrupt
- * instruction. It is only relevant if is_int is TRUE.
+ * instruction. It is only relevant if is_int is TRUE.
*/
-void do_interrupt(int intno, int is_int, int error_code,
+void do_interrupt(int intno, int is_int, int error_code,
target_ulong next_eip, int is_hw)
{
if (loglevel & CPU_LOG_INT) {
* Signal an interruption. It is executed in the main CPU loop.
* is_int is TRUE if coming from the int instruction. next_eip is the
* EIP value AFTER the interrupt instruction. It is only relevant if
- * is_int is TRUE.
+ * is_int is TRUE.
*/
-void raise_interrupt(int intno, int is_int, int error_code,
+void raise_interrupt(int intno, int is_int, int error_code,
int next_eip_addend)
{
env->exception_index = intno;
/* SMM support */
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
void do_smm_enter(void)
{
cpu_smm_update(env);
sm_state = env->smbase + 0x8000;
-
+
#ifdef TARGET_X86_64
for(i = 0; i < 6; i++) {
dt = &env->segs[i];
stq_phys(sm_state + 0x7e78, env->ldt.base);
stl_phys(sm_state + 0x7e74, env->ldt.limit);
stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);
-
+
stq_phys(sm_state + 0x7e88, env->idt.base);
stl_phys(sm_state + 0x7e84, env->idt.limit);
stq_phys(sm_state + 0x7e98, env->tr.base);
stl_phys(sm_state + 0x7e94, env->tr.limit);
stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);
-
+
stq_phys(sm_state + 0x7ed0, env->efer);
stq_phys(sm_state + 0x7ff8, EAX);
stq_phys(sm_state + 0x7fd0, EBP);
stq_phys(sm_state + 0x7fc8, ESI);
stq_phys(sm_state + 0x7fc0, EDI);
- for(i = 8; i < 16; i++)
+ for(i = 8; i < 16; i++)
stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]);
stq_phys(sm_state + 0x7f78, env->eip);
stl_phys(sm_state + 0x7f70, compute_eflags());
stl_phys(sm_state + 0x7fd0, EAX);
stl_phys(sm_state + 0x7fcc, env->dr[6]);
stl_phys(sm_state + 0x7fc8, env->dr[7]);
-
+
stl_phys(sm_state + 0x7fc4, env->tr.selector);
stl_phys(sm_state + 0x7f64, env->tr.base);
stl_phys(sm_state + 0x7f60, env->tr.limit);
stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);
-
+
stl_phys(sm_state + 0x7fc0, env->ldt.selector);
stl_phys(sm_state + 0x7f80, env->ldt.base);
stl_phys(sm_state + 0x7f7c, env->ldt.limit);
stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);
-
+
stl_phys(sm_state + 0x7f74, env->gdt.base);
stl_phys(sm_state + 0x7f70, env->gdt.limit);
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0);
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0);
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0);
-
- cpu_x86_update_cr0(env,
+
+ cpu_x86_update_cr0(env,
env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK));
cpu_x86_update_cr4(env, 0);
env->dr[7] = 0x00000400;
for(i = 0; i < 6; i++) {
offset = 0x7e00 + i * 16;
- cpu_x86_load_seg_cache(env, i,
+ cpu_x86_load_seg_cache(env, i,
lduw_phys(sm_state + offset),
ldq_phys(sm_state + offset + 8),
ldl_phys(sm_state + offset + 4),
env->ldt.base = ldq_phys(sm_state + 0x7e78);
env->ldt.limit = ldl_phys(sm_state + 0x7e74);
env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8;
-
+
env->idt.base = ldq_phys(sm_state + 0x7e88);
env->idt.limit = ldl_phys(sm_state + 0x7e84);
env->tr.base = ldq_phys(sm_state + 0x7e98);
env->tr.limit = ldl_phys(sm_state + 0x7e94);
env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
-
+
EAX = ldq_phys(sm_state + 0x7ff8);
ECX = ldq_phys(sm_state + 0x7ff0);
EDX = ldq_phys(sm_state + 0x7fe8);
EBP = ldq_phys(sm_state + 0x7fd0);
ESI = ldq_phys(sm_state + 0x7fc8);
EDI = ldq_phys(sm_state + 0x7fc0);
- for(i = 8; i < 16; i++)
+ for(i = 8; i < 16; i++)
env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8);
env->eip = ldq_phys(sm_state + 0x7f78);
- load_eflags(ldl_phys(sm_state + 0x7f70),
+ load_eflags(ldl_phys(sm_state + 0x7f70),
~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
env->dr[6] = ldl_phys(sm_state + 0x7f68);
env->dr[7] = ldl_phys(sm_state + 0x7f60);
#else
cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7ffc));
cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7ff8));
- load_eflags(ldl_phys(sm_state + 0x7ff4),
+ load_eflags(ldl_phys(sm_state + 0x7ff4),
~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
env->eip = ldl_phys(sm_state + 0x7ff0);
EDI = ldl_phys(sm_state + 0x7fec);
EAX = ldl_phys(sm_state + 0x7fd0);
env->dr[6] = ldl_phys(sm_state + 0x7fcc);
env->dr[7] = ldl_phys(sm_state + 0x7fc8);
-
+
env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff;
env->tr.base = ldl_phys(sm_state + 0x7f64);
env->tr.limit = ldl_phys(sm_state + 0x7f60);
env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8;
-
+
env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff;
env->ldt.base = ldl_phys(sm_state + 0x7f80);
env->ldt.limit = ldl_phys(sm_state + 0x7f7c);
env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8;
-
+
env->gdt.base = ldl_phys(sm_state + 0x7f74);
env->gdt.limit = ldl_phys(sm_state + 0x7f70);
offset = 0x7f84 + i * 12;
else
offset = 0x7f2c + (i - 3) * 12;
- cpu_x86_load_seg_cache(env, i,
+ cpu_x86_load_seg_cache(env, i,
ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff,
ldl_phys(sm_state + offset + 8),
ldl_phys(sm_state + offset + 4),
{
unsigned int den, r;
uint64_t num, q;
-
+
num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
den = T0;
if (den == 0) {
{
int den, r;
int64_t num, q;
-
+
num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
den = T0;
if (den == 0) {
{
uint32_t index;
index = (uint32_t)EAX;
-
+
/* test if maximum index reached */
if (index & 0x80000000) {
- if (index > env->cpuid_xlevel)
+ if (index > env->cpuid_xlevel)
index = env->cpuid_level;
} else {
- if (index > env->cpuid_level)
+ if (index > env->cpuid_level)
index = env->cpuid_level;
}
-
+
switch(index) {
case 0:
EAX = env->cpuid_level;
uint32_t e1, e2;
int index, entry_limit;
target_ulong ptr;
-
+
selector = T0 & 0xffff;
if ((selector & 0xfffc) == 0) {
/* XXX: NULL selector case: invalid LDT */
if (env->hflags & HF_LMA_MASK)
entry_limit = 15;
else
-#endif
+#endif
entry_limit = 7;
if ((index + entry_limit) > dt->limit)
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
uint32_t e1, e2;
int index, type, entry_limit;
target_ulong ptr;
-
+
selector = T0 & 0xffff;
if ((selector & 0xfffc) == 0) {
/* NULL selector case: invalid TR */
if (env->hflags & HF_LMA_MASK)
entry_limit = 15;
else
-#endif
+#endif
entry_limit = 7;
if ((index + entry_limit) > dt->limit)
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
e1 = ldl_kernel(ptr);
e2 = ldl_kernel(ptr + 4);
type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
- if ((e2 & DESC_S_MASK) ||
+ if ((e2 & DESC_S_MASK) ||
(type != 1 && type != 9))
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
if (!(e2 & DESC_P_MASK))
e3 = ldl_kernel(ptr + 8);
load_seg_cache_raw_dt(&env->tr, e1, e2);
env->tr.base |= (target_ulong)e3 << 32;
- } else
+ } else
#endif
{
load_seg_cache_raw_dt(&env->tr, e1, e2);
raise_exception_err(EXCP0D_GPF, 0);
cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
} else {
-
+
if (selector & 0x4)
dt = &env->ldt;
else
ptr = dt->base + index;
e1 = ldl_kernel(ptr);
e2 = ldl_kernel(ptr + 4);
-
+
if (!(e2 & DESC_S_MASK))
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
rpl = selector & 3;
/* must be readable segment */
if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK)
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
-
+
if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
/* if not conforming code, test rights */
- if (dpl < cpl || dpl < rpl)
+ if (dpl < cpl || dpl < rpl)
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
}
}
stl_kernel(ptr + 4, e2);
}
- cpu_x86_load_seg_cache(env, seg_reg, selector,
+ cpu_x86_load_seg_cache(env, seg_reg, selector,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
#if 0
- fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n",
+ fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n",
selector, (unsigned long)sc->base, sc->limit, sc->flags);
#endif
}
int new_cs, gate_cs, type;
uint32_t e1, e2, cpl, dpl, rpl, limit;
target_ulong new_eip, next_eip;
-
+
new_cs = T0;
new_eip = T1;
if ((new_cs & 0xfffc) == 0)
if (!(e2 & DESC_P_MASK))
raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
limit = get_seg_limit(e1, e2);
- if (new_eip > limit &&
+ if (new_eip > limit &&
!(env->hflags & HF_LMA_MASK) && !(e2 & DESC_L_MASK))
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
/* must be code segment */
- if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) !=
+ if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) !=
(DESC_S_MASK | DESC_CS_MASK)))
raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
- if (((e2 & DESC_C_MASK) && (dpl > cpl)) ||
+ if (((e2 & DESC_C_MASK) && (dpl > cpl)) ||
(!(e2 & DESC_C_MASK) && (dpl != cpl)))
raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
if (!(e2 & DESC_P_MASK))
uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask;
uint32_t val, limit, old_sp_mask;
target_ulong ssp, old_ssp, next_eip, new_eip;
-
+
new_cs = T0;
new_eip = T1;
next_eip = env->eip + next_eip_addend;
/* from this point, not restartable */
ESP = rsp;
cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
- get_seg_base(e1, e2),
+ get_seg_base(e1, e2),
get_seg_limit(e1, e2), e2);
EIP = new_eip;
- } else
+ } else
#endif
{
sp = ESP;
PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);
PUSHW(ssp, sp, sp_mask, next_eip);
}
-
+
limit = get_seg_limit(e1, e2);
if (new_eip > limit)
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
get_ss_esp_from_tss(&ss, &sp, dpl);
#ifdef DEBUG_PCALL
if (loglevel & CPU_LOG_PCALL)
- fprintf(logfile, "new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n",
+ fprintf(logfile, "new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n",
ss, sp, param_count, ESP);
#endif
if ((ss & 0xfffc) == 0)
raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
if (!(ss_e2 & DESC_P_MASK))
raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
-
+
// push_size = ((param_count * 2) + 8) << shift;
old_sp_mask = get_sp_mask(env->segs[R_SS].flags);
old_ssp = env->segs[R_SS].base;
-
+
sp_mask = get_sp_mask(ss_e2);
ssp = get_seg_base(ss_e1, ss_e2);
if (shift) {
if (new_stack) {
ss = (ss & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_SS, ss,
+ cpu_x86_load_seg_cache(env, R_SS, ss,
ssp,
get_seg_limit(ss_e1, ss_e2),
ss_e2);
}
selector = (selector & ~3) | dpl;
- cpu_x86_load_seg_cache(env, R_CS, selector,
+ cpu_x86_load_seg_cache(env, R_CS, selector,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
/* XXX: on x86_64, we do not want to nullify FS and GS because
they may still contain a valid base. I would be interested to
know how a real x86_64 CPU behaves */
- if ((seg_reg == R_FS || seg_reg == R_GS) &&
+ if ((seg_reg == R_FS || seg_reg == R_GS) &&
(env->segs[seg_reg].selector & 0xfffc) == 0)
return;
uint32_t e1, e2, ss_e1, ss_e2;
int cpl, dpl, rpl, eflags_mask, iopl;
target_ulong ssp, sp, new_eip, new_esp, sp_mask;
-
+
#ifdef TARGET_X86_64
if (shift == 2)
sp_mask = -1;
!(e2 & DESC_CS_MASK))
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
cpl = env->hflags & HF_CPL_MASK;
- rpl = new_cs & 3;
+ rpl = new_cs & 3;
if (rpl < cpl)
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
}
if (!(e2 & DESC_P_MASK))
raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
-
+
sp += addend;
- if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) ||
+ if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) ||
((env->hflags & HF_CS64_MASK) && !is_iret))) {
/* return to same priledge level */
- cpu_x86_load_seg_cache(env, R_CS, new_cs,
+ cpu_x86_load_seg_cache(env, R_CS, new_cs,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
/* NULL ss is allowed in long mode if cpl != 3*/
/* XXX: test CS64 ? */
if ((env->hflags & HF_LMA_MASK) && rpl != 3) {
- cpu_x86_load_seg_cache(env, R_SS, new_ss,
+ cpu_x86_load_seg_cache(env, R_SS, new_ss,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (rpl << DESC_DPL_SHIFT) |
DESC_W_MASK | DESC_A_MASK);
ss_e2 = DESC_B_MASK; /* XXX: should not be needed ? */
- } else
+ } else
#endif
{
raise_exception_err(EXCP0D_GPF, 0);
raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
if (!(ss_e2 & DESC_P_MASK))
raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);
- cpu_x86_load_seg_cache(env, R_SS, new_ss,
+ cpu_x86_load_seg_cache(env, R_SS, new_ss,
get_seg_base(ss_e1, ss_e2),
get_seg_limit(ss_e1, ss_e2),
ss_e2);
}
- cpu_x86_load_seg_cache(env, R_CS, new_cs,
+ cpu_x86_load_seg_cache(env, R_CS, new_cs,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
POPL(ssp, sp, sp_mask, new_ds);
POPL(ssp, sp, sp_mask, new_fs);
POPL(ssp, sp, sp_mask, new_gs);
-
+
/* modify processor state */
- load_eflags(new_eflags, TF_MASK | AC_MASK | ID_MASK |
+ load_eflags(new_eflags, TF_MASK | AC_MASK | ID_MASK |
IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | VIP_MASK);
load_seg_vm(R_CS, new_cs & 0xffff);
cpu_x86_set_cpl(env, 3);
{
int tss_selector, type;
uint32_t e1, e2;
-
+
/* specific case for TSS */
if (env->eflags & NT_MASK) {
#ifdef TARGET_X86_64
}
env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK);
cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (env->sysenter_cs + 8) & 0xfffc,
+ cpu_x86_load_seg_cache(env, R_SS, (env->sysenter_cs + 8) & 0xfffc,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
raise_exception_err(EXCP0D_GPF, 0);
}
cpu_x86_set_cpl(env, 3);
- cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3,
- 0, 0xffffffff,
+ cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3,
+ 0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3,
+ cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
void helper_movl_crN_T0(int reg)
{
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
switch(reg) {
case 0:
cpu_x86_update_cr0(env, T0);
EDX = (uint32_t)(val >> 32);
}
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
void helper_wrmsr(void)
{
}
update_mask |= MSR_EFER_FFXSR;
if (env->cpuid_ext2_features & CPUID_EXT2_NX)
update_mask |= MSR_EFER_NXE;
- env->efer = (env->efer & ~update_mask) |
+ env->efer = (env->efer & ~update_mask) |
(val & update_mask);
}
break;
#endif
default:
/* XXX: exception ? */
- break;
+ break;
}
}
default:
/* XXX: exception ? */
val = 0;
- break;
+ break;
}
EAX = (uint32_t)(val);
EDX = (uint32_t)(val >> 32);
CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
{
- if (b == 0.0)
+ if (b == 0.0)
fpu_set_exception(FPUS_ZE);
return a / b;
}
{
if (env->cr[0] & CR0_NE_MASK) {
raise_exception(EXCP10_COPR);
- }
-#if !defined(CONFIG_USER_ONLY)
+ }
+#if !defined(CONFIG_USER_ONLY)
else {
cpu_set_ferr(env);
}
void helper_fyl2x(void)
{
CPU86_LDouble fptemp;
-
+
fptemp = ST0;
if (fptemp>0.0){
fptemp = log(fptemp)/log(2.0); /* log2(ST) */
ST1 *= fptemp;
fpop();
- } else {
+ } else {
env->fpus &= (~0x4700);
env->fpus |= 0x400;
}
CPU86_LDoubleU fpsrcop1, fptemp1;
int expdif;
int q;
-
+
fpsrcop = ST0;
fptemp = ST1;
fpsrcop1.d = fpsrcop;
fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
ST1 *= fptemp;
fpop();
- } else {
+ } else {
env->fpus &= (~0x4700);
env->fpus |= 0x400;
}
CPU86_LDouble fptemp;
fptemp = ST0;
- if (fptemp<0.0) {
+ if (fptemp<0.0) {
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
env->fpus |= 0x400;
}
void helper_fscale(void)
{
- ST0 = ldexp (ST0, (int)(ST1));
+ ST0 = ldexp (ST0, (int)(ST1));
}
void helper_fsin(void)
helper_fstt(tmp, addr);
addr += 16;
}
-
+
if (env->cr[4] & CR4_OSFXSR_MASK) {
/* XXX: finish it */
stl(ptr + 0x18, env->mxcsr); /* mxcsr */
b0 = b;
b1 = b >> 32;
-
+
v = (uint64_t)a0 * (uint64_t)b0;
*plow = v;
*phigh = 0;
v = (uint64_t)a0 * (uint64_t)b1;
add128(plow, phigh, v << 32, v >> 32);
-
+
v = (uint64_t)a1 * (uint64_t)b0;
add128(plow, phigh, v << 32, v >> 32);
-
+
v = (uint64_t)a1 * (uint64_t)b1;
*phigh += v;
#ifdef DEBUG_MULDIV
#endif
}
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
#define MMUSUFFIX _mmu
#define GETPC() (__builtin_return_address(0))
/*
* i386 helpers (without register variable usage)
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
ldt.seg_not_present = 0;
ldt.useable = 1;
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
-
+
asm volatile ("movl %0, %%fs" : : "r" ((1 << 3) | 7));
}
#endif
env->ldt.flags = DESC_P_MASK;
env->tr.limit = 0xffff;
env->tr.flags = DESC_P_MASK;
-
- cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, 0);
+
+ cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, 0);
cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, 0);
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, 0);
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, 0);
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, 0);
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, 0);
-
+
env->eip = 0xfff0;
env->regs[R_EDX] = 0x600; /* indicate P6 processor */
-
+
env->eflags = 0x2;
-
+
/* FPU init */
for(i = 0;i < 8; i++)
env->fptags[i] = 1;
"SARQ",
};
-void cpu_dump_state(CPUState *env, FILE *f,
+void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
{
eflags = env->eflags;
#ifdef TARGET_X86_64
if (env->hflags & HF_CS64_MASK) {
- cpu_fprintf(f,
+ cpu_fprintf(f,
"RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
"RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
"R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
"R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
"RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
- env->regs[R_EAX],
- env->regs[R_EBX],
- env->regs[R_ECX],
- env->regs[R_EDX],
- env->regs[R_ESI],
- env->regs[R_EDI],
- env->regs[R_EBP],
- env->regs[R_ESP],
- env->regs[8],
- env->regs[9],
- env->regs[10],
- env->regs[11],
- env->regs[12],
- env->regs[13],
- env->regs[14],
- env->regs[15],
+ env->regs[R_EAX],
+ env->regs[R_EBX],
+ env->regs[R_ECX],
+ env->regs[R_EDX],
+ env->regs[R_ESI],
+ env->regs[R_EDI],
+ env->regs[R_EBP],
+ env->regs[R_ESP],
+ env->regs[8],
+ env->regs[9],
+ env->regs[10],
+ env->regs[11],
+ env->regs[12],
+ env->regs[13],
+ env->regs[14],
+ env->regs[15],
env->eip, eflags,
eflags & DF_MASK ? 'D' : '-',
eflags & CC_O ? 'O' : '-',
eflags & CC_A ? 'A' : '-',
eflags & CC_P ? 'P' : '-',
eflags & CC_C ? 'C' : '-',
- env->hflags & HF_CPL_MASK,
+ env->hflags & HF_CPL_MASK,
(env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
(env->a20_mask >> 20) & 1,
(env->hflags >> HF_SMM_SHIFT) & 1,
(env->hflags >> HF_HALTED_SHIFT) & 1);
- } else
+ } else
#endif
{
cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
"ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
"EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
- (uint32_t)env->regs[R_EAX],
- (uint32_t)env->regs[R_EBX],
- (uint32_t)env->regs[R_ECX],
- (uint32_t)env->regs[R_EDX],
- (uint32_t)env->regs[R_ESI],
- (uint32_t)env->regs[R_EDI],
- (uint32_t)env->regs[R_EBP],
- (uint32_t)env->regs[R_ESP],
+ (uint32_t)env->regs[R_EAX],
+ (uint32_t)env->regs[R_EBX],
+ (uint32_t)env->regs[R_ECX],
+ (uint32_t)env->regs[R_EDX],
+ (uint32_t)env->regs[R_ESI],
+ (uint32_t)env->regs[R_EDI],
+ (uint32_t)env->regs[R_EBP],
+ (uint32_t)env->regs[R_ESP],
(uint32_t)env->eip, eflags,
eflags & DF_MASK ? 'D' : '-',
eflags & CC_O ? 'O' : '-',
eflags & CC_A ? 'A' : '-',
eflags & CC_P ? 'P' : '-',
eflags & CC_C ? 'C' : '-',
- env->hflags & HF_CPL_MASK,
+ env->hflags & HF_CPL_MASK,
(env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
(env->a20_mask >> 20) & 1,
(env->hflags >> HF_SMM_SHIFT) & 1,
cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
env->idt.base, env->idt.limit);
cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
- (uint32_t)env->cr[0],
- env->cr[2],
- env->cr[3],
+ (uint32_t)env->cr[0],
+ env->cr[2],
+ env->cr[3],
(uint32_t)env->cr[4]);
} else
#endif
cpu_fprintf(f, "IDT= %08x %08x\n",
(uint32_t)env->idt.base, env->idt.limit);
cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
- (uint32_t)env->cr[0],
- (uint32_t)env->cr[2],
- (uint32_t)env->cr[3],
+ (uint32_t)env->cr[0],
+ (uint32_t)env->cr[2],
+ (uint32_t)env->cr[3],
(uint32_t)env->cr[4]);
}
if (flags & X86_DUMP_CCOP) {
#ifdef TARGET_X86_64
if (env->hflags & HF_CS64_MASK) {
cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
- env->cc_src, env->cc_dst,
+ env->cc_src, env->cc_dst,
cc_op_name);
- } else
+ } else
#endif
{
cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
- (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
+ (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
cc_op_name);
}
}
else
cpu_fprintf(f, " ");
}
- if (env->hflags & HF_CS64_MASK)
+ if (env->hflags & HF_CS64_MASK)
nb = 16;
else
nb = 8;
for(i=0;i<nb;i++) {
cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
- i,
+ i,
env->xmm_regs[i].XMM_L(3),
env->xmm_regs[i].XMM_L(2),
env->xmm_regs[i].XMM_L(1),
}
#endif
env->cr[0] = new_cr0 | CR0_ET_MASK;
-
+
/* update PE flag in hidden flags */
pe_state = (env->cr[0] & CR0_PE_MASK);
env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
tlb_flush_page(env, addr);
}
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
+int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
int is_write, int is_user, int is_softmmu)
{
/* user mode only emulation */
#define PHYS_ADDR_MASK 0xfffff000
/* return value:
- -1 = cannot handle fault
- 0 = nothing more to do
+ -1 = cannot handle fault
+ 0 = nothing more to do
1 = generate PF fault
2 = soft MMU activation required for this block
*/
-int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
+int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
int is_write1, int is_user, int is_softmmu)
{
uint64_t ptep, pte;
int error_code, is_dirty, prot, page_size, ret, is_write;
unsigned long paddr, page_offset;
target_ulong vaddr, virt_addr;
-
+
#if defined(DEBUG_MMU)
- printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
+ printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
addr, is_write1, is_user, env->eip);
#endif
is_write = is_write1 & 1;
-
+
if (!(env->cr[0] & CR0_PG_MASK)) {
pte = addr;
virt_addr = addr & TARGET_PAGE_MASK;
env->exception_index = EXCP0D_GPF;
return 1;
}
-
- pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
+
+ pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
env->a20_mask;
pml4e = ldq_phys(pml4e_addr);
if (!(pml4e & PG_PRESENT_MASK)) {
stl_phys_notdirty(pml4e_addr, pml4e);
}
ptep = pml4e ^ PG_NX_MASK;
- pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
+ pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
env->a20_mask;
pdpe = ldq_phys(pdpe_addr);
if (!(pdpe & PG_PRESENT_MASK)) {
#endif
{
/* XXX: load them when cr3 is loaded ? */
- pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) &
+ pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) &
env->a20_mask;
pdpe = ldq_phys(pdpe_addr);
if (!(pdpe & PG_PRESENT_MASK)) {
if (is_write && !(ptep & PG_RW_MASK))
goto do_fault_protect;
} else {
- if ((env->cr[0] & CR0_WP_MASK) &&
- is_write && !(ptep & PG_RW_MASK))
+ if ((env->cr[0] & CR0_WP_MASK) &&
+ is_write && !(ptep & PG_RW_MASK))
goto do_fault_protect;
}
is_dirty = is_write && !(pde & PG_DIRTY_MASK);
stl_phys_notdirty(pde_addr, pde);
}
/* align to page_size */
- pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
+ pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
virt_addr = addr & ~(page_size - 1);
} else {
/* 4 KB page */
ptep &= pte ^ PG_NX_MASK;
ptep ^= PG_NX_MASK;
if ((ptep & PG_NX_MASK) && is_write1 == 2)
- goto do_fault_protect;
+ goto do_fault_protect;
if (is_user) {
if (!(ptep & PG_USER_MASK))
goto do_fault_protect;
goto do_fault_protect;
} else {
if ((env->cr[0] & CR0_WP_MASK) &&
- is_write && !(ptep & PG_RW_MASK))
+ is_write && !(ptep & PG_RW_MASK))
goto do_fault_protect;
}
is_dirty = is_write && !(pte & PG_DIRTY_MASK);
uint32_t pde;
/* page directory entry */
- pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) &
+ pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) &
env->a20_mask;
pde = ldl_phys(pde_addr);
if (!(pde & PG_PRESENT_MASK)) {
if (is_write && !(pde & PG_RW_MASK))
goto do_fault_protect;
} else {
- if ((env->cr[0] & CR0_WP_MASK) &&
- is_write && !(pde & PG_RW_MASK))
+ if ((env->cr[0] & CR0_WP_MASK) &&
+ is_write && !(pde & PG_RW_MASK))
goto do_fault_protect;
}
is_dirty = is_write && !(pde & PG_DIRTY_MASK);
pde |= PG_DIRTY_MASK;
stl_phys_notdirty(pde_addr, pde);
}
-
+
pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
ptep = pte;
virt_addr = addr & ~(page_size - 1);
}
/* page directory entry */
- pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
+ pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
env->a20_mask;
pte = ldl_phys(pte_addr);
if (!(pte & PG_PRESENT_MASK)) {
goto do_fault_protect;
} else {
if ((env->cr[0] & CR0_WP_MASK) &&
- is_write && !(ptep & PG_RW_MASK))
+ is_write && !(ptep & PG_RW_MASK))
goto do_fault_protect;
}
is_dirty = is_write && !(pte & PG_DIRTY_MASK);
page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
paddr = (pte & TARGET_PAGE_MASK) + page_offset;
vaddr = virt_addr + page_offset;
-
+
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
return ret;
do_fault_protect:
error_code |= (is_write << PG_ERROR_W_BIT);
if (is_user)
error_code |= PG_ERROR_U_MASK;
- if (is_write1 == 2 &&
- (env->efer & MSR_EFER_NXE) &&
+ if (is_write1 == 2 &&
+ (env->efer & MSR_EFER_NXE) &&
(env->cr[4] & CR4_PAE_MASK))
error_code |= PG_ERROR_I_D_MASK;
env->error_code = error_code;
sext = (int64_t)addr >> 47;
if (sext != 0 && sext != -1)
return -1;
-
- pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
+
+ pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
env->a20_mask;
pml4e = ldl_phys(pml4e_addr);
if (!(pml4e & PG_PRESENT_MASK))
return -1;
-
- pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
+
+ pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
env->a20_mask;
pdpe = ldl_phys(pdpe_addr);
if (!(pdpe & PG_PRESENT_MASK))
return -1;
- } else
+ } else
#endif
{
- pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) &
+ pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) &
env->a20_mask;
pdpe = ldl_phys(pdpe_addr);
if (!(pdpe & PG_PRESENT_MASK))
/* page directory entry */
pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & env->a20_mask;
pde = ldl_phys(pde_addr);
- if (!(pde & PG_PRESENT_MASK))
+ if (!(pde & PG_PRESENT_MASK))
return -1;
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
pte = pde & ~0x003ff000; /* align to 4MB */
{
int fptag, i, j;
struct fpstate fp1, *fp = &fp1;
-
+
fp->fpuc = env->fpuc;
fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
fptag = 0;
asm volatile ("frstor %0" : "=m" (*fp));
env->native_fp_regs = 1;
}
-
+
void save_native_fp_state(CPUState *env)
{
int fptag, i, j;
/*
* i386 micro operations
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
__p.l.v1 = PARAM1;\
__p.l.v0 = PARAM2;\
__p.q;\
-})
+})
void OPPROTO op_movq_T0_im64(void)
{
{
int selector;
SegmentCache *sc;
-
+
selector = T0 & 0xffff;
/* env->segs[] access */
sc = (SegmentCache *)((char *)env + PARAM1);
}
FORCE_RET();
}
-
+
void OPPROTO op_arpl_update(void)
{
int eflags;
eflags = cc_table[CC_OP].compute_all();
CC_SRC = (eflags & ~CC_Z) | T1;
}
-
+
/* T0: segment, T1:eip */
void OPPROTO op_ljmp_protected_T0_T1(void)
{
helper_movl_crN_T0(PARAM1);
}
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
void OPPROTO op_movtl_T0_cr8(void)
{
T0 = cpu_get_apic_tpr(env);
[CC_OP_SUBB] = { compute_all_subb, compute_c_subb },
[CC_OP_SUBW] = { compute_all_subw, compute_c_subw },
[CC_OP_SUBL] = { compute_all_subl, compute_c_subl },
-
+
[CC_OP_SBBB] = { compute_all_sbbb, compute_c_sbbb },
[CC_OP_SBBW] = { compute_all_sbbw, compute_c_sbbw },
[CC_OP_SBBL] = { compute_all_sbbl, compute_c_sbbl },
-
+
[CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb },
[CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw },
[CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl },
-
+
[CC_OP_INCB] = { compute_all_incb, compute_c_incl },
[CC_OP_INCW] = { compute_all_incw, compute_c_incl },
[CC_OP_INCL] = { compute_all_incl, compute_c_incl },
-
+
[CC_OP_DECB] = { compute_all_decb, compute_c_incl },
[CC_OP_DECW] = { compute_all_decw, compute_c_incl },
[CC_OP_DECL] = { compute_all_decl, compute_c_incl },
-
+
[CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb },
[CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw },
[CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
[CC_OP_ADCQ] = { compute_all_adcq, compute_c_adcq },
[CC_OP_SUBQ] = { compute_all_subq, compute_c_subq },
-
+
[CC_OP_SBBQ] = { compute_all_sbbq, compute_c_sbbq },
-
+
[CC_OP_LOGICQ] = { compute_all_logicq, compute_c_logicq },
-
+
[CC_OP_INCQ] = { compute_all_incq, compute_c_incl },
[CC_OP_DECQ] = { compute_all_decq, compute_c_incl },
/*
* i386 micro operations (templates for various register related
* operations)
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
/*
* MMX/SSE/SSE2/PNI support
- *
+ *
* Copyright (c) 2005 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
{
Reg *d = (Reg *)((char *)env + PARAM1);
int pos = PARAM2;
-
+
d->W(pos) = T0;
}
{
Reg *s = (Reg *)((char *)env + PARAM1);
int pos = PARAM2;
-
+
T0 = s->W(pos);
}
/*
* i386 micro operations (included several times to generate
* different operand sizes)
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
zf = ((DATA_TYPE)CC_DST == 0) << 6;
sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
/* of is defined if shift count == 1 */
- of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
+ of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
return cf | pf | af | zf | sf | of;
}
{
int count;
target_long res;
-
+
res = T0 & DATA_MASK;
if (res != 0) {
count = 0;
/*
* i386 micro operations (included several times to generate
* different operand sizes)
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
/* gcc 3.2 workaround. This is really a bug in gcc. */
asm volatile("" : : "r" (T0));
#endif
- CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
(T0 & CC_C);
CC_OP = CC_OP_EFLAGS;
}
asm volatile("" : : "r" (T0));
#endif
CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
((T0 >> (DATA_BITS - 1)) & CC_C);
CC_OP = CC_OP_EFLAGS;
}
glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
((src >> (DATA_BITS - count)) & CC_C);
CC_OP = CC_OP_EFLAGS;
}
glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
((src >> (count - 1)) & CC_C);
CC_OP = CC_OP_EFLAGS;
}
/*
* i386 on i386 translation
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
enum {
OT_BYTE = 0,
OT_WORD,
- OT_LONG,
+ OT_LONG,
OT_QUAD,
};
/* code output */
uint8_t *gen_code_ptr;
uint8_t *gen_code_start;
-
+
/* current block context */
target_ulong cs_base; /* base of CS segment */
int pe; /* protected mode */
gl(s, val - (long)(s->gen_code_ptr + 4));
}
-static inline void gen_movl_addr_im(DisasContext *s,
+static inline void gen_movl_addr_im(DisasContext *s,
uint32_t addr, uint32_t val)
{
gb(s, CPU_SEG); /* seg movl im, addr */
- gb(s, 0xc7);
+ gb(s, 0xc7);
gb(s, 0x05);
gl(s, addr);
gl(s, val);
}
-static inline void gen_movw_addr_im(DisasContext *s,
+static inline void gen_movw_addr_im(DisasContext *s,
uint32_t addr, uint32_t val)
{
gb(s, CPU_SEG); /* seg movl im, addr */
- gb(s, 0x66);
- gb(s, 0xc7);
+ gb(s, 0x66);
+ gb(s, 0xc7);
gb(s, 0x05);
gl(s, addr);
gw(s, val);
gb(s, 0xe9); /* jmp */
tb->tb_jmp_offset[1] = s->gen_code_ptr - s->gen_code_start;
gl(s, 0);
-
+
tb->tb_next_offset[0] = s->gen_code_ptr - s->gen_code_start;
gen_movl_addr_im(s, CPU_FIELD_OFFSET(eip), target_eip);
gen_movl_addr_im(s, CPU_FIELD_OFFSET(tmp0), (uint32_t)tb);
base = rm;
index = 0;
scale = 0;
-
+
if (base == 4) {
havesib = 1;
code = ldub_code(s->pc++);
s->pc += 4;
break;
}
-
+
} else {
switch (mod) {
case 0:
static inline void parse_modrm(DisasContext *s, int modrm)
{
if ((modrm & 0xc0) != 0xc0)
- gen_lea_modrm(s, modrm);
+ gen_lea_modrm(s, modrm);
}
static inline uint32_t insn_get(DisasContext *s, int ot)
/* extended op code */
b = ldub_code(s->pc++) | 0x100;
goto reswitch;
-
+
/**************************/
/* arith & logic */
case 0x00 ... 0x05:
ot = OT_BYTE;
else
ot = dflag ? OT_LONG : OT_WORD;
-
+
switch(f) {
case 0: /* OP Ev, Gv */
modrm = ldub_code(s->pc++);
ot = OT_BYTE;
else
ot = dflag ? OT_LONG : OT_WORD;
-
+
modrm = ldub_code(s->pc++);
parse_modrm(s, modrm);
break;
case 2: /* call Ev */
/* XXX: optimize and handle MEM exceptions specifically
- fs movl %eax, regs[0]
- movl Ev, %eax
+ fs movl %eax, regs[0]
+ movl Ev, %eax
pushl next_eip
fs movl %eax, eip
*/
goto unsupported_op;
case 4: /* jmp Ev */
/* XXX: optimize and handle MEM exceptions specifically
- fs movl %eax, regs[0]
- movl Ev, %eax
+ fs movl %eax, regs[0]
+ movl Ev, %eax
fs movl %eax, eip
*/
goto unsupported_op;
ot = dflag ? OT_LONG : OT_WORD;
insn_get(s, ot);
break;
-
+
case 0x98: /* CWDE/CBW */
break;
case 0x99: /* CDQ/CWD */
break;
case 0x84: /* test Ev, Gv */
- case 0x85:
-
+ case 0x85:
+
case 0x1c0:
case 0x1c1: /* xadd Ev, Gv */
goto illegal_op;
parse_modrm(s, modrm);
break;
-
+
/**************************/
/* push/pop */
case 0x50 ... 0x57: /* push */
goto unsupported_op;
/************************/
/* floats */
- case 0xd8 ... 0xdf:
+ case 0xd8 ... 0xdf:
#if 1
/* currently not stable enough */
goto unsupported_op;
goto illegal_op;
parse_modrm(s, modrm);
break;
-
+
case 0xa0: /* mov EAX, Ov */
case 0xa1:
case 0xa2: /* mov Ov, EAX */
parse_modrm(s, modrm);
ldub_code(s->pc++);
break;
-
+
/************************/
/* string ops */
case 0xa4: /* movsS */
case 0xa5:
break;
-
+
case 0xaa: /* stosS */
case 0xab:
break;
case 0xc3: /* ret */
gb(s, CPU_SEG);
- if (!s->dflag)
+ if (!s->dflag)
gb(s, 0x66); /* d16 */
gb(s, 0x8f); /* pop addr */
gb(s, 0x05);
if (dflag) {
val = insn_get(s, OT_LONG);
} else {
- val = (int16_t)insn_get(s, OT_WORD);
+ val = (int16_t)insn_get(s, OT_WORD);
}
do_jcc:
next_eip = s->pc - s->cs_base;
case 0x90: /* nop */
break;
case 0x9b: /* fwait */
- if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
+ if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
(HF_MP_MASK | HF_TS_MASK)) {
goto unsupported_op;
}
#define GEN_CODE_MAX_INSN_SIZE 512
static inline int gen_intermediate_code_internal(CPUState *env,
- TranslationBlock *tb,
+ TranslationBlock *tb,
uint8_t *gen_code_ptr,
int *gen_code_size_ptr,
int search_pc,
env->singlestep_enabled)
return -1;
flags = tb->flags;
- if (flags & (HF_TF_MASK | HF_ADDSEG_MASK |
+ if (flags & (HF_TF_MASK | HF_ADDSEG_MASK |
HF_SOFTMMU_MASK | HF_INHIBIT_IRQ_MASK))
return -1;
if (!(flags & HF_SS32_MASK))
return -1;
if (tb->cflags & CF_SINGLE_INSN)
return -1;
- gen_code_end = gen_code_ptr +
+ gen_code_end = gen_code_ptr +
GEN_CODE_MAX_SIZE - GEN_CODE_MAX_INSN_SIZE;
dc->gen_code_ptr = gen_code_ptr;
dc->gen_code_start = gen_code_ptr;
break;
}
}
-
+
#ifdef DEBUG_DISAS
if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "----------------\n");
- fprintf(logfile, "IN: COPY: %s fpu=%d\n",
+ fprintf(logfile, "IN: COPY: %s fpu=%d\n",
lookup_symbol(pc_start),
tb->cflags & CF_TB_FP_USED ? 1 : 0);
target_disas(logfile, pc_start, dc->pc - pc_start, !dc->code32);
tb->tb_jmp_offset[2] = 0xffff;
tb->tb_jmp_offset[3] = 0xffff;
#endif
- return gen_intermediate_code_internal(env, tb,
+ return gen_intermediate_code_internal(env, tb,
tb->tc_ptr, gen_code_size_ptr,
0, NULL);
}
static uint8_t dummy_gen_code_buf[GEN_CODE_MAX_SIZE];
-int cpu_restore_state_copy(TranslationBlock *tb,
+int cpu_restore_state_copy(TranslationBlock *tb,
CPUState *env, unsigned long searched_pc,
void *puc)
{
if (searched_pc < (unsigned long)tb->tc_ptr)
return -1;
searched_pc = searched_pc - (long)tb->tc_ptr + (long)dummy_gen_code_buf;
- ret = gen_intermediate_code_internal(env, tb,
+ ret = gen_intermediate_code_internal(env, tb,
dummy_gen_code_buf, NULL,
1, (uint8_t *)searched_pc);
if (ret < 0)
return ret;
/* restore all the CPU state from the CPU context from the
signal. The FPU context stays in the host CPU. */
-
+
env->regs[R_EAX] = uc->uc_mcontext.gregs[REG_EAX];
env->regs[R_ECX] = uc->uc_mcontext.gregs[REG_ECX];
env->regs[R_EDX] = uc->uc_mcontext.gregs[REG_EDX];
/*
* i386 translation
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
/* i386 arith/logic operations */
enum {
- OP_ADDL,
- OP_ORL,
- OP_ADCL,
+ OP_ADDL,
+ OP_ORL,
+ OP_ADCL,
OP_SBBL,
- OP_ANDL,
- OP_SUBL,
- OP_XORL,
+ OP_ANDL,
+ OP_SUBL,
+ OP_XORL,
OP_CMPL,
};
/* i386 shift ops */
enum {
- OP_ROL,
- OP_ROR,
- OP_RCL,
- OP_RCR,
- OP_SHL,
- OP_SHR,
+ OP_ROL,
+ OP_ROR,
+ OP_RCL,
+ OP_RCR,
+ OP_SHL,
+ OP_SHR,
OP_SHL1, /* undocumented */
OP_SAR = 7,
};
enum {
OT_BYTE = 0,
OT_WORD,
- OT_LONG,
+ OT_LONG,
OT_QUAD,
};
#endif
};
-static GenOpFunc *gen_op_mov_TN_reg[NB_OP_SIZES][2][CPU_NB_REGS] =
+static GenOpFunc *gen_op_mov_TN_reg[NB_OP_SIZES][2][CPU_NB_REGS] =
{
[OT_BYTE] = {
{
gen_op_jnz_ecxl,
X86_64_ONLY(gen_op_jnz_ecxq),
};
-
+
static GenOpFunc1 *gen_op_jz_ecx[3] = {
gen_op_jz_ecxw,
gen_op_jz_ecxl,
if (s->aflag == 2) {
gen_op_addq_ESI_T0();
gen_op_addq_EDI_T0();
- } else
+ } else
#endif
if (s->aflag) {
gen_op_addl_ESI_T0();
#ifdef TARGET_X86_64
if (s->aflag == 2) {
gen_op_addq_EDI_T0();
- } else
+ } else
#endif
if (s->aflag) {
gen_op_addl_EDI_T0();
#ifdef TARGET_X86_64
if (s->aflag == 2) {
gen_op_addq_ESI_T0();
- } else
+ } else
#endif
if (s->aflag) {
gen_op_addl_ESI_T0();
#ifdef TARGET_X86_64
if (s->aflag == 2) {
gen_op_addq_EDI_T0();
- } else
+ } else
#endif
if (s->aflag) {
gen_op_addl_EDI_T0();
if (s->aflag == 2) {
gen_op_addq_ESI_T0();
gen_op_addq_EDI_T0();
- } else
+ } else
#endif
if (s->aflag) {
gen_op_addl_ESI_T0();
#ifdef TARGET_X86_64
if (s->aflag == 2) {
gen_op_addq_EDI_T0();
- } else
+ } else
#endif
if (s->aflag) {
gen_op_addl_EDI_T0();
#ifdef TARGET_X86_64
if (s->aflag == 2) {
gen_op_addq_ESI_T0();
- } else
+ } else
#endif
if (s->aflag) {
gen_op_addl_ESI_T0();
static void gen_op(DisasContext *s1, int op, int ot, int d)
{
GenOpFunc *gen_update_cc;
-
+
if (d != OR_TMP0) {
gen_op_mov_TN_reg[ot][0][d]();
} else {
/* for zero counts, flags are not updated, so must do it dynamically */
if (s1->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s1->cc_op);
-
+
if (d != OR_TMP0)
gen_op_shift_T0_T1_cc[ot][op]();
else
base = rm;
index = 0;
scale = 0;
-
+
if (base == 4) {
havesib = 1;
code = ldub_code(s->pc++);
s->pc += 4;
break;
}
-
+
if (base >= 0) {
/* for correct popl handling with esp */
if (base == 4 && s->popl_esp_hack)
else
gen_op_addq_A0_im64(disp >> 32, disp);
}
- } else
+ } else
#endif
{
gen_op_movl_A0_reg[base]();
gen_op_movq_A0_im(disp);
else
gen_op_movq_A0_im64(disp >> 32, disp);
- } else
+ } else
#endif
{
gen_op_movl_A0_im(disp);
#ifdef TARGET_X86_64
if (s->aflag == 2) {
gen_op_addq_A0_reg_sN[scale][index]();
- } else
+ } else
#endif
{
gen_op_addl_A0_reg_sN[scale][index]();
#ifdef TARGET_X86_64
if (s->aflag == 2) {
gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
- } else
+ } else
#endif
{
gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
if (s->aflag) {
base = rm;
-
+
if (base == 4) {
code = ldub_code(s->pc++);
base = (code & 7);
}
-
+
switch (mod) {
case 0:
if (base == 5) {
#ifdef TARGET_X86_64
if (CODE64(s)) {
gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
- } else
+ } else
#endif
{
gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
}
}
-static inline void gen_jcc(DisasContext *s, int b,
+static inline void gen_jcc(DisasContext *s, int b,
target_ulong val, target_ulong next_eip)
{
TranslationBlock *tb;
inv = b & 1;
jcc_op = (b >> 1) & 7;
-
+
if (s->jmp_opt) {
switch(s->cc_op) {
/* we optimize the cmp/jcc case */
case CC_OP_SUBQ:
func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
break;
-
+
/* some jumps are easy to compute */
case CC_OP_ADDB:
case CC_OP_ADDW:
gen_setcc_slow[jcc_op]();
func = gen_op_jnz_T0_label;
}
-
+
if (inv) {
tmp = val;
val = next_eip;
if (!func)
goto slow_jcc;
break;
-
+
/* some jumps are easy to compute */
case CC_OP_ADDB:
case CC_OP_ADDW:
if (CODE64(s)) {
if (addend == 8)
gen_op_addq_ESP_8();
- else
+ else
gen_op_addq_ESP_im(addend);
} else
#endif
gen_op_addl_ESP_2();
else if (addend == 4)
gen_op_addl_ESP_4();
- else
+ else
gen_op_addl_ESP_im(addend);
} else {
if (addend == 2)
gen_op_st_T0_A0[OT_WORD + s->mem_index]();
}
gen_op_movq_ESP_A0();
- } else
+ } else
#endif
{
gen_op_movl_A0_reg[R_ESP]();
gen_op_st_T0_A0[OT_WORD + s->mem_index]();
}
gen_op_movq_ESP_A0();
- } else
+ } else
#endif
{
gen_op_movl_A0_reg[R_ESP]();
gen_op_addl_A0_SS();
}
gen_op_st_T1_A0[s->dflag + 1 + s->mem_index]();
-
+
if (s->ss32 && !s->addseg)
gen_op_movl_ESP_A0();
else
if (CODE64(s)) {
gen_op_movq_A0_reg[R_ESP]();
gen_op_ld_T0_A0[(s->dflag ? OT_QUAD : OT_WORD) + s->mem_index]();
- } else
+ } else
#endif
{
gen_op_movl_A0_reg[R_ESP]();
if (CODE64(s)) {
ot = s->dflag ? OT_QUAD : OT_WORD;
opsize = 1 << ot;
-
+
gen_op_movl_A0_ESP();
gen_op_addq_A0_im(-opsize);
gen_op_movl_T1_A0();
gen_op_mov_reg_T1[ot][R_EBP]();
gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
gen_op_mov_reg_T1[OT_QUAD][R_ESP]();
- } else
+ } else
#endif
{
ot = s->dflag + OT_WORD;
opsize = 2 << s->dflag;
-
+
gen_op_movl_A0_ESP();
gen_op_addl_A0_im(-opsize);
if (!s->ss32)
/* an interrupt is different from an exception because of the
priviledge checks */
-static void gen_interrupt(DisasContext *s, int intno,
+static void gen_interrupt(DisasContext *s, int intno,
target_ulong cur_eip, target_ulong next_eip)
{
if (s->cc_op != CC_OP_DYNAMIC)
static void gen_movtl_T0_im(target_ulong val)
{
-#ifdef TARGET_X86_64
+#ifdef TARGET_X86_64
if ((int32_t)val == val) {
gen_op_movl_T0_im(val);
} else {
static void gen_movtl_T1_im(target_ulong val)
{
-#ifdef TARGET_X86_64
+#ifdef TARGET_X86_64
if ((int32_t)val == val) {
gen_op_movl_T1_im(val);
} else {
[0x57] = { gen_op_pxor_xmm, gen_op_pxor_xmm }, /* xorps, xorpd */
[0x58] = SSE_FOP(add),
[0x59] = SSE_FOP(mul),
- [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps,
+ [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps,
gen_op_cvtss2sd, gen_op_cvtsd2ss },
[0x5b] = { gen_op_cvtdq2ps, gen_op_cvtps2dq, gen_op_cvttps2dq },
[0x5c] = SSE_FOP(sub),
[0x6d] = { NULL, gen_op_punpckhqdq_xmm },
[0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
[0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
- [0x70] = { (GenOpFunc2 *)gen_op_pshufw_mmx,
- (GenOpFunc2 *)gen_op_pshufd_xmm,
- (GenOpFunc2 *)gen_op_pshufhw_xmm,
+ [0x70] = { (GenOpFunc2 *)gen_op_pshufw_mmx,
+ (GenOpFunc2 *)gen_op_pshufd_xmm,
+ (GenOpFunc2 *)gen_op_pshufhw_xmm,
(GenOpFunc2 *)gen_op_pshuflw_xmm },
[0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
[0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
gen_op_cvtsi2sd,
X86_64_ONLY(gen_op_cvtsq2ss),
X86_64_ONLY(gen_op_cvtsq2sd),
-
+
gen_op_cvttss2si,
gen_op_cvttsd2si,
X86_64_ONLY(gen_op_cvttss2sq),
X86_64_ONLY(gen_op_cvtss2sq),
X86_64_ONLY(gen_op_cvtsd2sq),
};
-
+
static GenOpFunc2 *sse_op_table4[8][4] = {
SSE_FOP(cmpeq),
SSE_FOP(cmplt),
SSE_FOP(cmpnle),
SSE_FOP(cmpord),
};
-
+
static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
{
int b1, op1_offset, op2_offset, is_xmm, val, ot;
GenOpFunc3 *sse_op3;
b &= 0xff;
- if (s->prefix & PREFIX_DATA)
+ if (s->prefix & PREFIX_DATA)
b1 = 1;
- else if (s->prefix & PREFIX_REPZ)
+ else if (s->prefix & PREFIX_REPZ)
b1 = 2;
- else if (s->prefix & PREFIX_REPNZ)
+ else if (s->prefix & PREFIX_REPNZ)
b1 = 3;
else
b1 = 0;
sse_op2 = sse_op_table1[b][b1];
- if (!sse_op2)
+ if (!sse_op2)
goto illegal_op;
if (b <= 0x5f || b == 0xc6 || b == 0xc2) {
is_xmm = 1;
b |= (b1 << 8);
switch(b) {
case 0x0e7: /* movntq */
- if (mod == 3)
+ if (mod == 3)
goto illegal_op;
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
if (s->dflag == 2) {
gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
gen_op_movq_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
- } else
+ } else
#endif
{
gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
if (s->dflag == 2) {
gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
gen_op_movq_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
- } else
+ } else
#endif
{
gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
if (s->dflag == 2) {
gen_op_movq_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
- } else
+ } else
#endif
{
gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
if (s->dflag == 2) {
gen_op_movq_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
- } else
+ } else
#endif
{
gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
rm = (modrm & 7) | REX_B(s);
op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
}
- sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
+ sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
(b & 1) * 4](op2_offset);
gen_op_mov_reg_T0[ot][reg]();
break;
case 0xc4: /* pinsrw */
- case 0x1c4:
+ case 0x1c4:
s->rip_offset = 1;
gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
val = ldub_code(s->pc++);
}
break;
case 0xc5: /* pextrw */
- case 0x1c5:
+ case 0x1c5:
if (mod != 3)
goto illegal_op;
val = ldub_code(s->pc++);
switch(b) {
case 0xf7:
/* maskmov : we must prepare A0 */
- if (mod != 3)
+ if (mod != 3)
goto illegal_op;
#ifdef TARGET_X86_64
if (s->aflag == 2) {
gen_op_movq_A0_reg[R_EDI]();
- } else
+ } else
#endif
{
gen_op_movl_A0_reg[R_EDI]();
#ifdef TARGET_X86_64
s->rex_x = 0;
s->rex_b = 0;
- x86_64_hregs = 0;
+ x86_64_hregs = 0;
#endif
s->rip_offset = 0; /* for relative ip address */
next_byte:
}
if (!(prefixes & PREFIX_ADR))
aflag = 2;
- } else
+ } else
#endif
{
switch (b) {
/* extended op code */
b = ldub_code(s->pc++) | 0x100;
goto reswitch;
-
+
/**************************/
/* arith & logic */
case 0x00 ... 0x05:
ot = OT_BYTE;
else
ot = dflag + OT_WORD;
-
+
switch(f) {
case 0: /* OP Ev, Gv */
modrm = ldub_code(s->pc++);
ot = OT_BYTE;
else
ot = dflag + OT_WORD;
-
+
modrm = ldub_code(s->pc++);
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
op = (modrm >> 3) & 7;
-
+
if (mod != 3) {
if (b == 0x83)
s->rip_offset = 1;
break;
case 0x84: /* test Ev, Gv */
- case 0x85:
+ case 0x85:
if ((b & 1) == 0)
ot = OT_BYTE;
else
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
reg = ((modrm >> 3) & 7) | rex_r;
-
+
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
gen_op_mov_TN_reg[ot][1][reg]();
gen_op_testl_T0_T1_cc();
s->cc_op = CC_OP_LOGICB + ot;
break;
-
+
case 0xa8: /* test eAX, Iv */
case 0xa9:
if ((b & 1) == 0)
gen_op_testl_T0_T1_cc();
s->cc_op = CC_OP_LOGICB + ot;
break;
-
+
case 0x98: /* CWDE/CBW */
#ifdef TARGET_X86_64
if (dflag == 2) {
gen_op_cmpxchg8b();
s->cc_op = CC_OP_EFLAGS;
break;
-
+
/**************************/
/* push/pop */
case 0x50 ... 0x57: /* push */
ot = dflag + OT_WORD;
modrm = ldub_code(s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
-
+
/* generate a generic store */
gen_ldst_modrm(s, modrm, ot, reg, 1);
break;
ot = OT_WORD + dflag;
modrm = ldub_code(s->pc++);
reg = ((modrm >> 3) & 7) | rex_r;
-
+
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
gen_op_mov_reg_T0[ot][reg]();
break;
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
-
+
if (mod == 3) {
gen_op_mov_TN_reg[ot][0][rm]();
switch(ot | (b & 8)) {
s->addseg = val;
gen_op_mov_reg_A0[ot - OT_WORD][reg]();
break;
-
+
case 0xa0: /* mov EAX, Ov */
case 0xa1:
case 0xa2: /* mov Ov, EAX */
gen_op_movq_A0_im(offset_addr);
else
gen_op_movq_A0_im64(offset_addr >> 32, offset_addr);
- } else
+ } else
#endif
{
if (s->aflag) {
if (s->aflag == 2) {
gen_op_movq_A0_reg[R_EBX]();
gen_op_addq_A0_AL();
- } else
+ } else
#endif
{
gen_op_movl_A0_reg[R_EBX]();
reg = (b & 7) | REX_B(s);
gen_movtl_T0_im(tmp);
gen_op_mov_reg_T0[OT_QUAD][reg]();
- } else
+ } else
#endif
{
ot = dflag ? OT_LONG : OT_WORD;
gen_eob(s);
}
break;
-
+
/************************/
/* shifts */
case 0xc0:
ot = OT_BYTE;
else
ot = dflag + OT_WORD;
-
+
modrm = ldub_code(s->pc++);
mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7;
-
+
if (mod != 3) {
if (shift == 2) {
s->rip_offset = 1;
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
reg = ((modrm >> 3) & 7) | rex_r;
-
+
if (mod != 3) {
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
gen_op_ld_T0_A0[ot + s->mem_index]();
gen_op_mov_TN_reg[ot][0][rm]();
}
gen_op_mov_TN_reg[ot][1][reg]();
-
+
if (shift) {
val = ldub_code(s->pc++);
if (ot == OT_QUAD)
/************************/
/* floats */
- case 0xd8 ... 0xdf:
+ case 0xd8 ... 0xdf:
if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
/* if CR0.EM or CR0.TS are set, generate an FPU exception */
/* XXX: what to do if illegal op ? */
gen_op_fild_FT0_A0();
break;
}
-
+
gen_op_fp_arith_ST0_FT0[op1]();
if (op1 == 3) {
/* fcomp needs pop */
case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
{
int op1;
-
+
op1 = op & 7;
if (op >= 0x20) {
gen_op_fp_arith_STN_ST0[op1](opreg);
break;
case 0x28: /* ffree sti */
gen_op_ffree_STN(opreg);
- break;
+ break;
case 0x2a: /* fst sti */
gen_op_fmov_STN_ST0(opreg);
break;
gen_movs(s, ot);
}
break;
-
+
case 0xaa: /* stosS */
case 0xab:
if ((b & 1) == 0)
case 0x9a: /* lcall im */
{
unsigned int selector, offset;
-
+
if (CODE64(s))
goto illegal_op;
ot = dflag ? OT_LONG : OT_WORD;
offset = insn_get(s, ot);
selector = insn_get(s, OT_WORD);
-
+
gen_op_movl_T0_im(selector);
gen_op_movl_T1_imu(offset);
}
ot = dflag ? OT_LONG : OT_WORD;
offset = insn_get(s, ot);
selector = insn_get(s, OT_WORD);
-
+
gen_op_movl_T0_im(selector);
gen_op_movl_T1_imu(offset);
}
if (dflag) {
tval = (int32_t)insn_get(s, OT_LONG);
} else {
- tval = (int16_t)insn_get(s, OT_WORD);
+ tval = (int16_t)insn_get(s, OT_WORD);
}
do_jcc:
next_eip = s->pc - s->cs_base;
}
gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
break;
-
+
/************************/
/* flags */
case 0x9c: /* pushf */
goto illegal_op;
break;
case 0x9b: /* fwait */
- if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
+ if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
(HF_MP_MASK | HF_TS_MASK)) {
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
} else {
case 0xcd: /* int N */
val = ldub_code(s->pc++);
if (s->vm86 && s->iopl != 3) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
}
gen_op_mov_TN_reg[OT_QUAD][0][reg]();
gen_op_bswapq_T0();
gen_op_mov_reg_T0[OT_QUAD][reg]();
- } else
+ } else
#endif
{
gen_op_mov_TN_reg[OT_LONG][0][reg]();
tval += next_eip;
if (s->dflag == 0)
tval &= 0xffff;
-
+
l1 = gen_new_label();
l2 = gen_new_label();
b &= 3;
if (s->aflag == 2) {
gen_op_movq_A0_reg[R_EBX]();
gen_op_addq_A0_AL();
- } else
+ } else
#endif
{
gen_op_movl_A0_reg[R_EBX]();
gen_op_movtl_T1_env(offsetof(CPUX86State,kernelgsbase));
gen_op_movtl_env_T1(offsetof(CPUX86State,segs[R_GS].base));
gen_op_movtl_env_T0(offsetof(CPUX86State,kernelgsbase));
- } else
+ } else
#endif
{
goto illegal_op;
reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s);
-
+
if (mod == 3) {
gen_op_mov_TN_reg[OT_LONG][0][rm]();
/* sign extend */
}
gen_op_mov_reg_T0[d_ot][reg]();
}
- } else
+ } else
#endif
{
if (!s->pe || s->vm86)
gen_jmp_im(s->pc - s->cs_base);
gen_eob(s);
} else {
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (reg == 8)
gen_op_movtl_T0_cr8();
else
op = (modrm >> 3) & 7;
switch(op) {
case 0: /* fxsave */
- if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
+ if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
(s->flags & HF_EM_MASK))
goto illegal_op;
if (s->flags & HF_TS_MASK) {
gen_op_fxsave_A0((s->dflag == 2));
break;
case 1: /* fxrstor */
- if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
+ if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
(s->flags & HF_EM_MASK))
goto illegal_op;
if (s->flags & HF_TS_MASK) {
#define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
/* flags read by an operation */
-static uint16_t opc_read_flags[NB_OPS] = {
+static uint16_t opc_read_flags[NB_OPS] = {
[INDEX_op_aas] = CC_A,
[INDEX_op_aaa] = CC_A,
[INDEX_op_das] = CC_A | CC_C,
[INDEX_op_daa] = CC_A | CC_C,
/* subtle: due to the incl/decl implementation, C is used */
- [INDEX_op_update_inc_cc] = CC_C,
+ [INDEX_op_update_inc_cc] = CC_C,
[INDEX_op_into] = CC_O,
};
/* flags written by an operation */
-static uint16_t opc_write_flags[NB_OPS] = {
+static uint16_t opc_write_flags[NB_OPS] = {
[INDEX_op_update2_cc] = CC_OSZAPC,
[INDEX_op_update1_cc] = CC_OSZAPC,
[INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_update_neg_cc] = CC_OSZAPC,
/* subtle: due to the incl/decl implementation, C is used */
- [INDEX_op_update_inc_cc] = CC_OSZAPC,
+ [INDEX_op_update_inc_cc] = CC_OSZAPC,
[INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_mulb_AL_T0] = CC_OSZAPC,
};
/* simpler form of an operation if no flags need to be generated */
-static uint16_t opc_simpler[NB_OPS] = {
+static uint16_t opc_simpler[NB_OPS] = {
[INDEX_op_update2_cc] = INDEX_op_nop,
[INDEX_op_update1_cc] = INDEX_op_nop,
[INDEX_op_update_neg_cc] = INDEX_op_nop,
basic block 'tb'. If search_pc is TRUE, also generate PC
information for each intermediate instruction. */
static inline int gen_intermediate_code_internal(CPUState *env,
- TranslationBlock *tb,
+ TranslationBlock *tb,
int search_pc)
{
DisasContext dc1, *dc = &dc1;
int flags, j, lj, cflags;
target_ulong pc_start;
target_ulong cs_base;
-
+
/* generate intermediate code */
pc_start = tb->pc;
cs_base = tb->cs_base;
/* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
the flag and abort the translation to give the irqs a
change to be happen */
- if (dc->tf || dc->singlestep_enabled ||
+ if (dc->tf || dc->singlestep_enabled ||
(flags & HF_INHIBIT_IRQ_MASK) ||
(cflags & CF_SINGLE_INSN)) {
gen_jmp_im(pc_ptr - dc->cs_base);
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
}
-
+
#ifdef DEBUG_DISAS
if (loglevel & CPU_LOG_TB_CPU) {
cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
/*
* m68k virtual CPU header
- *
+ *
* Copyright (c) 2005-2006 CodeSourcery
* Written by Paul Brook
*
/* Temporary storage for DIV helpers. */
uint32_t div1;
uint32_t div2;
-
+
/* MMU status. */
struct {
uint32_t ar;
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
-int cpu_m68k_signal_handler(int host_signum, void *pinfo,
+int cpu_m68k_signal_handler(int host_signum, void *pinfo,
void *puc);
void cpu_m68k_flush_flags(CPUM68KState *, int);
/* Linux uses 8k pages. */
#define TARGET_PAGE_BITS 13
#else
-/* Smallest TLB entry size is 1k. */
+/* Smallest TLB entry size is 1k. */
#define TARGET_PAGE_BITS 10
#endif
#include "cpu-all.h"
/*
* m68k execution defines
- *
+ *
* Copyright (c) 2005-2006 CodeSourcery
* Written by Paul Brook
*
/*
* m68k op helpers
- *
+ *
* Copyright (c) 2006 CodeSourcery
* Written by Paul Brook
*
/*
* m68k micro operations
- *
+ *
* Copyright (c) 2006 CodeSourcery
* Written by Paul Brook
*
uint32_t quot;
uint32_t rem;
uint32_t flags;
-
+
num = env->div1;
den = env->div2;
/* ??? This needs to make sure the throwing location is accurate. */
int32_t quot;
int32_t rem;
int32_t flags;
-
+
num = env->div1;
den = env->div2;
if (den == 0)
/*
* m68k translation
- *
+ *
* Copyright (c) 2005-2006 CodeSourcery
* Written by Paul Brook
*
{"m5206", M68K_INSN_CF_A},
{"cfv4e", M68K_INSN_CF_A | M68K_INSN_CF_B | M68K_INSN_CF_C
| M68K_INSN_CF_MAC | M68K_INSN_CF_EMAC | M68K_INSN_CF_FPU},
- {NULL, 0},
+ {NULL, 0},
};
typedef void (*disas_proc)(DisasContext *, uint16_t);
uint32_t base;
int op;
int l1;
-
+
base = s->pc;
op = (insn >> 8) & 0xf;
offset = (int8_t)insn;
}
gen_ea(s, insn, OS_LONG, res, NULL);
break;
- case 6: /* fmovem */
+ case 6: /* fmovem */
case 7:
{
int addr;
tmp = gen_new_qreg(QMODE_F32);
gen_op_f64_to_f32(tmp, res);
gen_op_f32_to_f64(res, tmp);
- }
+ }
gen_op_fp_result(res);
if (dest) {
gen_op_movf64(dest, res);
int arg0 = qop->args[0];
int arg1 = qop->args[1];
int l1, l2;
-
+
gen_op_add32 (arg0, arg0, arg1);
l1 = gen_new_label();
l2 = gen_new_label();
/* generate intermediate code */
pc_start = tb->pc;
-
+
dc->tb = tb;
gen_opc_ptr = gen_opc_buf;
register_m68k_insns(def);
}
-void cpu_dump_state(CPUState *env, FILE *f,
+void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
{
return addr;
}
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
int is_user, int is_softmmu)
#define FP_DIV0 8
#define FP_INVALID 16
#define FP_UNIMPLEMENTED 32
-
+
#endif
#if defined(MIPS_USES_R4K_TLB)
tlb_t tlb[MIPS_TLB_MAX];
void do_tlbr (void);
#ifdef MIPS_USES_FPU
void dump_fpu(CPUState *env);
-void fpu_dump_state(CPUState *env, FILE *f,
+void fpu_dump_state(CPUState *env, FILE *f,
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
int flags);
#endif
void do_raise_exception (uint32_t exception);
void do_raise_exception_direct (uint32_t exception);
-void cpu_dump_state(CPUState *env, FILE *f,
+void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags);
void cpu_mips_irqctrl_init (void);
/*
- * MIPS emulation micro-operations templates for floating point reg
+ * MIPS emulation micro-operations templates for floating point reg
* load & store for qemu.
- *
+ *
* Copyright (c) 2006 Marius Groeger
*
* This library is free software; you can redistribute it and/or
/*
* MIPS emulation helpers for qemu.
- *
+ *
* Copyright (c) 2004-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
return ret;
}
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
{
return addr;
/* TLB match but 'D' bit is cleared */
exception = EXCP_LTLBL;
break;
-
+
}
/* Raise exception */
env->CP0_BadVAddr = address;
/*
* MIPS emulation micro-operations for qemu.
- *
+ *
* Copyright (c) 2004-2005 Jocelyn Mayer
* Copyright (c) 2006 Marius Groeger (FPU operations)
*
}
/* convert MIPS rounding mode in FCR31 to IEEE library */
-unsigned int ieee_rm[] = {
+unsigned int ieee_rm[] = {
float_round_nearest_even,
float_round_to_zero,
float_round_up,
if (T1 == 0) {
/* XXX should this throw an exception?
* don't write to FCR0.
- * env->fcr0 = T0;
+ * env->fcr0 = T0;
*/
}
else {
- /* store new fcr31, masking unused bits */
+ /* store new fcr31, masking unused bits */
env->fcr31 = T0 & 0x0183FFFF;
/* set rounding mode */
}
}
-FOP_COND(d, f, 0, 0)
+FOP_COND(d, f, 0, 0)
FOP_COND(d, un, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status))
FOP_COND(d, eq, 0, float64_eq(FDT0, FDT1, &env->fp_status))
FOP_COND(d, ueq, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
/* NOTE: the comma operator will make "cond" to eval to false,
* but float*_is_unordered() is still called
*/
-FOP_COND(s, f, 0, 0)
+FOP_COND(s, f, 0, 0)
FOP_COND(s, un, 0, float32_is_unordered(FST1, FST0, &env->fp_status))
FOP_COND(s, eq, 0, float32_eq(FST0, FST1, &env->fp_status))
FOP_COND(s, ueq, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
/*
* MIPS emulation helpers for qemu.
- *
+ *
* Copyright (c) 2004-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
}
#endif
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
void do_mfc0_random (void)
{
cpu_abort(env, "mfc0 random\n");
enable = GET_FP_ENABLE(env->fcr31);
- /* determine current flags */
+ /* determine current flags */
if (flags & float_flag_invalid) {
cpuflags |= FP_INVALID;
cause |= FP_INVALID & enable;
}
if (flags & float_flag_divbyzero) {
- cpuflags |= FP_DIV0;
+ cpuflags |= FP_DIV0;
cause |= FP_DIV0 & enable;
}
if (flags & float_flag_overflow) {
- cpuflags |= FP_OVERFLOW;
+ cpuflags |= FP_OVERFLOW;
cause |= FP_OVERFLOW & enable;
}
if (flags & float_flag_underflow) {
- cpuflags |= FP_UNDERFLOW;
+ cpuflags |= FP_UNDERFLOW;
cause |= FP_UNDERFLOW & enable;
}
if (flags & float_flag_inexact) {
- cpuflags |= FP_INEXACT;
+ cpuflags |= FP_INEXACT;
cause |= FP_INEXACT & enable;
}
SET_FP_FLAGS(env->fcr31, cpuflags);
}
}
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr);
/*
* MIPS emulation memory micro-operations for qemu.
- *
+ *
* Copyright (c) 2004-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
/*
* MIPS emulation micro-operations templates for reg load & store for qemu.
- *
+ *
* Copyright (c) 2004-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
/*
* MIPS32 emulation for qemu: main translation routines.
- *
+ *
* Copyright (c) 2004-2005 Jocelyn Mayer
* Copyright (c) 2006 Marius Groeger (FPU operations)
* Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
const char *opn = "unk";
if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
- /* if no destination, treat it as a NOP
+ /* if no destination, treat it as a NOP
* For addi, we must generate the overflow exception when needed.
*/
MIPS_DEBUG("NOP");
if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
&& opc != OPC_DADD && opc != OPC_DSUB) {
- /* if no destination, treat it as a NOP
+ /* if no destination, treat it as a NOP
* For add & sub, we must generate the overflow exception when needed.
*/
MIPS_DEBUG("NOP");
likely:
ctx->hflags |= MIPS_HFLAG_BL;
break;
- default:
+ default:
MIPS_INVAL("cp1 branch/jump");
generate_exception_err (ctx, EXCP_RI, 1);
return;
* even-odd pair of adjacent coprocessor general registers. When the FR bit
* in the Status register equals one, both even and odd register numbers
* are valid.
- *
+ *
* Multiple float registers can be checked by calling
* CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
*/
gen_cmp_s(func-48);
opn = condnames[func-48];
break;
- default:
+ default:
if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
}
#endif
-
+
return 0;
}
#ifdef MIPS_USES_FPU
-void fpu_dump_state(CPUState *env, FILE *f,
+void fpu_dump_state(CPUState *env, FILE *f,
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
{
void dump_fpu (CPUState *env)
{
- if (loglevel) {
+ if (loglevel) {
fprintf(logfile, "pc=0x" TLSZ " HI=0x" TLSZ " LO=0x" TLSZ " ds %04x " TLSZ " %d\n",
env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
fpu_dump_state(env, logfile, fprintf, 0);
}
#endif
-void cpu_dump_state (CPUState *env, FILE *f,
+void cpu_dump_state (CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
{
uint32_t c0_status;
int i;
-
+
cpu_fprintf(f, "pc=0x" TLSZ " HI=0x" TLSZ " LO=0x" TLSZ " ds %04x " TLSZ " %d\n",
env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
for (i = 0; i < 32; i++) {
env->user_mode_only = 1;
#endif
#ifdef MIPS_USES_FPU
- env->fcr0 = MIPS_FCR0;
+ env->fcr0 = MIPS_FCR0;
#endif
/* XXX some guesswork here, values are CPU specific */
env->SYNCI_Step = 16;
/*
* PowerPC emulation cpu definitions for qemu.
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
-int cpu_ppc_signal_handler(int host_signum, void *pinfo,
+int cpu_ppc_signal_handler(int host_signum, void *pinfo,
void *puc);
void do_interrupt (CPUPPCState *env);
/*
* PowerPC emulation definitions for qemu.
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
/*
* PowerPC emulation helpers for qemu.
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
/*****************************************************************************/
/* PowerPC MMU emulation */
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
int is_user, int is_softmmu)
{
int exception, error_code;
-
+
if (rw == 2) {
exception = EXCP_ISI;
error_code = 0;
((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0;
if ((sr & 0x80000000) == 0) {
#if defined (DEBUG_MMU)
- if (loglevel > 0)
+ if (loglevel > 0)
fprintf(logfile, "pte segment: key=%d n=0x%08x\n",
key, sr & 0x10000000);
#endif
if (loglevel > 0) {
fprintf(logfile, "%s\n", __func__);
}
-#endif
+#endif
if ((access_type == ACCESS_CODE && msr_ir == 0) ||
(access_type != ACCESS_CODE && msr_dr == 0)) {
/* No address translation */
fprintf(logfile, "%s address %08x => %08x\n",
__func__, address, *physical);
}
-#endif
+#endif
return ret;
}
/* Compute current hflags */
env->hflags = (msr_pr << MSR_PR) | (msr_le << MSR_LE) |
(msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_fe1 << MSR_FE1) |
- (msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) |
+ (msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) |
(msr_se << MSR_SE) | (msr_be << MSR_BE);
}
/*
* PowerPC emulation micro-operations for qemu.
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
PPC_OP(setcrfbit)
{
- T1 = (T1 & PARAM(1)) | (T0 << PARAM(2));
+ T1 = (T1 & PARAM(1)) | (T0 << PARAM(2));
RETURN();
}
RETURN();
}
-PPC_OP(btest_T1)
+PPC_OP(btest_T1)
{
if (T0) {
regs->nip = T1 & ~3;
/*
* PowerPC emulation helpers for qemu.
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
/*
* PowerPC emulation micro-operations for qemu.
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
/*
* PowerPC emulation for qemu: main translation routines.
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
{
uint32_t mb, me, sh;
-
+
sh = SH(ctx->opcode);
mb = MB(ctx->opcode);
me = ME(ctx->opcode);
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
{
uint8_t crb;
-
+
if (!ctx->fpu_enabled) {
RET_EXCP(ctx, EXCP_NO_FP, 0);
return;
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
{
uint8_t crb;
-
+
if (!ctx->fpu_enabled) {
RET_EXCP(ctx, EXCP_NO_FP, 0);
return;
}
gen_op_set_T1(nb);
/* NIP cannot be restored if the memory exception comes from an helper */
- gen_op_update_nip((ctx)->nip - 4);
+ gen_op_update_nip((ctx)->nip - 4);
op_ldsts(lswi, start);
}
}
gen_op_load_xer_bc();
/* NIP cannot be restored if the memory exception comes from an helper */
- gen_op_update_nip((ctx)->nip - 4);
+ gen_op_update_nip((ctx)->nip - 4);
op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
}
nb = 32;
gen_op_set_T1(nb);
/* NIP cannot be restored if the memory exception comes from an helper */
- gen_op_update_nip((ctx)->nip - 4);
+ gen_op_update_nip((ctx)->nip - 4);
op_ldsts(stsw, rS(ctx->opcode));
}
}
gen_op_load_xer_bc();
/* NIP cannot be restored if the memory exception comes from an helper */
- gen_op_update_nip((ctx)->nip - 4);
+ gen_op_update_nip((ctx)->nip - 4);
op_ldsts(stsw, rS(ctx->opcode));
}
#define BCOND_LR 1
#define BCOND_CTR 2
-static inline void gen_bcond(DisasContext *ctx, int type)
-{
+static inline void gen_bcond(DisasContext *ctx, int type)
+{
uint32_t target = 0;
- uint32_t bo = BO(ctx->opcode);
- uint32_t bi = BI(ctx->opcode);
- uint32_t mask;
+ uint32_t bo = BO(ctx->opcode);
+ uint32_t bi = BI(ctx->opcode);
+ uint32_t mask;
uint32_t li;
if ((bo & 0x4) == 0)
- gen_op_dec_ctr();
+ gen_op_dec_ctr();
switch(type) {
case BCOND_IM:
li = (int32_t)((int16_t)(BD(ctx->opcode)));
gen_op_movl_T1_lr();
break;
}
- if (LK(ctx->opcode)) {
+ if (LK(ctx->opcode)) {
gen_op_setlr(ctx->nip);
}
if (bo & 0x10) {
- /* No CR condition */
- switch (bo & 0x6) {
- case 0:
+ /* No CR condition */
+ switch (bo & 0x6) {
+ case 0:
gen_op_test_ctr();
break;
- case 2:
+ case 2:
gen_op_test_ctrz();
- break;
+ break;
default:
- case 4:
- case 6:
+ case 4:
+ case 6:
if (type == BCOND_IM) {
gen_goto_tb(ctx, 0, target);
} else {
}
goto no_test;
}
- } else {
- mask = 1 << (3 - (bi & 0x03));
- gen_op_load_crf_T0(bi >> 2);
- if (bo & 0x8) {
- switch (bo & 0x6) {
- case 0:
+ } else {
+ mask = 1 << (3 - (bi & 0x03));
+ gen_op_load_crf_T0(bi >> 2);
+ if (bo & 0x8) {
+ switch (bo & 0x6) {
+ case 0:
gen_op_test_ctr_true(mask);
- break;
- case 2:
+ break;
+ case 2:
gen_op_test_ctrz_true(mask);
- break;
- default:
- case 4:
- case 6:
+ break;
+ default:
+ case 4:
+ case 6:
gen_op_test_true(mask);
- break;
- }
- } else {
- switch (bo & 0x6) {
- case 0:
+ break;
+ }
+ } else {
+ switch (bo & 0x6) {
+ case 0:
gen_op_test_ctr_false(mask);
- break;
- case 2:
+ break;
+ case 2:
gen_op_test_ctrz_false(mask);
- break;
+ break;
default:
- case 4:
- case 6:
+ case 4:
+ case 6:
gen_op_test_false(mask);
- break;
- }
- }
- }
+ break;
+ }
+ }
+ }
if (type == BCOND_IM) {
int l1 = gen_new_label();
gen_op_jz_T0(l1);
gen_op_btest_T1(ctx->nip);
}
no_test:
- ctx->exception = EXCP_BRANCH;
+ ctx->exception = EXCP_BRANCH;
}
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
-{
+{
gen_bcond(ctx, BCOND_IM);
}
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
-{
+{
gen_bcond(ctx, BCOND_CTR);
}
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
-{
+{
gen_bcond(ctx, BCOND_LR);
}
/*****************************************************************************/
/* Misc PowerPC helpers */
-void cpu_dump_state(CPUState *env, FILE *f,
+void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
{
if (env->nb_breakpoints > 0) {
for(j = 0; j < env->nb_breakpoints; j++) {
if (env->breakpoints[j] == ctx.nip) {
- gen_op_update_nip(ctx.nip);
+ gen_op_update_nip(ctx.nip);
gen_op_debug();
break;
}
/*
* PowerPC CPU initialization for qemu.
- *
+ *
* Copyright (c) 2003-2005 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
return ret;
}
-static int register_dblind_insn (opc_handler_t **ppc_opcodes,
+static int register_dblind_insn (opc_handler_t **ppc_opcodes,
unsigned char idx1, unsigned char idx2,
unsigned char idx3, opc_handler_t *handler)
{
import sys
denand (open (sys.argv[1], 'rb'),
open (sys.argv[2], 'wb'))
-
+
Style isssues
-------------
/*
* SH4 emulation
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
*
* This library is free software; you can redistribute it and/or
CPUSH4State *cpu_sh4_init(void);
int cpu_sh4_exec(CPUSH4State * s);
-int cpu_sh4_signal_handler(int host_signum, void *pinfo,
+int cpu_sh4_signal_handler(int host_signum, void *pinfo,
void *puc);
#include "softfloat.h"
/*
* SH4 emulation
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
*
* This library is free software; you can redistribute it and/or
/*
* SH4 emulation
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
*
* This library is free software; you can redistribute it and/or
/*
* SH4 emulation
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
*
* This library is free software; you can redistribute it and/or
/*
* SH4 emulation
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
*
* This library is free software; you can redistribute it and/or
/*
* SH4 emulation
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
*
* This library is free software; you can redistribute it and/or
/*
* SH4 translation
- *
+ *
* Copyright (c) 2005 Samuel Tardieu
*
* This library is free software; you can redistribute it and/or
#define TT_PRIV_INSN 0x03
#define TT_NFPU_INSN 0x04
#define TT_WIN_OVF 0x05
-#define TT_WIN_UNF 0x06
+#define TT_WIN_UNF 0x06
#define TT_FP_EXCP 0x08
#define TT_DFAULT 0x09
#define TT_EXTINT 0x10
/*
* SPARC micro operations (templates for various register related
* operations)
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
/*
* sparc helpers
- *
+ *
* Copyright (c) 2003-2005 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
spin_unlock(&global_cpu_lock);
}
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
int is_user, int is_softmmu)
__p.l.v1 = PARAM1;\
__p.l.v0 = PARAM2;\
__p.q;\
-})
+})
void OPPROTO op_movq_T0_im64(void)
{
void OPPROTO op_save(void)
{
uint32_t cwp;
- cwp = (env->cwp - 1) & (NWINDOWS - 1);
+ cwp = (env->cwp - 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
raise_exception(TT_WIN_OVF);
}
void OPPROTO op_restore(void)
{
uint32_t cwp;
- cwp = (env->cwp + 1) & (NWINDOWS - 1);
+ cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
raise_exception(TT_WIN_UNF);
}
void OPPROTO op_save(void)
{
uint32_t cwp;
- cwp = (env->cwp - 1) & (NWINDOWS - 1);
+ cwp = (env->cwp - 1) & (NWINDOWS - 1);
if (env->cansave == 0) {
- raise_exception(TT_SPILL | (env->otherwin != 0 ?
+ raise_exception(TT_SPILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
} else {
void OPPROTO op_restore(void)
{
uint32_t cwp;
- cwp = (env->cwp + 1) & (NWINDOWS - 1);
+ cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->canrestore == 0) {
- raise_exception(TT_FILL | (env->otherwin != 0 ?
+ raise_exception(TT_FILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
} else {
void OPPROTO op_eval_ble(void)
{
target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
-
+
T2 = Z | (N ^ V);
}
void OPPROTO op_eval_xble(void)
{
target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
-
+
T2 = Z | (N ^ V);
}
void OPPROTO op_flushw(void)
{
if (env->cansave != NWINDOWS - 2) {
- raise_exception(TT_SPILL | (env->otherwin != 0 ?
+ raise_exception(TT_SPILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
}
{
env->exception_index = tt;
cpu_loop_exit();
-}
+}
#ifdef USE_INT_TO_FLOAT_HELPERS
void do_fitos(void)
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26);
#endif
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
void helper_ld_asi(int asi, int size, int sign)
{
}
case 4: /* read MMU regs */
{
int reg = (T0 >> 8) & 0xf;
-
+
ret = env->mmuregs[reg];
if (reg == 3) /* Fault status cleared on read */
env->mmuregs[reg] = 0;
{
int reg = (T0 >> 8) & 0xf;
uint32_t oldreg;
-
+
oldreg = env->mmuregs[reg];
switch(reg) {
case 0:
// copy 32 bytes
uint32_t src = T1, dst = T0;
uint8_t temp[32];
-
+
tswap32s(&src);
cpu_physical_memory_read(src, (void *) &temp, 32);
int i;
uint32_t dst = T0;
uint64_t val;
-
+
val = (((uint64_t)T1) << 32) | T2;
tswap64s(&val);
case 0x56: // I-MMU tag read
{
unsigned int i;
-
+
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
case 0x5e: // D-MMU tag read
{
unsigned int i;
-
+
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
{
int reg = (T0 >> 3) & 0xf;
uint64_t oldreg;
-
+
oldreg = env->immuregs[reg];
switch(reg) {
case 0: // RO
{
int reg = (T0 >> 3) & 0xf;
uint64_t oldreg;
-
+
oldreg = env->dmmuregs[reg];
switch(reg) {
case 0: // RO
unsigned int cwp;
env->psret = 1;
- cwp = (env->cwp + 1) & (NWINDOWS - 1);
+ cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
raise_exception(TT_WIN_UNF);
}
count++;
}
#endif
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (env->tl == MAXTL) {
cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
return;
count++;
}
#endif
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (env->psret == 0) {
cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
return;
}
#endif
env->psret = 0;
- cwp = (env->cwp - 1) & (NWINDOWS - 1);
+ cwp = (env->cwp - 1) & (NWINDOWS - 1);
set_cwp(cwp);
env->regwptr[9] = env->pc;
env->regwptr[10] = env->npc;
}
#endif
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
#define MMUSUFFIX _mmu
#define GETPC() (__builtin_return_address(0))
/*
* SPARC micro operations (templates for various register related
* operations)
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
#endif
}
-static inline void gen_goto_tb(DisasContext *s, int tb_num,
+static inline void gen_goto_tb(DisasContext *s, int tb_num,
target_ulong pc, target_ulong npc)
{
TranslationBlock *tb;
{
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
target_ulong target = dc->pc + offset;
-
+
if (cond == 0x0) {
/* unconditional not taken */
if (a) {
- dc->pc = dc->npc + 4;
+ dc->pc = dc->npc + 4;
dc->npc = dc->pc + 4;
} else {
dc->pc = dc->npc;
}
case 0x3: /* V9 BPr */
{
- target = GET_FIELD_SP(insn, 0, 13) |
+ target = GET_FIELD_SP(insn, 0, 13) |
(GET_FIELD_SP(insn, 20, 21) << 14);
target = sign_extend(target, 16);
target <<= 2;
exit_gen_loop:
if (!dc->is_br) {
- if (dc->pc != DYNAMIC_PC &&
+ if (dc->pc != DYNAMIC_PC &&
(dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
/* static PC and NPC: we can use direct chaining */
gen_branch(dc, (long)tb, dc->pc, dc->npc);
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
-void cpu_dump_state(CPUState *env, FILE *f,
+void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
{
cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
- env->psrs?'S':'-', env->psrps?'P':'-',
+ env->psrs?'S':'-', env->psrps?'P':'-',
env->psret?'E':'-', env->wim);
#endif
cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
: "r0","r1","r2","r3","lr"); \
__syscall_return(type,__res); \
}
-
+
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
/*
* linux and CPU test
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
int __chk_error(const char *filename, int line, int ret)
{
if (ret < 0) {
- error1(filename, line, "%m (ret=%d, errno=%d)",
+ error1(filename, line, "%m (ret=%d, errno=%d)",
ret, errno);
}
return ret;
if (getcwd(cur_dir, sizeof(cur_dir)) == NULL)
error("getcwd");
-
+
chk_error(mkdir(TESTPATH, 0755));
-
+
chk_error(chdir(TESTPATH));
-
+
/* open/read/write/close/readv/writev/lseek */
fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644));
error("read");
if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0)
error("memcmp");
-
+
#define FOFFSET 16
ret = chk_error(lseek(fd, FOFFSET, SEEK_SET));
if (ret != 16)
error("readv");
if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0)
error("memcmp");
-
+
chk_error(close(fd));
/* access */
chk_error(ftruncate(fd, 50));
chk_error(fstat(fd, &st));
chk_error(close(fd));
-
+
if (st.st_size != 50)
error("stat size");
if (!S_ISREG(st.st_mode))
error("stat mode");
-
+
/* symlink/lstat */
chk_error(symlink("file2", "file3"));
chk_error(lstat("file3", &st));
if (!S_ISLNK(st.st_mode))
error("stat mode");
-
+
/* getdents */
dir = opendir(TESTPATH);
if (!dir)
ti = tv2.tv_sec - tv.tv_sec;
if (ti >= 2)
error("gettimeofday");
-
+
chk_error(getrusage(RUSAGE_SELF, &rusg1));
for(i = 0;i < 10000; i++);
chk_error(getrusage(RUSAGE_SELF, &rusg2));
{
int len;
len = strlen(buf);
- if (len < buf_size)
+ if (len < buf_size)
pstrcpy(buf + len, buf_size - len, s);
return buf;
}
chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len));
if (val != SOCK_STREAM)
error("getsockopt");
-
+
pid = chk_error(fork());
if (pid == 0) {
client_fd = client_socket();
int pid1, pid2, status1, status2;
stack1 = malloc(STACK_SIZE);
- pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE,
+ pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1"));
stack2 = malloc(STACK_SIZE);
- pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE,
+ pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2"));
while (waitpid(pid1, &status1, 0) != pid1);
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
chk_error(sigaction(SIGALRM, &act, NULL));
-
+
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 10 * 1000;
it.it_value.tv_sec = 0;
if (oit.it_value.tv_sec != it.it_value.tv_sec ||
oit.it_value.tv_usec != it.it_value.tv_usec)
error("itimer");
-
+
while (alarm_count < 5) {
usleep(10 * 1000);
}
if (setjmp(jmp_env) == 0) {
*(uint8_t *)0 = 0;
}
-
+
act.sa_handler = SIG_DFL;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
return 0;
}
-static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
+static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
unsigned long addr, unsigned int sel)
{
unsigned int e1, e2;
*(uint16_t *)seg_to_linear(env->segs[R_SS].selector, env->regs[R_ESP]) = val;
}
-static void host_segv_handler(int host_signum, siginfo_t *info,
+static void host_segv_handler(int host_signum, siginfo_t *info,
void *puc)
{
if (cpu_signal_handler(host_signum, info, puc)) {
if (argc != 2)
usage();
filename = argv[1];
-
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
+
+ vm86_mem = mmap((void *)0x00000000, 0x110000,
+ PROT_WRITE | PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (vm86_mem == MAP_FAILED) {
perror("mmap");
/* install exception handler for CPU emulator */
{
struct sigaction act;
-
+
sigfillset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
// act.sa_flags |= SA_ONSTACK;
/* flags setup : we activate the IRQs by default as in user
mode. We also activate the VM86 flag to run DOS code */
env->eflags |= IF_MASK | VM_MASK;
-
+
/* init basic registers */
env->eip = 0x100;
env->regs[R_ESP] = 0xfffe;
seg = (COM_BASE_ADDR - 0x100) >> 4;
- cpu_x86_load_seg_cache(env, R_CS, seg,
+ cpu_x86_load_seg_cache(env, R_CS, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_SS, seg,
+ cpu_x86_load_seg_cache(env, R_SS, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_DS, seg,
+ cpu_x86_load_seg_cache(env, R_DS, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_ES, seg,
+ cpu_x86_load_seg_cache(env, R_ES, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_FS, seg,
+ cpu_x86_load_seg_cache(env, R_FS, seg,
(seg << 4), 0xffff, 0);
- cpu_x86_load_seg_cache(env, R_GS, seg,
+ cpu_x86_load_seg_cache(env, R_GS, seg,
(seg << 4), 0xffff, 0);
/* exception support */
set_idt(17, 0);
set_idt(18, 0);
set_idt(19, 0);
-
+
/* put return code */
*seg_to_linear(env->segs[R_CS].selector, 0) = 0xb4; /* mov ah, $0 */
*seg_to_linear(env->segs[R_CS].selector, 1) = 0x00;
env->regs[R_EDI] = 0xfffe;
/* inform the emulator of the mmaped memory */
- page_set_flags(0x00000000, 0x110000,
+ page_set_flags(0x00000000, 0x110000,
PAGE_WRITE | PAGE_READ | PAGE_EXEC | PAGE_VALID);
for(;;) {
void dump_regs(struct vm86_regs *r)
{
- fprintf(stderr,
+ fprintf(stderr,
"EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
"ESI=%08lx EDI=%08lx EBP=%08lx ESP=%08lx\n"
"EIP=%08lx EFL=%08lx\n"
if (argc != 2)
usage();
filename = argv[1];
-
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
+
+ vm86_mem = mmap((void *)0x00000000, 0x110000,
+ PROT_WRITE | PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (vm86_mem == MAP_FAILED) {
perror("mmap");
case VM86_INTx:
{
int int_num, ah;
-
+
int_num = VM86_ARG(ret);
if (int_num != 0x21)
goto unknown_int;
code16_start:
.globl code16_func1
-
+
/* basic test */
code16_func1 = . - code16_start
mov $1, %eax
pop %ax
data32 lret
-/* test various jmp opcodes */
+/* test various jmp opcodes */
.globl code16_func3
code16_func3 = . - code16_start
jmp 1f
jz 2f
add $2, %ax
2:
-
+
call myfunc
-
+
lcall $CS_SEG, $(myfunc2 - code16_start)
ljmp $CS_SEG, $(myjmp1 - code16_start)
myjmp2_next:
data32 lret
-
+
myfunc2_addr:
.short myfunc2 - code16_start
.short CS_SEG
-void glue(glue(test_, OP), b)(long op0, long op1)
+void glue(glue(test_, OP), b)(long op0, long op1)
{
long res, s1, s0, flags;
s0 = op0;
flags = 0;
asm ("push %4\n\t"
"popf\n\t"
- stringify(OP)"b %b2\n\t"
+ stringify(OP)"b %b2\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=a" (res), "=g" (flags)
stringify(OP) "b", s0, s1, res, flags & CC_MASK);
}
-void glue(glue(test_, OP), w)(long op0h, long op0, long op1)
+void glue(glue(test_, OP), w)(long op0h, long op0, long op1)
{
long res, s1, flags, resh;
s1 = op1;
flags = 0;
asm ("push %5\n\t"
"popf\n\t"
- stringify(OP) "w %w3\n\t"
+ stringify(OP) "w %w3\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=a" (res), "=g" (flags), "=d" (resh)
stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK);
}
-void glue(glue(test_, OP), l)(long op0h, long op0, long op1)
+void glue(glue(test_, OP), l)(long op0h, long op0, long op1)
{
long res, s1, flags, resh;
s1 = op1;
flags = 0;
asm ("push %5\n\t"
"popf\n\t"
- stringify(OP) "l %k3\n\t"
+ stringify(OP) "l %k3\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=a" (res), "=g" (flags), "=d" (resh)
}
#if defined(__x86_64__)
-void glue(glue(test_, OP), q)(long op0h, long op0, long op1)
+void glue(glue(test_, OP), q)(long op0h, long op0, long op1)
{
long res, s1, flags, resh;
s1 = op1;
flags = 0;
asm ("push %5\n\t"
"popf\n\t"
- stringify(OP) "q %3\n\t"
+ stringify(OP) "q %3\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=a" (res), "=g" (flags), "=d" (resh)
movw %ax, %es
es movw $GET_OFFSET(int90_test), 0x90 * 4
es movw %cs, 0x90 * 4 + 2
-
+
/* launch int 0x90 */
int $0x90
movb $0x09, %ah
int $0x21
- pushf
+ pushf
popw %dx
movb $0xff, %ah
int $0x21
cli
- pushf
+ pushf
popw %dx
movb $0xff, %ah
int $0x21
- sti
- pushfl
+ sti
+ pushfl
popl %edx
movb $0xff, %ah
int $0x21
-
+
#if 0
movw $GET_OFFSET(IF_msg1), %dx
movb $0x09, %ah
cli
#endif
- pushf
+ pushf
popw %dx
movb $0xff, %ah
int $0x21
-
+
pushfl
movw %sp, %bx
orw $0x200, (%bx)
int $0x21
int90_test:
- pushf
+ pushf
pop %dx
movb $0xff, %ah
int $0x21
movw 4(%bx), %dx
movb $0xff, %ah
int $0x21
-
+
movw $GET_OFFSET(int90_msg), %dx
movb $0x09, %ah
int $0x21
iret
-
+
int90_msg:
.string "INT90 started\n$"
-
+
hello_world:
.string "Hello VM86 world\n$"
.string "If you see a diff here, your Linux kernel is buggy, please update to 2.4.20 kernel\n$"
vm86_code_end:
-
\ No newline at end of file
/*
* x86 CPU test
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
#define OP imul
#include "test-i386-muldiv.h"
-void test_imulw2(long op0, long op1)
+void test_imulw2(long op0, long op1)
{
long res, s1, s0, flags;
s0 = op0;
flags = 0;
asm volatile ("push %4\n\t"
"popf\n\t"
- "imulw %w2, %w0\n\t"
+ "imulw %w2, %w0\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=q" (res), "=g" (flags)
"imulw", s0, s1, res, flags & CC_MASK);
}
-void test_imull2(long op0, long op1)
+void test_imull2(long op0, long op1)
{
long res, s1, s0, flags;
s0 = op0;
flags = 0;
asm volatile ("push %4\n\t"
"popf\n\t"
- "imull %k2, %k0\n\t"
+ "imull %k2, %k0\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=q" (res), "=g" (flags)
}
#if defined(__x86_64__)
-void test_imulq2(long op0, long op1)
+void test_imulq2(long op0, long op1)
{
long res, s1, s0, flags;
s0 = op0;
flags = 0;
asm volatile ("push %4\n\t"
"popf\n\t"
- "imulq %2, %0\n\t"
+ "imulq %2, %0\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=q" (res), "=g" (flags)
uint32_t ignored[4];
long double fpregs[8];
} float_env32;
-
+
asm volatile ("fnstenv %0\n" : : "m" (float_env32));
float_env32.fpus &= ~0x7f;
asm volatile ("fldenv %0\n" : : "m" (float_env32));
"fstsw %%ax\n"
: "=a" (fpus)
: "t" (a), "u" (b));
- printf("fcom(%f %f)=%04lx \n",
+ printf("fcom(%f %f)=%04lx \n",
a, b, fpus & (0x4500 | FPUS_EMASK));
fpu_clear_exceptions();
asm("fucom %2\n"
"fstsw %%ax\n"
: "=a" (fpus)
: "t" (a), "u" (b));
- printf("fucom(%f %f)=%04lx\n",
+ printf("fucom(%f %f)=%04lx\n",
a, b, fpus & (0x4500 | FPUS_EMASK));
if (TEST_FCOMI) {
/* test f(u)comi instruction */
"pop %0\n"
: "=r" (eflags), "=a" (fpus)
: "t" (a), "u" (b));
- printf("fcomi(%f %f)=%04lx %02lx\n",
+ printf("fcomi(%f %f)=%04lx %02lx\n",
a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
fpu_clear_exceptions();
asm("fucomi %3, %2\n"
"pop %0\n"
: "=r" (eflags), "=a" (fpus)
: "t" (a), "u" (b));
- printf("fucomi(%f %f)=%04lx %02lx\n",
+ printf("fucomi(%f %f)=%04lx %02lx\n",
a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
}
fpu_clear_exceptions();
printf("(float)%f = %f\n", a, fa);
printf("(long double)%f = %Lf\n", a, la);
printf("a=" FMT64X "\n", *(uint64_t *)&a);
- printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,
+ printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,
*(unsigned short *)((char *)(&la) + 8));
/* test all roundings */
asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
- printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
+ printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
}
TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
-
+
TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
else
op1 = op0;
op2 = 0x6532432432434;
- asm("cmpxchg8b %1\n"
+ asm("cmpxchg8b %1\n"
"pushf\n"
"pop %2\n"
: "=A" (op0), "=m" (op1), "=g" (eflags)
: "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
- printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n",
+ printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n",
op0, op1, eflags & CC_Z);
}
}
segoff.seg = MK_SEL(2);
segoff.offset = 0xabcdef12;
- asm volatile("lfs %2, %0\n\t"
+ asm volatile("lfs %2, %0\n\t"
"movl %%fs, %1\n\t"
- : "=r" (res), "=g" (res2)
+ : "=r" (res), "=g" (res2)
: "m" (segoff));
printf("FS:reg = %04x:%08x\n", res2, res);
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
/* call the first function */
- asm volatile ("lcall %1, %2"
+ asm volatile ("lcall %1, %2"
: "=a" (res)
: "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
printf("func1() = 0x%08x\n", res);
- asm volatile ("lcall %2, %3"
+ asm volatile ("lcall %2, %3"
: "=a" (res), "=c" (res2)
: "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
printf("func2() = 0x%08x spdec=%d\n", res, res2);
- asm volatile ("lcall %1, %2"
+ asm volatile ("lcall %1, %2"
: "=a" (res)
: "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
printf("func3() = 0x%08x\n", res);
asm volatile ("mov %%cs, %0" : "=r" (cs_sel));
asm volatile ("push %1\n"
- "call func_lret\n"
+ "call func_lret\n"
: "=a" (res)
: "r" (cs_sel) : "memory", "cc");
printf("func_lret=" FMTLX "\n", res);
/* NOTE: we assume that &func_lret < 4GB */
desc.offset = (long)&func_lret;
desc.seg = cs_sel;
-
+
asm volatile ("xor %%rax, %%rax\n"
"rex64 lcall %1\n"
: "=a" (res)
- : "m" (desc)
+ : "m" (desc)
: "memory", "cc");
printf("func_lret2=" FMTLX "\n", res);
printf("func_lret3=" FMTLX "\n", res);
}
#else
- asm volatile ("push %%cs ; call %1"
+ asm volatile ("push %%cs ; call %1"
: "=a" (res)
: "m" (func_lret): "memory", "cc");
printf("func_lret=" FMTLX "\n", res);
- asm volatile ("pushf ; push %%cs ; call %1"
+ asm volatile ("pushf ; push %%cs ; call %1"
: "=a" (res)
: "m" (func_iret): "memory", "cc");
printf("func_iret=" FMTLX "\n", res);
TEST_STRING(stos, "");
TEST_STRING(stos, "rep ");
TEST_STRING(lods, ""); /* to verify stos */
- TEST_STRING(lods, "rep ");
+ TEST_STRING(lods, "rep ");
TEST_STRING(movs, "");
TEST_STRING(movs, "rep ");
TEST_STRING(lods, ""); /* to verify stos */
uint8_t *vm86_mem;
int seg, ret;
- vm86_mem = mmap((void *)0x00000000, 0x110000,
- PROT_WRITE | PROT_READ | PROT_EXEC,
+ vm86_mem = mmap((void *)0x00000000, 0x110000,
+ PROT_WRITE | PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (vm86_mem == MAP_FAILED) {
printf("ERROR: could not map vm86 memory");
/* move code to proper address. We use the same layout as a .com
dos program. */
- memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,
+ memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,
&vm86_code_start, &vm86_code_end - &vm86_code_start);
/* mark int 0x21 as being emulated */
case VM86_INTx:
{
int int_num, ah, v;
-
+
int_num = VM86_ARG(ret);
if (int_num != 0x21)
goto unknown_int;
{
struct sigaction act;
volatile int val;
-
+
act.sa_sigaction = sig_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO | SA_NODEFER;
ldt.seg_not_present = 1;
ldt.useable = 1;
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
-
+
if (setjmp(jmp_env) == 0) {
/* segment not present */
asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
/* read from an invalid address */
v1 = *(char *)0x1234;
}
-
+
/* test illegal instruction reporting */
printf("UD2 exception:\n");
if (setjmp(jmp_env) == 0) {
/* now execute an invalid instruction */
asm volatile("lock nop");
}
-
+
printf("INT exception:\n");
if (setjmp(jmp_env) == 0) {
asm volatile ("int $0xfd");
asm volatile ("pushf\n"
"orl $0x00100, (%%esp)\n"
"popf\n"
- "movl $0xabcd, %0\n"
+ "movl $0xabcd, %0\n"
"movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");
}
printf("val=0x%x\n", val);
asm volatile ("pushf\n"
"orl $0x00100, (%%esp)\n"
"popf\n"
- "movl $0xabcd, %0\n"
+ "movl $0xabcd, %0\n"
/* jmp test */
"movl $3, %%ecx\n"
"rep cmpsb\n"
"movl $4, %%ecx\n"
"rep cmpsb\n"
-
+
/* getpid() syscall: single step should skip one
instruction */
"movl $20, %%eax\n"
"int $0x80\n"
"movl $0, %%eax\n"
-
+
/* when modifying SS, trace is not done on the next
instruction */
"movl %%ss, %%ecx\n"
"popl %%ss\n"
"addl $1, %0\n"
"movl $1, %%eax\n"
-
+
"pushf\n"
"andl $~0x00100, (%%esp)\n"
"popf\n"
- : "=m" (val)
- :
+ : "=m" (val)
+ :
: "cc", "memory", "eax", "ecx", "esi", "edi");
printf("val=%d\n", val);
for(i = 0; i < 4; i++)
" fxrstor %0\n"
" fxsave %1\n"
" fninit\n"
- : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp)
+ : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp)
: "m" (a), "m" (b));
printf("fpuc=%04x\n", fp->fpuc);
printf("fpus=%04x\n", fp->fpus);
printf("fptag=%04x\n", fp->fptag);
for(i = 0; i < 3; i++) {
printf("ST%d: " FMT64X " %04x\n",
- i,
+ i,
*(uint64_t *)&fp->fpregs1[i * 16],
*(uint16_t *)&fp->fpregs1[i * 16 + 8]);
}
#endif
for(i = 0; i < nb_xmm; i++) {
printf("xmm%d: " FMT64X "" FMT64X "\n",
- i,
+ i,
*(uint64_t *)&fp->xmm_regs[i * 16],
*(uint64_t *)&fp->xmm_regs[i * 16 + 8]);
}
MMX_OP2(pmulhuw);
MMX_OP2(pmulhw);
-
+
MMX_OP2(psubsb);
MMX_OP2(psubsw);
MMX_OP2(pminsw);
asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
-
+
asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
a.q[1] = test_values[0][1];
b.q[0] = test_values[1][0];
b.q[1] = test_values[1][1];
- asm volatile("maskmovq %1, %0" :
+ asm volatile("maskmovq %1, %0" :
: "y" (a.q[0]), "y" (b.q[0]), "D" (&r)
- : "memory");
- printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n",
- "maskmov",
- r.q[0],
- a.q[0],
+ : "memory");
+ printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n",
+ "maskmov",
+ r.q[0],
+ a.q[0],
b.q[0]);
- asm volatile("maskmovdqu %1, %0" :
+ asm volatile("maskmovdqu %1, %0" :
: "x" (a.dq), "x" (b.dq), "D" (&r)
- : "memory");
- printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n",
- "maskmov",
- r.q[1], r.q[0],
- a.q[1], a.q[0],
+ : "memory");
+ printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n",
+ "maskmov",
+ r.q[1], r.q[0],
+ a.q[1], a.q[0],
b.q[1], b.q[0]);
}
SSE_OPS(cmpnlt);
SSE_OPS(cmpnle);
SSE_OPS(cmpord);
-
-
+
+
a.d[0] = 2.7;
a.d[1] = -3.4;
b.d[0] = 45.7;
$inf = gensym();
# Try cwd and $ibase.
- open($inf, "<" . $1)
+ open($inf, "<" . $1)
or open($inf, "<" . $ibase . "/" . $1)
or die "cannot open $1 or $ibase/$1: $!\n";
next;
/*
* Generic thunking code to convert data between host and target CPU
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
int nb_fields, offset, max_align, align, size, i, j;
se = struct_entries + id;
-
+
/* first we count the number of fields */
type_ptr = types;
nb_fields = 0;
se->nb_fields = nb_fields;
se->name = name;
#ifdef DEBUG
- printf("struct %s: id=%d nb_fields=%d\n",
+ printf("struct %s: id=%d nb_fields=%d\n",
se->name, id, se->nb_fields);
#endif
/* now we can alloc the data */
se->size[i] = offset;
se->align[i] = max_align;
#ifdef DEBUG
- printf("%s: size=%d align=%d\n",
+ printf("%s: size=%d align=%d\n",
i == THUNK_HOST ? "host" : "target", offset, max_align);
#endif
}
/* now we can define the main conversion functions */
-const argtype *thunk_convert(void *dst, const void *src,
+const argtype *thunk_convert(void *dst, const void *src,
const argtype *type_ptr, int to_host)
{
int type;
uint8_t *d;
const argtype *field_types;
const int *dst_offsets, *src_offsets;
-
+
se = struct_entries + *type_ptr++;
if (se->convert[0] != NULL) {
/* specific conversion is needed */
d = dst;
s = src;
for(i = 0;i < se->nb_fields; i++) {
- field_types = thunk_convert(d + dst_offsets[i],
- s + src_offsets[i],
+ field_types = thunk_convert(d + dst_offsets[i],
+ s + src_offsets[i],
field_types, to_host);
}
}
/* Utility function: Table-driven functions to translate bitmasks
* between X86 and Alpha formats...
*/
-unsigned int target_to_host_bitmask(unsigned int x86_mask,
+unsigned int target_to_host_bitmask(unsigned int x86_mask,
bitmask_transtbl * trans_tbl)
{
bitmask_transtbl * btp;
return(alpha_mask);
}
-unsigned int host_to_target_bitmask(unsigned int alpha_mask,
+unsigned int host_to_target_bitmask(unsigned int alpha_mask,
bitmask_transtbl * trans_tbl)
{
bitmask_transtbl * btp;
/*
* Generic thunking code to convert data between host and target CPU
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
void thunk_register_struct(int id, const char *name, const argtype *types);
void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
-const argtype *thunk_convert(void *dst, const void *src,
+const argtype *thunk_convert(void *dst, const void *src,
const argtype *type_ptr, int to_host);
#ifndef NO_THUNK_TYPE_SIZE
#endif /* NO_THUNK_TYPE_SIZE */
-unsigned int target_to_host_bitmask(unsigned int x86_mask,
+unsigned int target_to_host_bitmask(unsigned int x86_mask,
bitmask_transtbl * trans_tbl);
-unsigned int host_to_target_bitmask(unsigned int alpha_mask,
+unsigned int host_to_target_bitmask(unsigned int alpha_mask,
bitmask_transtbl * trans_tbl);
#endif
/*
* Host code generation
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
for(;;) {
c = *opc_ptr++;
n = op_nb_args[c];
- fprintf(logfile, "0x%04x: %s",
+ fprintf(logfile, "0x%04x: %s",
(int)(opc_ptr - opc_buf - 1), op_str[c]);
for(i = 0; i < n; i++) {
fprintf(logfile, " 0x%x", opparam_ptr[i]);
uint8_t *gen_code_ptr;
int c, i;
unsigned long gen_code_addr[OPC_BUF_SIZE];
-
+
if (nb_gen_labels == 0)
return;
/* compute the address of each op code */
-
+
gen_code_ptr = gen_code_buf;
i = 0;
for(;;) {
gen_code_ptr += opc_copy_size[c];
i++;
}
-
+
/* compute the address of each label */
for(i = 0; i < nb_gen_labels; i++) {
gen_labels[i] = gen_code_addr[gen_labels[i]];
}
/* return non zero if the very first instruction is invalid so that
- the virtual CPU can trigger an exception.
+ the virtual CPU can trigger an exception.
'*gen_code_size_ptr' contains the size of the generated code (host
code).
return 0;
}
-/* The cpu state corresponding to 'searched_pc' is restored.
+/* The cpu state corresponding to 'searched_pc' is restored.
*/
-int cpu_restore_state(TranslationBlock *tb,
+int cpu_restore_state(TranslationBlock *tb,
CPUState *env, unsigned long searched_pc,
void *puc)
{
#endif
if (gen_intermediate_code_pc(env, tb) < 0)
return -1;
-
+
/* find opc index corresponding to search_pc */
tc_ptr = (unsigned long)tb->tc_ptr;
if (searched_pc < tc_ptr)
fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
}
}
- fprintf(logfile, "spc=0x%08lx j=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
- searched_pc, j, gen_opc_pc[j] - tb->cs_base,
+ fprintf(logfile, "spc=0x%08lx j=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
+ searched_pc, j, gen_opc_pc[j] - tb->cs_base,
(uint32_t)tb->cs_base);
}
#endif
} else if (npc == 2) {
target_ulong t2 = (target_ulong)puc;
/* jump PC: use T2 and the jump targets of the translation */
- if (t2)
+ if (t2)
env->npc = gen_opc_jump_pc[0];
else
env->npc = gen_opc_jump_pc[1];
case INDEX_op_ ## op ## _user:\
case INDEX_op_ ## op ## _kernel
#endif
-
+
CASE3(stfd):
CASE3(stfs):
CASE3(lfd):
/*
* Host code generation
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
* Linux host USB redirector
*
* 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
};
typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
+ int vendor_id, int product_id,
const char *product_name, int speed);
-static int usb_host_find_device(int *pbus_num, int *paddr,
+static int usb_host_find_device(int *pbus_num, int *paddr,
char *product_name, int product_name_size,
const char *devname);
done by the host OS */
ioctl(s->fd, USBDEVFS_RESET);
#endif
-}
+}
static void usb_host_handle_destroy(USBDevice *dev)
{
int bus_num, addr;
char product_name[PRODUCT_NAME_SZ];
- if (usb_host_find_device(&bus_num, &addr,
+ if (usb_host_find_device(&bus_num, &addr,
product_name, sizeof(product_name),
- devname) < 0)
+ devname) < 0)
return NULL;
-
- snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
+
+ snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
bus_num, addr);
fd = open(buf, O_RDWR);
if (fd < 0) {
perror("read descr");
goto fail;
}
-
+
i = 0;
dev_descr_len = descr[0];
if (dev_descr_len > descr_len)
#ifdef DEBUG
printf("host USB device %d.%d grabbed\n", bus_num, addr);
-#endif
+#endif
dev = qemu_mallocz(sizeof(USBHostDevice));
if (!dev)
}
static int get_tag_value(char *buf, int buf_size,
- const char *str, const char *tag,
+ const char *str, const char *tag,
const char *stopchars)
{
const char *p;
int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
int ret;
char product_name[512];
-
+
f = fopen(USBDEVFS_PATH "/devices", "r");
if (!f) {
term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
if (line[0] == 'T' && line[1] == ':') {
if (device_count && (vendor_id || product_id)) {
/* New device. Add the previously discovered device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
+ ret = func(opaque, bus_num, addr, class_id, vendor_id,
product_id, product_name, speed);
if (ret)
goto the_end;
}
if (device_count && (vendor_id || product_id)) {
/* Add the last device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
+ ret = func(opaque, bus_num, addr, class_id, vendor_id,
product_id, product_name, speed);
}
the_end:
char product_name[PRODUCT_NAME_SZ];
} FindDeviceState;
-static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
+static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
int class_id,
- int vendor_id, int product_id,
+ int vendor_id, int product_id,
const char *product_name, int speed)
{
FindDeviceState *s = opaque;
}
}
-/* the syntax is :
- 'bus.addr' (decimal numbers) or
+/* the syntax is :
+ 'bus.addr' (decimal numbers) or
'vendor_id:product_id' (hexa numbers) */
-static int usb_host_find_device(int *pbus_num, int *paddr,
+static int usb_host_find_device(int *pbus_num, int *paddr,
char *product_name, int product_name_size,
const char *devname)
{
}
void usb_info_device(int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
+ int vendor_id, int product_id,
const char *product_name,
int speed)
{
const char *class_str, *speed_str;
switch(speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
+ case USB_SPEED_LOW:
+ speed_str = "1.5";
break;
- case USB_SPEED_FULL:
- speed_str = "12";
+ case USB_SPEED_FULL:
+ speed_str = "12";
break;
- case USB_SPEED_HIGH:
- speed_str = "480";
+ case USB_SPEED_HIGH:
+ speed_str = "480";
break;
default:
- speed_str = "?";
+ speed_str = "?";
break;
}
- term_printf(" Device %d.%d, speed %s Mb/s\n",
+ term_printf(" Device %d.%d, speed %s Mb/s\n",
bus_num, addr, speed_str);
class_str = usb_class_str(class_id);
- if (class_str)
+ if (class_str)
term_printf(" %s:", class_str);
else
term_printf(" Class %02x:", class_id);
term_printf("\n");
}
-static int usb_host_info_device(void *opaque, int bus_num, int addr,
+static int usb_host_info_device(void *opaque, int bus_num, int addr,
int class_id,
- int vendor_id, int product_id,
+ int vendor_id, int product_id,
const char *product_name,
int speed)
{
/*
* QEMU System Emulator
- *
+ *
* Copyright (c) 2003-2007 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
}
/* size is the word size in byte */
-int register_ioport_read(int start, int length, int size,
+int register_ioport_read(int start, int length, int size,
IOPortReadFunc *func, void *opaque)
{
int i, bsize;
}
/* size is the word size in byte */
-int register_ioport_write(int start, int length, int size,
+int register_ioport_write(int start, int length, int size,
IOPortWriteFunc *func, void *opaque)
{
int i, bsize;
#ifdef DEBUG_IOPORT
if (loglevel & CPU_LOG_IOPORT)
fprintf(logfile, "outb: %04x %02x\n", addr, val);
-#endif
+#endif
ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
#ifdef USE_KQEMU
if (env)
#ifdef DEBUG_IOPORT
if (loglevel & CPU_LOG_IOPORT)
fprintf(logfile, "outw: %04x %04x\n", addr, val);
-#endif
+#endif
ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
#ifdef USE_KQEMU
if (env)
uint32_t high, low;
#else
uint32_t low, high;
-#endif
+#endif
} l;
} u, res;
uint64_t rl, rh;
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000000000LL + ts.tv_nsec;
- } else
+ } else
#endif
{
/* XXX: using gettimeofday leads to problems if the date
/***********************************************************/
/* timers */
-
+
#define QEMU_TIMER_REALTIME 0
#define QEMU_TIMER_VIRTUAL 1
t = *pt;
if (!t)
break;
- if (t->expire_time > expire_time)
+ if (t->expire_time > expire_time)
break;
pt = &t->next;
}
static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
{
QEMUTimer *ts;
-
+
for(;;) {
ts = *ptimer_head;
if (!ts || ts->expire_time > current_time)
/* remove timer from the list before calling the callback */
*ptimer_head = ts->next;
ts->next = NULL;
-
+
/* run the callback (the timer list can be modified) */
ts->cb(ts->opaque);
}
}
#ifdef _WIN32
-void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
+void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
#else
static void host_alarm_handler(int host_signum)
{
struct sigaction act;
struct itimerval itv;
-
+
/* get times() syscall frequency */
timer_freq = sysconf(_SC_CLK_TCK);
-
+
/* timer signal */
sigfillset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGIO, &act, NULL);
fcntl(rtc_fd, F_SETFL, O_ASYNC);
fcntl(rtc_fd, F_SETOWN, getpid());
- } else
+ } else
#endif /* defined(__linux__) */
{
use_itimer:
- pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
+ pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
PIT_FREQ) / 1000000;
}
}
s->chr_send_event(s, event);
}
-void qemu_chr_add_handlers(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
+void qemu_chr_add_handlers(CharDriverState *s,
+ IOCanRWHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
void *opaque)
if (s->chr_update_read_handler)
s->chr_update_read_handler(s);
}
-
+
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
return len;
static int send_all(int fd, const uint8_t *buf, int len1)
{
int ret, len;
-
+
len = len1;
while (len > 0) {
ret = send(fd, buf, len, 0);
FDCharDriver *s = chr->opaque;
int size, len;
uint8_t buf[1024];
-
+
len = sizeof(buf);
if (len > s->max_size)
len = s->max_size;
if (s->fd_in >= 0) {
if (nographic && s->fd_in == 0) {
} else {
- qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
+ qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
fd_chr_read, NULL, chr);
}
}
case 'x':
exit(0);
break;
- case 's':
+ case 's':
{
int i;
for (i = 0; i < MAX_DISKS; i++) {
if (client_index < stdio_nb_clients) {
uint8_t buf[1];
CharDriverState *chr;
-
+
chr = stdio_clients[client_index];
if (qemu_chr_can_read(chr) > 0) {
buf[0] = ch;
{
int size;
uint8_t buf[1];
-
+
size = read(0, buf, 1);
if (size == 0) {
/* stdin has been closed. Remove it from the active list. */
term_timestamps_start = ti;
ti -= term_timestamps_start;
secs = ti / 1000000000;
- snprintf(buf1, sizeof(buf1),
+ snprintf(buf1, sizeof(buf1),
"[%02d:%02d:%02d.%03d] ",
secs / 3600,
(secs / 60) % 60,
tty.c_cflag |= CS8;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 0;
-
+
tcsetattr (0, TCSANOW, &tty);
atexit(term_exit);
struct termios tty;
char slave_name[1024];
int master_fd, slave_fd;
-
+
/* Not satisfying */
if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
return NULL;
}
-
+
/* Disabling local echo and line-buffered output */
tcgetattr (master_fd, &tty);
tty.c_lflag &= ~(ECHO|ICANON|ISIG);
return qemu_chr_open_fd(master_fd, master_fd);
}
-static void tty_serial_init(int fd, int speed,
+static void tty_serial_init(int fd, int speed,
int parity, int data_bits, int stop_bits)
{
struct termios tty;
speed_t spd;
#if 0
- printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
+ printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
speed, parity, data_bits, stop_bits);
#endif
tcgetattr (fd, &tty);
}
if (stop_bits == 2)
tty.c_cflag |= CSTOPB;
-
+
tcsetattr (fd, TCSANOW, &tty);
}
static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
{
FDCharDriver *s = chr->opaque;
-
+
switch(cmd) {
case CHR_IOCTL_SERIAL_SET_PARAMS:
{
QEMUSerialSetParams *ssp = arg;
- tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
+ tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
ssp->data_bits, ssp->stop_bits);
}
break;
COMSTAT comstat;
DWORD size;
DWORD err;
-
+
s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!s->hsend) {
fprintf(stderr, "Failed CreateEvent\n");
s->hcom = NULL;
goto fail;
}
-
+
if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
fprintf(stderr, "Failed SetupComm\n");
goto fail;
}
-
+
ZeroMemory(&comcfg, sizeof(COMMCONFIG));
size = sizeof(COMMCONFIG);
GetDefaultCommConfig(filename, &comcfg, &size);
fprintf(stderr, "Failed SetCommTimeouts\n");
goto fail;
}
-
+
if (!ClearCommError(s->hcom, &err, &comstat)) {
fprintf(stderr, "Failed ClearCommError\n");
goto fail;
int ret, err;
uint8_t buf[1024];
DWORD size;
-
+
ZeroMemory(&s->orecv, sizeof(s->orecv));
s->orecv.hEvent = s->hrecv;
ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
s->len = s->max_size;
if (s->len == 0)
return;
-
+
win_chr_readfile(s);
}
WinCharState *s = opaque;
COMSTAT status;
DWORD comerr;
-
+
ClearCommError(s->hcom, &comerr, &status);
if (status.cbInQue > 0) {
s->len = status.cbInQue;
{
CharDriverState *chr;
WinCharState *s;
-
+
chr = qemu_mallocz(sizeof(CharDriverState));
if (!chr)
return NULL;
int ret;
DWORD size;
char openname[256];
-
+
s->fpipe = TRUE;
s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
fprintf(stderr, "Failed CreateEvent\n");
goto fail;
}
-
+
snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
chr->opaque = s;
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
-
+
if (win_chr_pipe_init(s, filename) < 0) {
free(s);
free(chr);
qemu_chr_reset(chr);
return chr;
}
-
+
static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
{
HANDLE fd_out;
-
+
fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fd_out == INVALID_HANDLE_VALUE)
qemu_free(s);
}
-static CharDriverState *qemu_chr_open_tcp(const char *host_str,
+static CharDriverState *qemu_chr_open_tcp(const char *host_str,
int is_telnet,
int is_unix)
{
else
#endif
fd = socket(PF_INET, SOCK_STREAM, 0);
-
- if (fd < 0)
+
+ if (fd < 0)
goto fail;
if (!is_waitconnect)
val = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
}
-
+
ret = bind(fd, addr, addrlen);
if (ret < 0)
goto fail;
else
qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
}
-
+
if (is_listen && is_waitconnect) {
printf("QEMU waiting for connection on: %s\n", host_str);
tcp_chr_accept(chr);
return text_console_init(&display_state);
} else if (!strcmp(filename, "null")) {
return qemu_chr_open_null();
- } else
+ } else
if (strstart(filename, "tcp:", &p)) {
return qemu_chr_open_tcp(p, 0, 0);
} else
return qemu_chr_open_pty();
} else if (!strcmp(filename, "stdio")) {
return qemu_chr_open_stdio();
- } else
+ } else
#endif
#if defined(__linux__)
if (strstart(filename, "/dev/parport", NULL)) {
return qemu_chr_open_pp(filename);
- } else
+ } else
if (strstart(filename, "/dev/", NULL)) {
return qemu_chr_open_tty(filename);
- } else
+ } else
#endif
#ifdef _WIN32
if (strstart(filename, "COM", NULL)) {
for(i = 0; i < 6; i++) {
macaddr[i] = strtol(p, (char **)&p, 16);
if (i == 5) {
- if (*p != '\0')
+ if (*p != '\0')
return -1;
} else {
- if (*p != ':')
+ if (*p != ':')
return -1;
p++;
}
slirp_inited = 1;
slirp_init();
}
- slirp_vc = qemu_new_vlan_client(vlan,
+ slirp_vc = qemu_new_vlan_client(vlan,
slirp_receive, NULL, NULL);
snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
return 0;
const char *p;
struct in_addr guest_addr;
int host_port, guest_port;
-
+
if (!slirp_inited) {
slirp_inited = 1;
slirp_init();
}
if (!inet_aton(buf, &guest_addr))
goto fail;
-
+
guest_port = strtol(p, &r, 0);
if (r == p)
goto fail;
-
+
if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
fprintf(stderr, "qemu: could not set up redirection\n");
exit(1);
fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
exit(1);
}
-
+
#ifndef _WIN32
char smb_dir[1024];
break;
if (strcmp(de->d_name, ".") != 0 &&
strcmp(de->d_name, "..") != 0) {
- snprintf(filename, sizeof(filename), "%s/%s",
+ snprintf(filename, sizeof(filename), "%s/%s",
smb_dir, de->d_name);
unlink(filename);
}
exit(1);
}
snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
-
+
f = fopen(smb_conf, "w");
if (!f) {
fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
exit(1);
}
- fprintf(f,
+ fprintf(f,
"[global]\n"
"private dir=%s\n"
"smb ports=0\n"
snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
SMBD_COMMAND, smb_conf);
-
+
slirp_add_exec(0, smb_cmdline, 4, 139);
}
{
struct ifreq ifr;
int fd, ret;
-
+
fd = open("/dev/net/tun", O_RDWR);
if (fd < 0) {
fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
s = net_tap_fd_init(vlan, fd);
if (!s)
return -1;
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
+ snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"tap: ifname=%s setup_script=%s", ifname, setup_script);
return 0;
}
static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
{
NetSocketState *s = opaque;
- sendto(s->fd, buf, size, 0,
+ sendto(s->fd, buf, size, 0,
(struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
}
size = recv(s->fd, buf1, sizeof(buf1), 0);
if (size < 0) {
err = socket_error();
- if (err != EWOULDBLOCK)
+ if (err != EWOULDBLOCK)
goto eoc;
} else if (size == 0) {
/* end of connection */
int size;
size = recv(s->fd, s->buf, sizeof(s->buf), 0);
- if (size < 0)
+ if (size < 0)
return;
if (size == 0) {
/* end of connection */
int val, ret;
if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
- inet_ntoa(mcastaddr->sin_addr),
+ inet_ntoa(mcastaddr->sin_addr),
(int)ntohl(mcastaddr->sin_addr.s_addr));
return -1;
}
val = 1;
- ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+ ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
(const char *)&val, sizeof(val));
if (ret < 0) {
perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
perror("bind");
goto fail;
}
-
+
/* Add host to multicast group */
imr.imr_multiaddr = mcastaddr->sin_addr;
imr.imr_interface.s_addr = htonl(INADDR_ANY);
- ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(const char *)&imr, sizeof(struct ip_mreq));
if (ret < 0) {
perror("setsockopt(IP_ADD_MEMBERSHIP)");
/* Force mcast msgs to loopback (eg. several QEMUs in same host */
val = 1;
- ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
+ ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
(const char *)&val, sizeof(val));
if (ret < 0) {
perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
socket_set_nonblock(fd);
return fd;
fail:
- if (fd >= 0)
+ if (fd >= 0)
closesocket(fd);
return -1;
}
-static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
+static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
int is_connected)
{
struct sockaddr_in saddr;
NetSocketState *s;
/* fd passed: multicast: "learn" dgram_dst address from bound address and save it
- * Because this may be "shared" socket from a "master" process, datagrams would be recv()
+ * Because this may be "shared" socket from a "master" process, datagrams would be recv()
* by ONLY ONE process: we must "clone" this dgram socket --jjo
*/
/* clone newfd to fd, close newfd */
dup2(newfd, fd);
close(newfd);
-
+
} else {
fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
fd, strerror(errno));
if (is_connected) s->dgram_dst=saddr;
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: fd=%d (%s mcast=%s:%d)",
+ "socket: fd=%d (%s mcast=%s:%d)",
fd, is_connected? "cloned" : "",
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
return s;
qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
}
-static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
+static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
int is_connected)
{
NetSocketState *s;
if (!s)
return NULL;
s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan,
+ s->vc = qemu_new_vlan_client(vlan,
net_socket_receive, NULL, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"socket: fd=%d", fd);
return s;
}
-static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
+static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
int is_connected)
{
int so_type=-1, optlen=sizeof(so_type);
static void net_socket_accept(void *opaque)
{
- NetSocketListenState *s = opaque;
+ NetSocketListenState *s = opaque;
NetSocketState *s1;
struct sockaddr_in saddr;
socklen_t len;
break;
}
}
- s1 = net_socket_fd_init(s->vlan, fd, 1);
+ s1 = net_socket_fd_init(s->vlan, fd, 1);
if (!s1) {
closesocket(fd);
} else {
snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
- "socket: connection from %s:%d",
+ "socket: connection from %s:%d",
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
}
}
if (parse_host_port(&saddr, host_str) < 0)
return -1;
-
+
s = qemu_mallocz(sizeof(NetSocketListenState));
if (!s)
return -1;
/* allow fast reuse */
val = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
-
+
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret < 0) {
perror("bind");
if (!s)
return -1;
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: connect to %s:%d",
+ "socket: connect to %s:%d",
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
return 0;
}
return -1;
s->dgram_dst = saddr;
-
+
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: mcast=%s:%d",
+ "socket: mcast=%s:%d",
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
return 0;
if (ret < 0) {
fprintf(stderr, "Could not initialize device '%s'\n", device);
}
-
+
return ret;
}
return -1;
p = strchr(devname, '.');
- if (!p)
+ if (!p)
return -1;
bus_num = strtoul(devname, NULL, 0);
addr = strtoul(p + 1, NULL, 0);
{
int ret;
ret = usb_device_add(devname);
- if (ret < 0)
+ if (ret < 0)
term_printf("Could not add USB device '%s'\n", devname);
}
{
int ret;
ret = usb_device_del(devname);
- if (ret < 0)
+ if (ret < 0)
term_printf("Could not remove USB device '%s'\n", devname);
}
if (!dev)
continue;
switch(dev->speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
+ case USB_SPEED_LOW:
+ speed_str = "1.5";
break;
- case USB_SPEED_FULL:
- speed_str = "12";
+ case USB_SPEED_FULL:
+ speed_str = "12";
break;
- case USB_SPEED_HIGH:
- speed_str = "480";
+ case USB_SPEED_HIGH:
+ speed_str = "480";
break;
default:
- speed_str = "?";
+ speed_str = "?";
break;
}
- term_printf(" Device %d.%d, Speed %s Mb/s, Product %s\n",
+ term_printf(" Device %d.%d, Speed %s Mb/s, Product %s\n",
0, dev->addr, speed_str, dev->devname);
}
}
/* Remove PID file. Called on normal exit */
-static void remove_pidfile(void)
+static void remove_pidfile(void)
{
unlink (pid_filename);
}
atexit(remove_pidfile);
}
} else {
- fprintf(stderr, "%s already exists. Remove it and try again.\n",
+ fprintf(stderr, "%s already exists. Remove it and try again.\n",
filename);
exit(1);
}
/* XXX: fd_read_poll should be suppressed, but an API change is
necessary in the character devices to suppress fd_can_read(). */
-int qemu_set_fd_handler2(int fd,
- IOCanRWHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
+int qemu_set_fd_handler2(int fd,
+ IOCanRWHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
void *opaque)
{
IOHandlerRecord **pioh, *ioh;
return 0;
}
-int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
- IOHandler *fd_write,
+int qemu_set_fd_handler(int fd,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
void *opaque)
{
return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
} WaitObjects;
static WaitObjects wait_objects = {0};
-
+
int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
{
WaitObjects *w = &wait_objects;
w->events[i] = w->events[i + 1];
w->func[i] = w->func[i + 1];
w->opaque[i] = w->opaque[i + 1];
- }
+ }
}
if (found)
w->num--;
fseek(f->outfile, f->buf_offset, SEEK_SET);
fwrite(f->buf, 1, f->buf_index, f->outfile);
} else {
- bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
+ bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
f->buf, f->buf_index);
}
f->buf_offset += f->buf_index;
if (len < 0)
len = 0;
} else {
- len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
+ len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
f->buf, IO_BUF_SIZE);
if (len < 0)
len = 0;
static SaveStateEntry *first_se;
-int register_savevm(const char *idstr,
- int instance_id,
+int register_savevm(const char *idstr,
+ int instance_id,
int version_id,
SaveStateHandler *save_state,
LoadStateHandler *load_state,
/* record size: filled later */
len_pos = qemu_ftell(f);
qemu_put_be32(f, 0);
-
+
se->save_state(f, se->opaque);
/* fill record size */
SaveStateEntry *se;
for(se = first_se; se != NULL; se = se->next) {
- if (!strcmp(se->idstr, idstr) &&
+ if (!strcmp(se->idstr, idstr) &&
instance_id == se->instance_id)
return se;
}
int64_t total_len, end_pos, cur_pos;
unsigned int v;
char idstr[256];
-
+
v = qemu_get_be32(f);
if (v != QEMU_VM_FILE_MAGIC)
goto fail;
version_id = qemu_get_be32(f);
record_len = qemu_get_be32(f);
#if 0
- printf("idstr=%s instance=0x%x version=%d len=%d\n",
+ printf("idstr=%s instance=0x%x version=%d len=%d\n",
idstr, instance_id, version_id, record_len);
#endif
cur_pos = qemu_ftell(f);
se = find_se(idstr, instance_id);
if (!se) {
- fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
+ fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
instance_id, idstr);
} else {
ret = se->load_state(f, se->opaque, version_id);
if (ret < 0) {
- fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
+ fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
instance_id, idstr);
}
}
{
QEMUSnapshotInfo *sn_tab, *sn;
int nb_sns, i, ret;
-
+
ret = -ENOENT;
nb_sns = bdrv_snapshot_list(bs, &sn_tab);
if (nb_sns < 0)
saved_vm_running = vm_running;
vm_stop(0);
-
+
must_delete = 0;
if (name) {
ret = bdrv_snapshot_find(bs, old_sn, name);
sn->date_nsec = tv.tv_usec * 1000;
#endif
sn->vm_clock_nsec = qemu_get_clock(vm_clock);
-
+
if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
term_printf("Device %s does not support VM state snapshots\n",
bdrv_get_device_name(bs));
goto the_end;
}
-
+
/* save the VM state */
f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
if (!f) {
term_printf("Error %d while writing VM\n", ret);
goto the_end;
}
-
+
/* create the snapshots */
for(i = 0; i < MAX_DISKS; i++) {
term_printf("No block device supports snapshots\n");
return;
}
-
+
/* Flush all IO requests so they don't interfere with the new state. */
qemu_aio_flush();
bdrv_get_device_name(bs));
return;
}
-
+
/* restore the VM state */
f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
if (!f) {
term_printf("No block device supports snapshots\n");
return;
}
-
+
for(i = 0; i <= MAX_DISKS; i++) {
bs1 = bs_table[i];
if (bdrv_has_snapshot(bs1)) {
uint16_t fptag, fpus, fpuc, fpregs_format;
uint32_t hflags;
int i;
-
+
for(i = 0; i < CPU_NB_REGS; i++)
qemu_put_betls(f, &env->regs[i]);
qemu_put_betls(f, &env->eip);
qemu_put_betls(f, &env->eflags);
hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
qemu_put_be32s(f, &hflags);
-
+
/* FPU */
fpuc = env->fpuc;
fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
for(i = 0; i < 8; i++) {
fptag |= ((!env->fptags[i]) << i);
}
-
+
qemu_put_be16s(f, &fpuc);
qemu_put_be16s(f, &fpus);
qemu_put_be16s(f, &fptag);
fpregs_format = 1;
#endif
qemu_put_be16s(f, &fpregs_format);
-
+
for(i = 0; i < 8; i++) {
#ifdef USE_X86LDOUBLE
{
cpu_put_seg(f, &env->tr);
cpu_put_seg(f, &env->gdt);
cpu_put_seg(f, &env->idt);
-
+
qemu_put_be32s(f, &env->sysenter_cs);
qemu_put_be32s(f, &env->sysenter_esp);
qemu_put_be32s(f, &env->sysenter_eip);
-
+
qemu_put_betls(f, &env->cr[0]);
qemu_put_betls(f, &env->cr[2]);
qemu_put_betls(f, &env->cr[3]);
qemu_put_betls(f, &env->cr[4]);
-
+
for(i = 0; i < 8; i++)
qemu_put_betls(f, &env->dr[i]);
qemu_get_be16s(f, &fpus);
qemu_get_be16s(f, &fptag);
qemu_get_be16s(f, &fpregs_format);
-
+
/* NOTE: we cannot always restore the FPU state if the image come
from a host with a different 'USE_X86LDOUBLE' define. We guess
if we are in an MMX state to restore correctly in that case. */
for(i = 0; i < 8; i++) {
uint64_t mant;
uint16_t exp;
-
+
switch(fpregs_format) {
case 0:
mant = qemu_get_be64(f);
}
#else
env->fpregs[i].mmx.MMX_Q(0) = mant;
-#endif
+#endif
break;
default:
return -EINVAL;
for(i = 0; i < 8; i++) {
env->fptags[i] = (fptag >> i) & 1;
}
-
+
for(i = 0; i < 6; i++)
cpu_get_seg(f, &env->segs[i]);
cpu_get_seg(f, &env->ldt);
cpu_get_seg(f, &env->tr);
cpu_get_seg(f, &env->gdt);
cpu_get_seg(f, &env->idt);
-
+
qemu_get_be32s(f, &env->sysenter_cs);
qemu_get_be32s(f, &env->sysenter_esp);
qemu_get_be32s(f, &env->sysenter_eip);
-
+
qemu_get_betls(f, &env->cr[0]);
qemu_get_betls(f, &env->cr[2]);
qemu_get_betls(f, &env->cr[3]);
qemu_get_betls(f, &env->cr[4]);
-
+
for(i = 0; i < 8; i++)
qemu_get_betls(f, &env->dr[i]);
qemu_get_be64s(f, &env->fmask);
qemu_get_be64s(f, &env->kernelgsbase);
#endif
- if (version_id >= 4)
+ if (version_id >= 4)
qemu_get_be32s(f, &env->smbase);
/* XXX: compute hflags from scratch, except for CPL and IIF */
memset(s, 0, sizeof(*s));
s->f = f;
ret = deflateInit2(&s->zstream, 1,
- Z_DEFLATED, 15,
+ Z_DEFLATED, 15,
9, Z_DEFAULT_STRATEGY);
if (ret != Z_OK)
return -1;
int i;
RamCompressState s1, *s = &s1;
uint8_t buf[10];
-
+
qemu_put_be32(f, phys_ram_size);
if (ram_compress_open(s, f) < 0)
return;
sector_num = -1;
for(j = 0; j < MAX_DISKS; j++) {
if (bs_table[j]) {
- sector_num = bdrv_hash_find(bs_table[j],
+ sector_num = bdrv_hash_find(bs_table[j],
phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
if (sector_num >= 0)
break;
buf[1] = j;
cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
ram_compress_buf(s, buf, 10);
- } else
+ } else
#endif
{
// normal_compress:
fprintf(stderr, "Error while reading ram block address=0x%08x", i);
goto error;
}
- } else
+ } else
#if 0
if (buf[0] == 1) {
int bs_index;
fprintf(stderr, "Invalid block device index %d\n", bs_index);
goto error;
}
- if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i,
+ if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i,
BDRV_HASH_BLOCK_SIZE / 512) < 0) {
- fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
+ fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
bs_index, sector_num);
goto error;
}
- } else
+ } else
#endif
{
error:
}
}
-void vm_stop(int reason)
+void vm_stop(int reason)
{
if (vm_running) {
cpu_disable_ticks();
if (ret == 0 && timeout > 0) {
int err;
WaitObjects *w = &wait_objects;
-
+
ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
if (w->func[ret - WAIT_OBJECT_0])
nfds = ioh->fd;
}
}
-
+
tv.tv_sec = 0;
#ifdef _WIN32
tv.tv_usec = 0;
qemu_bh_poll();
if (vm_running) {
- qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
+ qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
qemu_get_clock(vm_clock));
/* run dma transfers, if any */
DMA_run();
}
-
+
/* real time timers */
- qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
+ qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
qemu_get_clock(rt_clock));
}
if (bs && bdrv_is_encrypted(bs)) {
term_printf("%s is encrypted.\n", bdrv_get_device_name(bs));
for(j = 0; j < 3; j++) {
- monitor_readline("Password: ",
+ monitor_readline("Password: ",
1, password, sizeof(password));
if (bdrv_set_key(bs, password) == 0)
break;
for(i = 1; i < MAX_SERIAL_PORTS; i++)
serial_devices[i][0] = '\0';
serial_device_index = 0;
-
+
pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
for(i = 1; i < MAX_PARALLEL_PORTS; i++)
parallel_devices[i][0] = '\0';
parallel_device_index = 0;
-
+
usb_devices_index = 0;
-
+
nb_net_clients = 0;
nb_nics = 0;
/* default mac address of the first network interface */
-
+
optind = 1;
for(;;) {
if (optind >= argc)
popt = qemu_options;
for(;;) {
if (!popt->name) {
- fprintf(stderr, "%s: invalid option -- '%s'\n",
+ fprintf(stderr, "%s: invalid option -- '%s'\n",
argv[0], r);
exit(1);
}
printf("Supported machines are:\n");
for(m = first_machine; m != NULL; m = m->next) {
printf("%-10s %s%s\n",
- m->name, m->desc,
+ m->name, m->desc,
m == first_machine ? " (default)" : "");
}
exit(1);
break;
case QEMU_OPTION_boot:
boot_device = optarg[0];
- if (boot_device != 'a' &&
+ if (boot_device != 'a' &&
#if defined(TARGET_SPARC) || defined(TARGET_I386)
// Network boot
boot_device != 'n' &&
break;
#endif
case QEMU_OPTION_redir:
- net_slirp_redir(optarg);
+ net_slirp_redir(optarg);
break;
#endif
#ifdef HAS_AUDIO
{
int mask;
CPULogItem *item;
-
+
mask = cpu_str_to_log_mask(optarg);
if (!mask) {
printf("Log items (comma separated):\n");
if (*p == 'x') {
p++;
depth = strtol(p, (char **)&p, 10);
- if (depth != 8 && depth != 15 && depth != 16 &&
+ if (depth != 8 && depth != 15 && depth != 16 &&
depth != 24 && depth != 32)
goto graphic_error;
} else if (*p == '\0') {
} else {
goto graphic_error;
}
-
+
graphic_width = w;
graphic_height = h;
graphic_depth = depth;
fprintf(stderr, "qemu: too many serial ports\n");
exit(1);
}
- pstrcpy(serial_devices[serial_device_index],
+ pstrcpy(serial_devices[serial_device_index],
sizeof(serial_devices[0]), optarg);
serial_device_index++;
break;
fprintf(stderr, "qemu: too many parallel ports\n");
exit(1);
}
- pstrcpy(parallel_devices[parallel_device_index],
+ pstrcpy(parallel_devices[parallel_device_index],
sizeof(parallel_devices[0]), optarg);
parallel_device_index++;
break;
len = read(fds[0], &status, 1);
if (len == -1 && (errno == EINTR))
goto again;
-
+
if (len != 1 || status != 0)
exit(1);
else
linux_boot = (kernel_filename != NULL);
if (!linux_boot &&
- hd_filename[0] == '\0' &&
+ hd_filename[0] == '\0' &&
(cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
fd_filename[0] == '\0')
help();
}
setvbuf(stdout, NULL, _IOLBF, 0);
-
+
init_timers();
init_timer_alarm();
qemu_aio_init();
if (devname[0] != '\0' && strcmp(devname, "none")) {
serial_hds[i] = qemu_chr_open(devname);
if (!serial_hds[i]) {
- fprintf(stderr, "qemu: could not open serial device '%s'\n",
+ fprintf(stderr, "qemu: could not open serial device '%s'\n",
devname);
exit(1);
}
if (devname[0] != '\0' && strcmp(devname, "none")) {
parallel_hds[i] = qemu_chr_open(devname);
if (!parallel_hds[i]) {
- fprintf(stderr, "qemu: could not open parallel device '%s'\n",
+ fprintf(stderr, "qemu: could not open parallel device '%s'\n",
devname);
exit(1);
}
gdbstub_port);
exit(1);
}
- } else
+ } else
#endif
if (loadvm)
do_loadvm(loadvm);
/*
* QEMU System Emulator header
- *
+ *
* Copyright (c) 2003 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
typedef int IOCanRWHandler(void *opaque);
typedef void IOHandler(void *opaque);
-int qemu_set_fd_handler2(int fd,
- IOCanRWHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
+int qemu_set_fd_handler2(int fd,
+ IOCanRWHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
void *opaque);
int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
+ IOHandler *fd_read,
IOHandler *fd_write,
void *opaque);
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
void qemu_chr_send_event(CharDriverState *s, int event);
-void qemu_chr_add_handlers(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
+void qemu_chr_add_handlers(CharDriverState *s,
+ IOCanRWHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
void *opaque);
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 register_savevm(const char *idstr,
+ int instance_id,
int version_id,
SaveStateHandler *save_state,
LoadStateHandler *load_state,
typedef struct BlockDriverInfo {
/* in bytes, 0 if irrelevant */
- int cluster_size;
+ int cluster_size;
/* offset at which the VM state can be saved (0 if not possible) */
- int64_t vm_state_offset;
+ int64_t vm_state_offset;
} BlockDriverInfo;
typedef struct QEMUSnapshotInfo {
void bdrv_init(void);
BlockDriver *bdrv_find_format(const char *format_name);
-int bdrv_create(BlockDriver *drv,
+int bdrv_create(BlockDriver *drv,
const char *filename, int64_t size_in_sectors,
const char *backing_file, int flags);
BlockDriverState *bdrv_new(const char *device_name);
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
BlockDriver *drv);
void bdrv_close(BlockDriverState *bs);
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
+int bdrv_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors);
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
+int bdrv_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
+int bdrv_pread(BlockDriverState *bs, int64_t offset,
void *buf, int count);
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
+int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
const void *buf, int count);
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
int64_t bdrv_getlength(BlockDriverState *bs);
#define BIOS_ATA_TRANSLATION_LARGE 3
#define BIOS_ATA_TRANSLATION_RECHS 4
-void bdrv_set_geometry_hint(BlockDriverState *bs,
+void bdrv_set_geometry_hint(BlockDriverState *bs,
int cyls, int heads, int secs);
void bdrv_set_type_hint(BlockDriverState *bs, int type);
void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
-void bdrv_get_geometry_hint(BlockDriverState *bs,
+void bdrv_get_geometry_hint(BlockDriverState *bs,
int *pcyls, int *pheads, int *psecs);
int bdrv_get_type_hint(BlockDriverState *bs);
int bdrv_get_translation_hint(BlockDriverState *bs);
int bdrv_is_locked(BlockDriverState *bs);
void bdrv_set_locked(BlockDriverState *bs, int locked);
void bdrv_eject(BlockDriverState *bs, int eject_flag);
-void bdrv_set_change_cb(BlockDriverState *bs,
+void bdrv_set_change_cb(BlockDriverState *bs,
void (*change_cb)(void *opaque), void *opaque);
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
void bdrv_info(void);
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
int bdrv_is_encrypted(BlockDriverState *bs);
int bdrv_set_key(BlockDriverState *bs, const char *key);
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
+void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
void *opaque);
const char *bdrv_get_device_name(BlockDriverState *bs);
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
+int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
-void bdrv_get_backing_filename(BlockDriverState *bs,
+void bdrv_get_backing_filename(BlockDriverState *bs,
char *filename, int filename_size);
-int bdrv_snapshot_create(BlockDriverState *bs,
+int bdrv_snapshot_create(BlockDriverState *bs,
QEMUSnapshotInfo *sn_info);
-int bdrv_snapshot_goto(BlockDriverState *bs,
+int bdrv_snapshot_goto(BlockDriverState *bs,
const char *snapshot_id);
int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
-int bdrv_snapshot_list(BlockDriverState *bs,
+int bdrv_snapshot_list(BlockDriverState *bs,
QEMUSnapshotInfo **psn_info);
char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
#ifndef QEMU_TOOL
-typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size,
+typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size,
int boot_device,
DisplayState *ds, const char **fd_filename, int snapshot,
const char *kernel_filename, const char *kernel_cmdline,
typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
-int register_ioport_read(int start, int length, int size,
+int register_ioport_read(int start, int length, int size,
IOPortReadFunc *func, void *opaque);
-int register_ioport_write(int start, int length, int size,
+int register_ioport_write(int start, int length, int size,
IOPortWriteFunc *func, void *opaque);
void isa_unassign_ioport(int start, int length);
typedef struct PCIBus PCIBus;
typedef struct PCIDevice PCIDevice;
-typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
+typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
uint32_t address, uint32_t data, int len);
-typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
+typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
uint32_t address, int len);
-typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
+typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type);
#define PCI_ADDRESS_SPACE_MEM 0x00
int devfn;
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
-
+
/* do not access the following fields */
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
+ PCIConfigReadFunc *config_read,
PCIConfigWriteFunc *config_write);
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
+void pci_register_io_region(PCIDevice *pci_dev, int region_num,
+ uint32_t size, int type,
PCIMapIORegionFunc *map_func);
void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level);
-uint32_t pci_default_read_config(PCIDevice *d,
+uint32_t pci_default_read_config(PCIDevice *d,
uint32_t address, int len);
-void pci_default_write_config(PCIDevice *d,
+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);
s->dpy_resize(s, w, h);
}
-int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
+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,
+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);
/* cirrus_vga.c */
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
+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,
+void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size);
/* sdl.c */
typedef struct fdctrl_t fdctrl_t;
-fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
+fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
uint32_t io_base,
BlockDriverState **fds);
int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
void *sparc32_dma_init(uint32_t daddr, int espirq, int leirq, void *iommu,
void *intctl);
void ledma_set_irq(void *opaque, int isr);
-void ledma_memory_read(void *opaque, target_phys_addr_t addr,
+void ledma_memory_read(void *opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap);
-void ledma_memory_write(void *opaque, target_phys_addr_t addr,
+void ledma_memory_write(void *opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap);
void espdma_raise_irq(void *opaque);
void espdma_clear_irq(void *opaque);
const uint8_t *buf, int len);
int adb_poll(ADBBusState *s, uint8_t *buf_out);
-ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
- ADBDeviceRequest *devreq,
- ADBDeviceReset *devreset,
+ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
+ ADBDeviceRequest *devreq,
+ ADBDeviceReset *devreset,
void *opaque);
void adb_kbd_init(ADBBusState *bus);
void adb_mouse_init(ADBBusState *bus);
pflash_t *pflash_register (target_ulong base, ram_addr_t off,
BlockDriverState *bs,
target_ulong sector_len, int nb_blocs, int width,
- uint16_t id0, uint16_t id1,
+ uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3);
#include "gdbstub.h"
/*
* QEMU VNC display driver
- *
+ *
* Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
* 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
typedef void VncSendHextileTile(VncState *vs,
int x, int y, int w, int h,
- uint32_t *last_bg,
+ uint32_t *last_bg,
uint32_t *last_fg,
int *has_bg, int *has_fg);
d[j++] = -1;
n -= 32;
}
- if (n > 0)
+ if (n > 0)
d[j++] = (1 << n) - 1;
while (j < nb_words)
d[j++] = 0;
return (d[k >> 5] >> (k & 0x1f)) & 1;
}
-static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
+static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
int nb_words)
{
int i;
r = (v >> vs->red_shift1) & vs->red_max;
g = (v >> vs->green_shift1) & vs->green_max;
b = (v >> vs->blue_shift1) & vs->blue_max;
- v = (r << vs->red_shift) |
- (g << vs->green_shift) |
+ v = (r << vs->red_shift) |
+ (g << vs->green_shift) |
(b << vs->blue_shift);
switch(vs->pix_bpp) {
case 1:
has_fg = has_bg = 0;
for (j = y; j < (y + h); j += 16) {
for (i = x; i < (x + w); i += 16) {
- vs->send_hextile_tile(vs, i, j,
+ vs->send_hextile_tile(vs, i, j,
MIN(16, x + w - i), MIN(16, y + h - j),
&last_bg32, &last_fg32, &has_bg, &has_fg);
}
int keycode;
keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
-
+
/* QEMU console switch */
switch(keycode) {
case 0x2a: /* Left Shift */
else
vs->modifiers_state[keycode] = 0;
break;
- case 0x02 ... 0x0a: /* '1' to '9' keys */
+ case 0x02 ... 0x0a: /* '1' to '9' keys */
if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
/* Reset the modifiers sent to the current console */
reset_keys(vs);
char *old_row = vs->old_data + y_position * vs->ds->linesize;
for (i = 0; i < h; i++) {
- vnc_set_bits(vs->dirty_row[y_position + i],
+ vnc_set_bits(vs->dirty_row[y_position + i],
(vs->ds->width / 16), VNC_DIRTY_WORDS);
memset(old_row, 42, vs->ds->width * vs->depth);
old_row += vs->ds->linesize;
vnc_client_error(vs);
return;
}
- if (bits_per_pixel == 32 &&
+ if (bits_per_pixel == 32 &&
host_big_endian_flag == big_endian_flag &&
red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
red_shift == 16 && green_shift == 8 && blue_shift == 0) {
vs->depth = 4;
vs->write_pixels = vnc_write_pixels_copy;
vs->send_hextile_tile = send_hextile_tile_32;
- } else
- if (bits_per_pixel == 16 &&
+ } else
+ if (bits_per_pixel == 16 &&
host_big_endian_flag == big_endian_flag &&
red_max == 31 && green_max == 63 && blue_max == 31 &&
red_shift == 11 && green_shift == 5 && blue_shift == 0) {
vs->depth = 2;
vs->write_pixels = vnc_write_pixels_copy;
vs->send_hextile_tile = send_hextile_tile_16;
- } else
- if (bits_per_pixel == 8 &&
+ } else
+ if (bits_per_pixel == 8 &&
red_max == 7 && green_max == 7 && blue_max == 3 &&
red_shift == 5 && green_shift == 2 && blue_shift == 0) {
vs->depth = 1;
vs->write_pixels = vnc_write_pixels_copy;
vs->send_hextile_tile = send_hextile_tile_8;
- } else
+ } else
{
/* generic and slower case */
if (bits_per_pixel != 8 &&
vnc_client_error(vs);
break;
}
-
+
vnc_read_when(vs, protocol_client_msg, 1);
return 0;
}
vs->send_hextile_tile = send_hextile_tile_8;
}
vs->write_pixels = vnc_write_pixels_copy;
-
+
vnc_write(vs, pad, 3); /* padding */
- vnc_write_u32(vs, 4);
+ vnc_write_u32(vs, 4);
vnc_write(vs, "QEMU", 4);
vnc_flush(vs);
fprintf(stderr, "Could not parse VNC address\n");
exit(1);
}
-
+
iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
reuse_addr = 1;
static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
int x, int y, int w, int h,
- uint32_t *last_bg32,
+ uint32_t *last_bg32,
uint32_t *last_fg32,
int *has_bg, int *has_fg)
{
flags |= 0x08;
irow = (pixel_t *)row;
-
+
for (j = 0; j < h; j++) {
int min_x = -1;
for (i = 0; i < w; i++) {