(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)
- 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)
- 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.
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);
- }
+ }
}
}
};
/* 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"},
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);
}
{
/* 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);
}
}
}
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)
{
{
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++)
{
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;
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,
}
ts->heap_limit = limit;
}
-
+
ptr = lock_user(ARG(0), 16, 0);
ptr[0] = tswap32(ts->heap_base);
ptr[1] = tswap32(ts->heap_limit);
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;
}
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)
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),
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),
{
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);
{
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)
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;
}
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)
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)
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)
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;
inflateEnd(strm);
return 0;
}
-
+
static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
{
int ret, csize;
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);
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;
qemu_aio_release(acb);
return;
}
-
+
/* prepare next AIO request */
acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
0, 0, 0, 0);
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)
{
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) {
return -1;
}
}
-
+
qemu_free(out_buf);
return 0;
}
- 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.
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_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 ||
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)
/* 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),
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 */
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);
inflateEnd(strm);
return 0;
}
-
+
static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
{
int ret, csize, nb_csectors, sector_offset;
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);
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;
qemu_aio_release(acb);
return;
}
-
+
/* prepare next AIO request */
acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
0, 0, 0, 0);
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)
{
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;
}
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;
return -1;
}
}
-
+
qemu_free(out_buf);
return 0;
}
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;
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)
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;
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') {
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;
{
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;
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);
BDRVQcowState *s = bs->opaque;
int64_t start, last, cluster_offset;
int k;
-
+
if (size <= 0)
return;
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)
/* 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);
{
BDRVRawState *s = bs->opaque;
int ret;
-
+
ret = fd_open(bs);
if (ret < 0)
return ret;
{
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;
raw_close,
raw_create,
raw_flush,
-
+
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
if ( KERN_SUCCESS != kernResult ) {
printf( "IOMasterPort returned %d\n", kernResult );
}
-
+
classesToMatch = IOServiceMatching( kIOCDMediaClass );
if ( classesToMatch == NULL ) {
printf( "IOServiceMatching returned a NULL dictionary.\n" );
{
printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
}
-
+
return kernResult;
}
}
IOObjectRelease( nextMedia );
}
-
+
return kernResult;
}
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 );
}
raw_close,
NULL,
raw_flush,
-
+
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
.bdrv_aio_cancel = raw_aio_cancel,
OVERLAPPED ov;
DWORD ret_count;
int ret;
-
+
memset(&ov, 0, sizeof(ov));
ov.Offset = offset;
ov.OffsetHigh = offset >> 32;
OVERLAPPED ov;
DWORD ret_count;
int ret;
-
+
memset(&ov, 0, sizeof(ov));
ov.Offset = offset;
ov.OffsetHigh = offset >> 32;
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 {
raw_close,
NULL,
raw_flush,
-
+
#if 0
.bdrv_aio_read = raw_aio_read,
.bdrv_aio_write = raw_aio_write,
#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
fail_gd:
qemu_free(gd_buf);
- fail_rgd:
+ fail_rgd:
qemu_free(rgd_buf);
fail:
close(p_fd);
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),
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;
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);
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);
for(j = i - 1; j>0 && filename[j]!='.';j--);
if (j > 0)
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];
mapping->end = mapping->begin;
return -1;
}
-
+
i = mapping->info.dir.first_dir_index =
first_cluster == 0 ? 0 : s->directory.next;
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));
s->qcow_filename = NULL;
s->fat2 = NULL;
s->downcase_short_names = 1;
-
+
if (!strstart(dirname, "fat:", NULL))
return -1;
} else
/* new directory */
schedule_mkdir(s, cluster_num, strdup(path));
-
+
lfn_init(&lfn);
do {
int i;
mapping = next_mapping;
}
-
+
cluster = c1;
}
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) &&
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))
}
}
#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[PATH_MAX];
char backing_filename[PATH_MAX];
-
+
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 (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;
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;
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);
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;
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 ] ) );
{
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;
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
+ 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
+ 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
+ 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
+ 232 // 0xe8 E0, 68 WWW Stop
231 // 0xe7 E0, 67 WWW Refresh
- 230 // 0xe6 E0, 66 WWW Favorites
+ 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];
}
}
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
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];
}
{
uint8_t *d, *d1;
int x, y, bpp;
-
+
bpp = (ds->depth + 7) >> 3;
d1 = ds->data +
ds->linesize * posy + bpp * posx;
{
TextConsole *s;
int i, y1;
-
+
s = active_console;
if (!s || (s->console_type == GRAPHIC_CONSOLE))
return;
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;
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;
for(j = 0; j < 2; j++) {
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->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;
#if defined(__sparc__) && !defined(HOST_SOLARIS)
/* 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 (interrupt_request & CPU_INTERRUPT_DEBUG) {
#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. */
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;
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
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 */
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.gregs[R15];
/* XXX: compute is_write */
is_write = 0;
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.gregs[16];
/* XXX: compute is_write */
is_write = 0;
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.psw.addr;
/* XXX: compute is_write */
is_write = 0;
struct ucontext *uc = puc;
greg_t pc = uc->uc_mcontext.pc;
int is_write;
-
+
/* XXX: compute is_write */
is_write = 0;
return handle_cpu_signal(pc, (unsigned long)info->si_addr,
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));
#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
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;
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++) {
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 */
ElfW(Sym) *sym;
char *shstr;
ELF_RELOC *rel;
-
+
fd = open(filename, O_RDONLY);
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;
}
);
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 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);
-
+
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);
if ( sym->n_type & N_STAB ) /* Debug symbols are ignored */
return "debug";
-
+
if(!name)
return name;
if(name[0]=='_')
{
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];
/* 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]);
unsigned int i, j;
EXE_SYM *sym;
struct nlist *syment;
-
+
fd = open(filename, O_RDONLY);
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);
/* 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");
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))
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;
}
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)
}
}
}
-
+
nb_args = 0;
while (nb_args < MAX_ARGS && args_present[nb_args])
nb_args++;
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
}
}
}
-#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));
n, reloc_offset);
continue;
}
-
+
get_reloc_expr(relname, sizeof(relname), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = rel->r_addend;
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. ]
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");
}
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;
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];
typedef void (GenOpFunc1)(long);
typedef void (GenOpFunc2)(long, long);
typedef void (GenOpFunc3)(long, long, long);
-
+
#if defined(TARGET_I386)
void optimize_flags_init(void);
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__("swp %0, %1, [%2]"
: "=r"(ret)
: "0"(1), "r"(spinlock));
-
+
return ret;
}
#elif defined(__mc68000)
{
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,
PROT_READ | PROT_WRITE | PROT_EXEC);
}
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);
{
int n, tb_start, tb_end;
TranslationBlock *tb;
-
+
p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8);
if (!p->code_bitmap)
return;
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
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,
env->mem_write_pc, NULL);
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)
}
*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
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)
{
/* 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;
}
}
}
-
+
/* since each CPU stores ram addresses in its TLB cache, we must
reset the modified entries */
/* XXX: slow ! */
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);
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 &&
!(pd & IO_MEM_ROMD)) {
/* I/O case */
} else {
pd = p->phys_offset;
}
-
+
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
!(pd & IO_MEM_ROMD)) {
/* I/O case */
} 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 {
pd = p->phys_offset;
}
-
+
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
#ifdef TARGET_WORDS_BIGENDIAN
} 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);
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;
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++)
uint8_t mem_buf[2000];
uint32_t *registers;
target_ulong addr, len;
-
+
#ifdef DEBUG_GDB
printf("command='%s'\n", line_buf);
#endif
/* 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 */
{
int sci_level, pmsts;
int64_t expire_time;
-
+
pmsts = get_pmsts(s);
sci_level = (((pmsts & s->pmen) &
(RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
{
PIIX4PMState *s = opaque;
uint32_t val;
-
+
addr &= 1;
if (addr == 0) {
val = s->apmc;
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);
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;
}
}
*paddr = (pfn << page_bits) | (vaddr & page_mask);
-
+
return 0;
}
foreach_apic(apic_iter, deliver_bitmask,
apic_init_ipi(apic_iter) );
return;
-
+
case APIC_DM_EXTINT:
/* handled in I/O APIC code */
break;
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)
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) >>
s->count_shift;
register_savevm("apic", s->id, 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,
vector, polarity, trig_mode);
register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
qemu_register_reset(ioapic_reset, s);
-
+
return s;
}
{
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 */
} PCICirrusVGAState;
static uint8_t rop_to_index[256];
-
+
/***************************************
*
* prototypes.
{
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);
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) |
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))
return;
/* fast test to see if the cursor intersects with the scan line */
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;
unsigned mode;
addr &= s->cirrus_addr_mask;
-
+
if (((s->sr[0x17] & 0x44) == 0x44) &&
((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
/* memory-mapped I/O */
} else if (s->gr[0x0B] & 0x02) {
goto generic_io;
}
-
+
mode = s->gr[0x05] & 0x7;
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
CirrusVGAState *s;
s = qemu_mallocz(sizeof(CirrusVGAState));
-
+
vga_common_init((VGAState *)s,
ds, vga_ram_base, vga_ram_offset, vga_ram_size);
cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
uint8_t *pci_conf;
CirrusVGAState *s;
int device_id;
-
+
device_id = CIRRUS_ID_CLGD5446;
/* setup PCI configuration registers */
#define PUTPIXEL() ROP_OP(((uint32_t *)d)[0], col)
#else
#error unsupported DEPTH
-#endif
+#endif
static void
glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
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;
counter = (d - (s->counter_value + 1)) % (s->latch + 2);
counter = (s->latch - counter) & 0xffff;
}
-
+
/* Note: we consider the irq is raised on 0 */
if (counter == 0xffff) {
next_time = d + s->latch + 1;
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 int esp_load(QEMUFile *f, void *opaque, int version_id)
{
ESPState *s = opaque;
-
+
if (version_id != 3)
return -EINVAL; // Cannot emulate 2
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
/* Update IO mapping */
if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD])
{
- /* Unmap old IO address */
+ /* Unmap old IO address */
if (s->PCI0IO_length)
{
- cpu_register_physical_memory(s->PCI0IO_start, s->PCI0IO_length, IO_MEM_UNASSIGNED);
+ cpu_register_physical_memory(s->PCI0IO_start, s->PCI0IO_length, IO_MEM_UNASSIGNED);
}
/* Map new IO address */
s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21;
HeathrowPIC *pic;
unsigned int n;
uint32_t value;
-
+
n = ((addr & 0xfff) - 0x10) >> 4;
if (n >= 2) {
value = 0;
qemu_irq *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;
PITState *pit = opaque;
int ret, count;
PITChannelState *s;
-
+
addr &= 3;
s = &pit->channels[addr];
if (s->status_latched) {
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;
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,
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;
uint8_t cmd;
uint8_t status;
uint32_t addr;
-
+
struct PCIIDEState *pci_dev;
/* current transfer state */
uint32_t cur_addr;
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 */
ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
}
ide_set_sector(s, sector_num + n);
-
+
bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
ide_sector_write_aio_cb, bm);
}
bm->aiocb = NULL;
return;
}
-
+
s->io_buffer_index = 0;
if (s->cd_sector_size == 2352) {
n = 1;
buf[9] = 0x12;
buf[10] = 0x08;
buf[11] = 0x00;
-
+
buf[12] = 0x70;
buf[13] = 3 << 5;
buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
int start, eject;
start = packet[4] & 1;
eject = (packet[4] >> 1) & 1;
-
+
if (eject && !start) {
/* eject the disk */
bdrv_eject(s->bs, 1);
IDEState *s = ((IDEState *)opaque)->cur_drive;
uint8_t *p;
int ret;
-
+
p = s->data_ptr;
ret = cpu_to_le32(*(uint32_t *)p);
p += 4;
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, irq);
ide_init_ioport(ide_state, iobase, iobase2);
}
BMDMAState *bm = opaque;
PCIIDEState *pci_dev;
uint32_t val;
-
+
switch(addr & 3) {
case 0:
val = bm->cmd;
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_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;
{
PCIIDEState *d;
uint8_t *pci_conf;
-
+
/* register a function 1 of PIIX3 */
d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
sizeof(PCIIDEState),
ide_if = qemu_mallocz(sizeof(IDEState) * 2);
ide_init2(&ide_if[0], hd_table[0], hd_table[1], irq);
-
+
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
pmac_ide_write, &ide_if[0]);
return pmac_ide_memory;
{
IOMMUState *s = opaque;
int i;
-
+
for (i = 0; i < IOMMU_NREGS; i++)
qemu_put_be32s(f, &s->regs[i]);
qemu_put_be64s(f, &s->iostart);
{
IOMMUState *s = opaque;
int i;
-
+
if (version_id != 2)
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, 2, iommu_save, iommu_load, s);
qemu_register_reset(iommu_reset, s);
return s;
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;
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);
#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:
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;
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);
stl_raw(p++, 0x00000000); /* nop */
/* YAMON service vector */
- stl_raw(phys_ram_base + bios_offset + 0x500, 0xbfc00580); /* start: */
+ stl_raw(phys_ram_base + bios_offset + 0x500, 0xbfc00580); /* start: */
stl_raw(phys_ram_base + bios_offset + 0x504, 0xbfc0083c); /* print_count: */
- stl_raw(phys_ram_base + bios_offset + 0x520, 0xbfc00580); /* start: */
+ stl_raw(phys_ram_base + bios_offset + 0x520, 0xbfc00580); /* start: */
stl_raw(phys_ram_base + bios_offset + 0x52c, 0xbfc00800); /* flush_cache: */
stl_raw(phys_ram_base + bios_offset + 0x534, 0xbfc00808); /* print: */
stl_raw(phys_ram_base + bios_offset + 0x538, 0xbfc00800); /* reg_cpu_isr: */
static int ne2000_can_receive(void *opaque)
{
NE2000State *s = opaque;
-
+
if (s->cmd & E8390_STOP)
return 1;
return !ne2000_buffer_full(s);
uint8_t buf1[60];
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 {
void isa_ne2000_init(int base, qemu_irq 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);
}
PCINE2000State *d;
NE2000State *s;
uint8_t *pci_conf;
-
+
d = (PCINE2000State *)pci_register_device(bus,
"NE2000", sizeof(PCINE2000State),
devfn,
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_ADDRESS_SPACE_IO, ne2000_map);
s = &d->ne2000;
s->macaddr[3],
s->macaddr[4],
s->macaddr[5]);
-
+
/* XXX: instance number ? */
register_savevm("ne2000", 0, 3, ne2000_save, ne2000_load, s);
}
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_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 */
parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
{
ParallelState *s = opaque;
-
+
pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
addr &= 7;
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)
{
static const char shutdown_str[8] = "Shutdown";
static int shutdown_index = 0;
-
+
switch(addr) {
/* Bochs BIOS messages */
case 0x400:
/* map all the bios at the top of memory */
cpu_register_physical_memory((uint32_t)(-bios_size),
bios_size, bios_offset | IO_MEM_ROM);
-
+
bochs_bios_init();
if (linux_boot)
smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
}
}
-
+
if (i440fx_state) {
i440fx_init_memory_mappings(i440fx_state);
}
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])
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];
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);
PCIDevice *pci_dev = (PCIDevice *)opaque;
PCIBus *bus;
int change;
-
+
change = level - pci_dev->irq_state[irq_num];
if (!change)
return;
PCIBus *bus = first_bus;
PCIDevice *d;
int devfn;
-
+
while (bus && bus->bus_num != bus_num)
bus = bus->next;
if (bus) {
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);
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;
#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)),
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 */
#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)));
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) = GET_FIELD(tmd.length, TMDL, BCNT);
CSR_CXST(s) = tmd.status;
} 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;
nrda = s->rdra +
(CSR_RCVRL(s) - rcvrc) *
(BCR_SWSTYLE(s) ? 16 : 8 );
- RMDLOAD(&rmd, PHYSADDR(s,nrda));
+ RMDLOAD(&rmd, PHYSADDR(s,nrda));
if (GET_FIELD(rmd.status, RMDS, OWN)) {
#ifdef PCNET_DEBUG_RMD
printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
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
#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;
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;
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);
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);
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[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[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;
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_ADDRESS_SPACE_MEM, pcnet_mmio_map);
-
+
d->irq = d->dev.irq[0];
d->phys_mem_read = pci_physical_memory_read;
d->phys_mem_write = pci_physical_memory_write;
offset -= (uint32_t)(long)pfl->storage;
else
offset -= pfl->base;
-
+
DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d\n", __func__,
offset, value, width);
/* Set the device in I/O access mode */
static void pl011_update(pl011_state *s)
{
uint32_t flags;
-
+
flags = s->int_level & s->int_enabled;
qemu_set_irq(s->irq, flags != 0);
}
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:
/* Transfer data between the card and the FIFO. This is complicated by
the FIFO holding 32-bit words and the card taking data in single byte
chunks. FIFO bytes are transferred in little-endian order. */
-
+
static void pl181_fifo_run(pl181_state *s)
{
uint32_t bits;
uint64_t wdt_next; /* Tick for next WDT interrupt */
struct QEMUTimer *wdt_timer;
};
-
+
/* Fixed interval timer */
static void cpu_4xx_fit_cb (void *opaque)
{
target_ulong kernel_base, kernel_size, initrd_base, initrd_size;
int linux_boot;
int fl_idx, fl_sectors;
-
+
/* RAM is soldered to the board so the size cannot be changed */
ram_bases[0] = 0x00000000;
ram_sizes[0] = 0x04000000;
}
mask = mask >> 1;
}
-
+
}
static void ppc4xx_gpt_set_irqs (ppc4xx_gpt_t *gpt)
qemu_irq_lower(gpt->irqs[i]);
mask = mask >> 1;
}
-
+
}
static void ppc4xx_gpt_compute_timer (ppc4xx_gpt_t *gpt)
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,
{
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
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,
bios_size = (bios_size + 0xfff) & ~0xfff;
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);
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 */
/* XXX: suppress that */
dummy_irq = i8259_init(NULL);
-
+
/* XXX: use Mac Serial port */
serial_init(0x3f8, dummy_irq[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(pic[0x12]);
-
+
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
-
+
{
MacIONVRAMState *nvr;
nvr = macio_nvram_init();
#endif
/* cuda also initialize ADB */
cuda_mem_index = cuda_init(pic[0x19]);
-
+
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
-
+
macio_init(pci_bus, 0x0022);
-
+
nvram = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
-
+
arch_name = "MAC99";
}
kernel_filename, kernel_cmdline,
initrd_filename, cpu_model, 0);
}
-
+
static void ppc_heathrow_init (int ram_size, int vga_ram_size, int boot_device,
DisplayState *ds, const char **fd_filename,
int snapshot,
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_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->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->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));
PCIRTL8139State *d;
RTL8139State *s;
uint8_t *pci_conf;
-
+
d = (PCIRTL8139State *)pci_register_device(bus,
"RTL8139", sizeof(PCIRTL8139State),
devfn,
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);
{
SerialState *s = opaque;
unsigned char ch;
-
+
addr &= 7;
#ifdef DEBUG_SERIAL
printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
{
SLAVIO_INTCTLState *s = opaque;
int i;
-
+
for (i = 0; i < MAX_CPUS; i++) {
qemu_put_be32s(f, &s->intreg_pending[i]);
}
ChannelState *s = opaque;
SERIOQueue *q = &s->queue;
int val;
-
+
if (q->count == 0) {
return 0;
} else {
{
SLAVIO_TIMERState *s = opaque;
uint32_t tmp;
-
+
if (version_id != 2)
return -EINVAL;
void smbus_eeprom_device_init(i2c_bus *bus, uint8_t addr, uint8_t *buf)
{
SMBusEEPROMDevice *eeprom;
-
+
eeprom = (SMBusEEPROMDevice *)smbus_device_init(bus, addr,
sizeof(SMBusEEPROMDevice));
/* Pad short packets. */
if (size < 64) {
int pad;
-
+
if (size & 1)
*(p++) = buf[size - 1];
pad = 64 - size;
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)
static void tcx_save(QEMUFile *f, void *opaque)
{
TCXState *s = opaque;
-
+
qemu_put_be16s(f, (uint16_t *)&s->height);
qemu_put_be16s(f, (uint16_t *)&s->width);
qemu_put_be16s(f, (uint16_t *)&s->depth);
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] */
0x07, /* u8 if_iInterface; */
-
+
/* HID descriptor */
0x09, /* u8 bLength; */
0x21, /* u8 bDescriptorType; */
5: Remote wakeup,
4..0: resvd */
50, /* u8 MaxPower; */
-
+
/* USB 1.1:
* USB 2.0, single TT organization (mandatory):
* one interface, protocol 0
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;
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)
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 */
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);
if (td->ctrl & TD_CTRL_IOC) {
*int_mask |= 0x01;
}
-
+
if (!(td->ctrl & TD_CTRL_ACTIVE))
return 1;
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);
}
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];
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
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 */
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;
line_compare = 65535;
} else
#endif
- {
+ {
/* compute line_offset in bytes */
line_offset = s->cr[0x13];
line_offset <<= 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_16,
vga_draw_glyph9_16,
};
-
+
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,
-};
+};
/*
* Text mode update
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;
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;
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];
uint8_t *d;
uint32_t v, addr1, addr;
vga_draw_line_func *vga_draw_line;
-
+
full_update |= update_basic_params(s);
s->get_resolution(s, &width, &height);
s->shift_control = shift_control;
s->double_scan = double_scan;
}
-
+
if (shift_control == 0) {
full_update |= update_palette16(s);
if (s->sr[0x01] & 8) {
}
if (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",
} else {
s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(s->ds)];
-
+
full_update = 0;
if (!(s->ar_index & 0x20)) {
graphic_mode = GMODE_BLANK;
static void vga_invalidate_display(void *opaque)
{
VGAState *s = (VGAState *)opaque;
-
+
s->last_width = -1;
s->last_height = -1;
}
PCIVGAState *d;
VGAState *s;
uint8_t *pci_conf;
-
+
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);
graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, 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[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_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
{
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,
s->ds->linesize);
#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
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];
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);
s += 2;
d += BPP;
} while (--w != 0);
-#endif
+#endif
}
/*
s += 2;
d += BPP;
} while (--w != 0);
-#endif
+#endif
}
/*
{
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;
{
int fptag, i, j;
struct fpstate fp1, *fp = &fp1;
-
+
fp->fpuc = env->fpuc;
fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
fptag = 0;
struct kqemu_cpu_state *kenv)
{
int selector;
-
+
selector = (env->star >> 32) & 0xffff;
#ifdef __x86_64__
if (env->hflags & HF_LMA_MASK) {
#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,
}
}
qsort(pr, nb_pc_records, sizeof(PCRecord *), pc_rec_cmp);
-
+
f = fopen("/tmp/kqemu.stats", "w");
if (!f) {
perror("/tmp/kqemu.stats");
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
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);
#define TARGET_NR_lremovexattr 392
#define TARGET_NR_fremovexattr 393
#define TARGET_NR_futex 394
-#define TARGET_NR_sched_setaffinity 395
+#define TARGET_NR_sched_setaffinity 395
#define TARGET_NR_sched_getaffinity 396
#define TARGET_NR_tuxcall 397
#define TARGET_NR_io_setup 398
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); \
elf_type,
interpreter_fd,
eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
-
+
if (error == -1) {
/* Real error */
close(interpreter_fd);
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;
}
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)),
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;
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 */
};
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");
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) {
if ((sp + stack_len) & 15)
sp -= 16 - ((sp + stack_len) & 15);
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;
}
return -1;
}
}
-
+
if(retval>=0) {
/* success. Initialize important registers */
do_init_thread(regs, infop);
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;
{
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",
{
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)];
{
int trapnr, ret;
target_siginfo_t info;
-
+
while (1) {
trapnr = cpu_sparc_exec (env);
-
+
switch (trapnr) {
#ifndef TARGET_SPARC64
case 0x88:
/* 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 */
target_siginfo_t info;
int trapnr;
uint32_t ret;
-
+
for(;;) {
trapnr = cpu_ppc_exec(env);
if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH &&
{
int trapnr, ret;
target_siginfo_t info;
-
+
while (1) {
trapnr = cpu_sh4_exec (env);
-
+
switch (trapnr) {
case 0x160:
ret = do_syscall(env,
unsigned int n;
target_siginfo_t info;
TaskState *ts = env->opaque;
-
+
for(;;) {
trapnr = cpu_m68k_exec(env);
switch(trapnr) {
{
int trapnr;
target_siginfo_t info;
-
+
while (1) {
trapnr = cpu_alpha_exec (env);
-
+
switch (trapnr) {
case EXCP_RESET:
fprintf(stderr, "Reset requested. Exit\n");
if (optind >= argc)
break;
-
+
r = argv[optind++];
mask = cpu_str_to_log_mask(r);
if (!mask) {
qemu_host_page_size */
env = cpu_init();
global_env = env;
-
+
wrk = environ;
while (*(wrk++))
environ_count++;
for (wrk = target_environ; *wrk; wrk++) {
free(*wrk);
}
-
+
free(target_environ);
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 */
#if defined(TARGET_X86_64)
env->regs[R_EAX] = regs->rax;
return -EINVAL;
if (len == 0)
return 0;
-
+
host_start = start & qemu_host_page_mask;
host_end = HOST_PAGE_ALIGN(end);
if (start > host_start) {
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);
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,
/* 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);
goto the_end1;
}
}
-
+
if (start & ~TARGET_PAGE_MASK) {
errno = EINVAL;
return -1;
return ret;
real_end -= qemu_host_page_size;
}
-
+
/* map the middle (easier) */
if (real_start < real_end) {
unsigned long offset1;
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);
return -EINVAL;
if (end == start)
return 0;
-
+
start &= qemu_host_page_mask;
return msync(g2h(start), end - start, flags);
}
int i;
unsigned long sigmask;
uint32_t target_sigmask;
-
+
sigmask = ((unsigned long *)s)[0];
target_sigmask = 0;
for(i = 0; i < 32; i++) {
s1.sig[i] = tswapl(s->sig[i]);
target_to_host_sigset_internal(d, &s1);
}
-
+
void host_to_target_old_sigset(target_ulong *old_sigset,
const sigset_t *sigset)
{
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];
target_to_host_sigset_internal(&set, &target_set);
sigprocmask(SIG_SETMASK, &set, NULL);
-
+
/* restore registers */
if (restore_sigcontext(env, &frame->sc, &eax))
goto badframe;
:"r" (®s));
/* Unreached */
#endif
-
+
regs->PC[regs->current_tc] = regs->CP0_EPC;
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
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");
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
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... */
target_efds = NULL;
efds_ptr = NULL;
}
-
+
if (target_tv) {
target_to_host_timeval(&tv, target_tv);
tv_ptr = &tv;
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;
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));
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 =
target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
host->c_oflag =
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[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[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[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[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[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;
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];
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));
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:
lock_user_struct(target_fl64, arg, 1);
fl64.l_type = tswap16(target_fl64->l_type) >> 1;
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);
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);
case TARGET_NR_getitimer:
{
struct itimerval value;
-
+
ret = get_errno(getitimer(arg1, &value));
if (!is_error(ret) && arg2) {
host_to_target_timeval(arg2,
/* 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;
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++)
*/
#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) */
STRUCT(sockaddr_ifreq,
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), MK_STRUCT(STRUCT_sockaddr))
-
+
STRUCT(short_ifreq,
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_SHORT)
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);
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;
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:
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",
env->segs[R_CS].selector, env->eip);
/* Load a U-Boot image. */
int load_uboot(const char *filename, target_ulong *ep, int *is_linux)
{
-
+
int fd;
int size;
uboot_image_header_t h;
{"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)
{
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 {
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') {
case '$':
{
char buf[128], *q;
-
+
pch++;
q = buf;
while ((*pch >= 'a' && *pch <= 'z') ||
{
target_long val, val2;
int op;
-
+
val = expr_unary();
for(;;) {
op = *pch;
#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))
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))
p++;
if (*typestr == '?') {
case '/':
{
int count, format, size;
-
+
while (isspace(*p))
p++;
if (*p == '/') {
{
int has_option;
/* option */
-
+
c = *typestr++;
if (c == '\0')
goto bad_type;
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 t
toggle console timestamps
@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
| (10.0.2.2)
|
----> DNS server (10.0.2.3)
- |
+ |
----> SMB server (10.0.2.4)
@end example
@table @option
-@item -g WxH[xDEPTH]
+@item -g WxH[xDEPTH]
Set the initial VGA graphic mode. The default is 800x600x15.
@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)
@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)
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;
-
+
flags = 0;
for(;;) {
c = getopt(argc, argv, "b:f:he6");
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 (flags && BLOCK_FLAG_COMPRESS) {
char *cmdline;
nb_completions = 0;
-
+
cmdline = qemu_malloc(term_cmd_buf_index + 1);
if (!cmdline)
return;
quite close.
For example the instruction "mvo" is defined in the PoP as follows:
-
+
MVO D1(L1,B1),D2(L2,B2) [SS]
--------------------------------------
{
SDL_Event ev1, *ev = &ev1;
int mod_state;
-
+
if (last_vm_running != vm_running) {
last_vm_running = vm_running;
sdl_update_caption();
} else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) {
dz = 1;
}
-#endif
+#endif
sdl_send_mouse_event(dz);
}
}
/* 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},
const uint8_t *p, *p_end;
int len, tag;
- *pmsg_type = 0;
+ *pmsg_type = 0;
p = buf;
p_end = buf + size;
/* 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 &&
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) -
sizeof(struct ip) - sizeof(struct udphdr);
udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
sum += s_util.s;
mlen = 0;
} else
-
+
mlen = -1;
} else if (mlen == -1)
s_util.c[0] = *(u_int8_t *)w;
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);
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++] = ' ';
if (!dfd)
debug_init("slirp_stats", 0xf);
lprint_arg = (char **)&dfd;
-
+
ipstats();
tcpstats();
udpstats();
}
/*
- * 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)
*/
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);
}
ifm = next_m;
else
ifm = if_batchq.ifq_next;
-
+
/* Set which packet to send on next iteration */
next_m = ifm->ifq_next;
}
}
m->m_len += hlen;
m->m_data -= hlen;
-
+
/* icmpstat.icps_inhist[icp->icmp_type]++; */
/* code = icp->icmp_code; */
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) {
icmpstat.icps_notsupp++;
m_freem(m);
break;
-
+
default:
icmpstat.icps_badtype++;
m_freem(m);
/* 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:
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);
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);
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;
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;
}
}
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
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",
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;
}
}
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)
#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;
}
}
*/
int len = strlen(format);
char *bptr1, *bptr2;
-
+
bptr1 = bptr2 = strdup(format);
-
+
while (len--) {
if (*bptr1 == '\r')
memcpy(bptr1, bptr1+1, len+1);
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",
"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;
}
}
sb->sb_rptr += num;
if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
sb->sb_rptr -= sb->sb_datalen;
-
+
}
void
memcpy(to+off,sb->sb_data,len);
}
}
-
+
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);
}
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;
global_readfds = NULL;
global_writefds = NULL;
global_xfds = NULL;
-
+
nfds = *pnfds;
/*
* First, TCP sockets
*/
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
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;
*/
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
*/
* 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);
}
if (pkt_len < ETH_HLEN)
return;
-
+
proto = ntohs(*(uint16_t *)(pkt + 12));
switch(proto) {
case ETH_P_ARP:
/* 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 {
/*
#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));
}
if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
char buff[256];
int len;
-
+
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",
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
(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 */
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
*/
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;
}
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
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
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
}
/* 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",
}
return;
- cont_conn:
+ cont_conn:
/* m==NULL
* Check if the connect succeeded
*/
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
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)) {
* of sequence; drop it.
*/
tiflags &= ~TH_FIN;
-
+
/*
* Send an ACK to resynchronize and drop any data.
* But keep on processing for RST or ACK.
* 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)) {
/* 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);
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++;
}
}
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.
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
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,
* 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; }
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",
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
};
struct emu_t *tcpemu = 0;
-
+
/*
* Return TOS according to the above table
*/
* 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
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_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;
}
}
}
-
+
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]",
&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",
n1, n2, n3, n4, n5, n6, x==7?buff:"");
&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",
buff, (unsigned long)ntohl(so->so_faddr.s_addr),
} 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),
* any more.
*
* A typical packet for player version 1.0 (release version):
- *
+ *
* 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];
-
+
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:
/*
* skip version number
*/
bptr++;
break;
-
+
case 5:
/*
* The difference between versions 1.0 and
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)
+ ((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),
*(u_char *)bptr++ = p & 0xff;
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;
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) {
* 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
*
* *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
struct tftp_session {
int in_use;
unsigned char filename[TFTP_FILENAME_MAX];
-
+
struct in_addr client_ip;
u_int16_t client_port;
-
+
int timestamp;
};
m->m_data += if_maxlinkhdr;
tp = (void *)m->m_data;
m->m_data += sizeof(struct udpiphdr);
-
+
tp->tp_op = htons(TFTP_OACK);
n += sprintf(tp->x.tp_buf + n, "%s", key) + 1;
n += sprintf(tp->x.tp_buf + n, "%u", value) + 1;
saddr.sin_addr = recv_tp->ip.ip_dst;
saddr.sin_port = recv_tp->udp.uh_dport;
-
+
daddr.sin_addr = spt->client_ip;
daddr.sin_port = spt->client_port;
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);
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);
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;
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) {
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 */
}
daddr.sin_addr = so->so_laddr;
daddr.sin_port = so->so_lport;
-
+
return udp_output2(so, m, &saddr, &daddr, so->so_iptos);
}
*/
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(nmsg, ctl_addr)->sin_addr = our_addr;
strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD);
}
-
+
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;
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,
+ 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,
(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;
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_head->s_port = addr.sin_port;
cu_head->so_addr = our_addr.s_addr;
}
-
+
return;
}
}
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);
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;
/* 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);
0,
KEY_READ,
&connection_key);
-
+
if (status == ERROR_SUCCESS) {
len = sizeof (name_data);
status = RegQueryValueEx(
result = WriteFile(overlapped->handle, buffer, size,
&write_size, &overlapped->write_overlapped);
-
+
if (!result) {
switch (error = GetLastError())
{
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);
else
env->exception_index = EXCP_DFAULT;
env->ipr[IPR_EXC_ADDR] = address;
-
+
return 1;
}
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;
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;
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;
}
{
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);
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:
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.
nType = nDest;
else
nType = fpa11->fType[getFn(opcode)];
-
+
if (!CONSTANT_FM(opcode))
{
register unsigned int Fm = getFm(opcode);
floatx80_to_float32(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
}
break;
-
+
case typeDouble:
{
if (typeSingle == nType)
floatx80_to_float64(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
}
break;
-
+
case typeExtended:
{
if (typeSingle == nType)
}
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[2] = 0; /* empty */
}
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:
default: val = fpa11->fpreg[Fn].fSingle;
}
-
+
tput32(addr, p[0]);
-}
+}
static inline
void storeDouble(const unsigned int Fn,unsigned int *pMem)
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:
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, nType << 14);
}
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);
{
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();
goto unordered;
rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
break;
-
+
case typeExtended:
//printk("extended.\n");
if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
goto unordered;
rFn = fpa11->fpreg[Fn].fExtended;
break;
-
+
default: return 0;
}
goto unordered;
rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status);
break;
-
+
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);
}
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
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;
}
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;
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;
} 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 */
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;
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;
uint32_t cpuid_model[12];
uint32_t cpuid_ext2_features;
uint32_t cpuid_apic_id;
-
+
#ifdef USE_KQEMU
int kqemu_enabled;
int last_io_time;
{
SegmentCache *sc;
unsigned int new_hflags;
-
+
sc = &env->segs[seg_reg];
sc->selector = selector;
sc->base = base;
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);
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;
uint32_t *esp_ptr, int dpl)
{
int type, index, shift;
-
+
#if 0
{
int i;
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;
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);
static inline target_ulong get_rsp_from_tss(int level)
{
int index;
-
+
#if 0
printf("TR: base=" TARGET_FMT_lx " limit=%x\n",
env->tr.base, env->tr.limit);
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);
ECX = env->eip + next_eip_addend;
env->regs[11] = compute_eflags();
-
+
code64 = env->hflags & HF_CS64_MASK;
cpu_x86_set_cpl(env, 0);
#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,
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;
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,
target_ulong next_eip, int is_hw)
* 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,
int next_eip_addend)
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);
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,
env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK));
cpu_x86_update_cr4(env, 0);
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);
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);
{
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_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);
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)
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)
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;
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);
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) {
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;
}
if (!(e2 & DESC_P_MASK))
raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
-
+
sp += addend;
if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) ||
((env->hflags & HF_CS64_MASK) && !is_iret))) {
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 |
IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | VIP_MASK);
{
int tss_selector, type;
uint32_t e1, e2;
-
+
/* specific case for TSS */
if (env->eflags & NT_MASK) {
#ifdef TARGET_X86_64
void helper_fyl2x(void)
{
CPU86_LDouble fptemp;
-
+
fptemp = ST0;
if (fptemp>0.0){
fptemp = log(fptemp)/log(2.0); /* log2(ST) */
helper_fstt(tmp, addr);
addr += 16;
}
-
+
if (env->cr[4] & CR4_OSFXSR_MASK) {
/* XXX: finish it */
stl(ptr + 0x18, env->mxcsr); /* mxcsr */
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_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;
}
#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);
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",
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)) &
env->a20_mask;
pml4e = ldq_phys(pml4e_addr);
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_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:
sext = (int64_t)addr >> 47;
if (sext != 0 && sext != -1)
return -1;
-
+
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)) &
env->a20_mask;
pdpe = ldl_phys(pdpe_addr);
{
int fptag, i, j;
struct fpstate fp1, *fp = &fp1;
-
+
fp->fpuc = env->fpuc;
fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
fptag = 0;
{
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)
{
[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 },
{
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);
}
{
int count;
target_long res;
-
+
res = T0 & DATA_MASK;
if (res != 0) {
count = 0;
/* 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 */
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);
ot = dflag ? OT_LONG : OT_WORD;
insn_get(s, ot);
break;
-
+
case 0x98: /* CWDE/CBW */
break;
case 0x99: /* CDQ/CWD */
case 0x84: /* test Ev, Gv */
case 0x85:
-
+
case 0x1c0:
case 0x1c1: /* xadd Ev, Gv */
goto illegal_op;
parse_modrm(s, modrm);
break;
-
+
/**************************/
/* push/pop */
case 0x50 ... 0x57: /* push */
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);
break;
}
}
-
+
#ifdef DEBUG_DISAS
if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "----------------\n");
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];
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,
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)
if (s->aflag) {
base = rm;
-
+
if (base == 4) {
code = ldub_code(s->pc++);
base = (code & 7);
}
-
+
switch (mod) {
case 0:
if (base == 5) {
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:
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)) {
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();
{
ot = s->dflag + OT_WORD;
opsize = 2 << s->dflag;
-
+
gen_op_movl_A0_ESP();
gen_op_addl_A0_im(-opsize);
if (!s->ss32)
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 {
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;
/* 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;
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_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)
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);
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);
}
}
gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
break;
-
+
/************************/
/* flags */
case 0x9c: /* pushf */
tval += next_eip;
if (s->dflag == 0)
tval &= 0xffff;
-
+
l1 = gen_new_label();
l2 = gen_new_label();
b &= 3;
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 */
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;
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);
/* Temporary storage for DIV helpers. */
uint32_t div1;
uint32_t div2;
-
+
/* MMU status. */
struct {
uint32_t ar;
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)
uint32_t base;
int op;
int l1;
-
+
base = s->pc;
op = (insn >> 8) & 0xf;
offset = (int8_t)insn;
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;
/* TLB match but 'D' bit is cleared */
exception = EXCP_LTLBL;
break;
-
+
}
/* Raise exception */
env->CP0_BadVAddr = address;
enable = GET_FP_ENABLE(env->fpu->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) {
fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
}
#endif
-
+
return 0;
}
int flags)
{
int i;
-
+
cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
for (i = 0; i < 32; i++) {
ppcemb_tlb_t *tlb;
target_phys_addr_t raddr;
int i, ret, zsel, zpr;
-
+
ret = -1;
raddr = -1;
for (i = 0; i < env->nb_tlb; i++) {
" %d %d\n", __func__, address, raddr, ctx->prot,
ret);
}
-
+
return ret;
}
target_ulong eaddr, int rw)
{
int in_plb, ret;
-
+
ctx->raddr = eaddr;
ctx->prot = PAGE_READ;
ret = 0;
double d;
uint8_t n;
int i;
-
+
printf("static const uint8_t mfrom_ROM_table[602] =\n{\n ");
for (i = 0; i < 602; i++) {
/* Extremly decomposed:
b0 = b;
b1 = b >> 32;
-
+
v = (uint64_t)a0 * (uint64_t)b0;
*plow = v;
*phigh = 0;
void do_load_dcr (void)
{
target_ulong val;
-
+
if (unlikely(env->dcr_env == NULL)) {
if (loglevel != 0) {
fprintf(logfile, "No DCR environment\n");
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 (unlikely(!ctx->fpu_enabled)) {
RET_EXCP(ctx, EXCP_NO_FP, 0);
return;
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
{
uint8_t crb;
-
+
if (unlikely(!ctx->fpu_enabled)) {
RET_EXCP(ctx, EXCP_NO_FP, 0);
return;
else
#endif
gen_op_test_ctr_false(mask);
- break;
+ break;
case 2:
#if defined(TARGET_PPC64)
if (ctx->sf_mode)
}
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);
}
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
{
uint32_t crm, crn;
-
+
if (likely(ctx->opcode & 0x00100000)) {
crm = CRM(ctx->opcode);
if (likely((crm ^ (crm - 1)) == 0)) {
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
{
uint32_t crm, crn;
-
+
gen_op_load_gpr_T0(rS(ctx->opcode));
crm = CRM(ctx->opcode);
if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
break;
-
+
case CPU_PPC_G2: /* PowerPC G2 family */
case CPU_PPC_G2H4:
case CPU_PPC_G2gp:
import sys
denand (open (sys.argv[1], 'rb'),
open (sys.argv[2], 'wb'))
-
+
Style isssues
-------------
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);
}
{
env->exception_index = tt;
cpu_loop_exit();
-}
+}
void check_ieee_exceptions()
{
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
unsigned int i;
uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
-
+
for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
temp = ldl_kernel(src);
stl_kernel(dst, temp);
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
: "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) { \
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));
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();
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;
if (argc != 2)
usage();
filename = argv[1];
-
+
vm86_mem = mmap((void *)0x00000000, 0x110000,
PROT_WRITE | PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
/* 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;
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;
if (argc != 2)
usage();
filename = argv[1];
-
+
vm86_mem = mmap((void *)0x00000000, 0x110000,
PROT_WRITE | PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
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
movw %ax, %es
es movw $GET_OFFSET(int90_test), 0x90 * 4
es movw %cs, 0x90 * 4 + 2
-
+
/* launch int 0x90 */
int $0x90
movb $0xff, %ah
int $0x21
- sti
+ sti
pushfl
popl %edx
movb $0xff, %ah
int $0x21
-
+
#if 0
movw $GET_OFFSET(IF_msg1), %dx
movb $0x09, %ah
popw %dx
movb $0xff, %ah
int $0x21
-
+
pushfl
movw %sp, %bx
orw $0x200, (%bx)
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$"
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));
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));
/* 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)
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");
"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"
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]);
SSE_OPS(cmpnlt);
SSE_OPS(cmpnle);
SSE_OPS(cmpord);
-
-
+
+
a.d[0] = 2.7;
a.d[1] = -3.4;
b.d[0] = 45.7;
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;
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 */
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]];
#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)
case INDEX_op_ ## op ## _user:\
case INDEX_op_ ## op ## _kernel
#endif
-
+
CASE3(stfd):
CASE3(stfs):
CASE3(lfd):
product_name, sizeof(product_name),
devname) < 0)
return NULL;
-
+
snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
bus_num, addr);
fd = open(buf, O_RDWR);
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)
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");
#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;
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);
}
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;
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;
-
+
#if defined(__linux__)
/* Not satisfying */
if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
return NULL;
}
#endif
-
+
/* Disabling local echo and line-buffered output */
tcgetattr (master_fd, &tty);
tty.c_lflag &= ~(ECHO|ICANON|ISIG);
}
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:
{
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(chr);
}
WinCharState *s = chr->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(chr, filename) < 0) {
free(s);
free(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)
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);
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];
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);
snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
SMBD_COMMAND, smb_conf);
-
+
slirp_add_exec(0, smb_cmdline, 4, 139);
}
/*
* Allocate TAP device, returns opened fd.
* Stores dev name in the first arg(must be large enough).
- */
+ */
int tap_alloc(char *dev)
{
int tap_fd, if_fd, ppa = -1;
{
struct ifreq ifr;
int fd, ret;
-
+
TFR(fd = open("/dev/net/tun", O_RDWR));
if (fd < 0) {
fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
perror("bind");
goto fail;
}
-
+
/* Add host to multicast group */
imr.imr_multiaddr = mcastaddr->sin_addr;
imr.imr_interface.s_addr = htonl(INADDR_ANY);
static void net_socket_accept(void *opaque)
{
- NetSocketListenState *s = opaque;
+ NetSocketListenState *s = opaque;
NetSocketState *s1;
struct sockaddr_in saddr;
socklen_t len;
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");
return -1;
s->dgram_dst = saddr;
-
+
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"socket: mcast=%s:%d",
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
if (ret < 0) {
fprintf(stderr, "Could not initialize device '%s'\n", device);
}
-
+
return ret;
}
} 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--;
/* record size: filled later */
len_pos = qemu_ftell(f);
qemu_put_be32(f, 0);
-
+
se->save_state(f, se->opaque);
/* fill record size */
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;
{
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]);
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;
if (ret == 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])
w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
-
+
/* Check for additional signaled events */
for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
-
+
/* Check if event is signaled */
ret2 = WaitForSingleObject(w->events[i], 0);
if(ret2 == WAIT_OBJECT_0) {
} else {
err = GetLastError();
fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
- }
- }
+ }
+ }
} else if (ret == WAIT_TIMEOUT) {
} else {
err = GetLastError();
nfds = ioh->fd;
}
}
-
+
tv.tv_sec = 0;
#ifdef _WIN32
tv.tv_usec = 0;
/* Check bottom-halves last in case any of the earlier events triggered
them. */
qemu_bh_poll();
-
+
}
static CPUState *cur_cpu;
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)
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");
} else {
goto graphic_error;
}
-
+
graphic_width = w;
graphic_height = h;
graphic_depth = depth;
}
setvbuf(stdout, NULL, _IOLBF, 0);
-
+
init_timers();
init_timer_alarm();
qemu_aio_init();
int devfn;
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
-
+
/* do not access the following fields */
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
int keycode;
keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
-
+
/* QEMU console switch */
switch(keycode) {
case 0x2a: /* Left Shift */