Ejemplo n.º 1
0
static void write_little_endian_word(WORD x)
{
  write_byte((BYTE)x);
  write_byte((BYTE)(x >> 8));
}
Ejemplo n.º 2
0
/*----------------------------------------------------------------------
 * Parse a single token (called from the scanner)
 */
void
parse_token (token_t token, char *str)
{
    unsigned long num;

    /*
     * This is implemented as a simple state machine of five states.
     * State transitions are caused by tokens being received from the
     * scanner. The code should be self_documenting.
     */

    if (debug>=2) {
        /* Sanitize - remove all '\r' */
        char *c;
        if (str!=NULL) { while ((c = strchr(str, '\r')) != NULL) *c=' '; }

        fprintf(stderr, "(%s, %s \"%s\") -> (",
                state_str[state], token_str[token], str ? str : "");
    }

    switch(state) {

    /* ----- Waiting for new packet -------------------------------------------*/
    case INIT:
        switch(token) {
        case T_TEXT:
            append_to_preamble(str);
            break;
        case T_DIRECTIVE:
            process_directive(str);
            break;
        case T_OFFSET:
            num = parse_num(str, TRUE);
            if (num==0) {
                /* New packet starts here */
                start_new_packet();
                state = READ_OFFSET;
            }
            break;
        default:
            break;
        }
        break;

    /* ----- Processing packet, start of new line -----------------------------*/
    case START_OF_LINE:
        switch(token) {
        case T_TEXT:
            append_to_preamble(str);
            break;
        case T_DIRECTIVE:
            process_directive(str);
            break;
        case T_OFFSET:
            num = parse_num(str, TRUE);
            if (num==0) {
                /* New packet starts here */
                start_new_packet();
                packet_start = 0;
                state = READ_OFFSET;
            } else if ((num - packet_start) != curr_offset) {
                /*
                 * The offset we read isn't the one we expected.
                 * This may only mean that we mistakenly interpreted
                 * some text as byte values (e.g., if the text dump
                 * of packet data included a number with spaces around
                 * it).  If the offset is less than what we expected,
                 * assume that's the problem, and throw away the putative
                 * extra byte values.
                 */
                if (num < curr_offset) {
                    unwrite_bytes(curr_offset - num);
                    state = READ_OFFSET;
                } else {
                    /* Bad offset; switch to INIT state */
                    if (debug>=1)
                        fprintf(stderr, "Inconsistent offset. Expecting %0lX, got %0lX. Ignoring rest of packet\n",
                                curr_offset, num);
                    write_current_packet();
                    state = INIT;
                }
            } else
                state = READ_OFFSET;
            break;
        default:
            break;
        }
        break;

    /* ----- Processing packet, read offset -----------------------------------*/
    case READ_OFFSET:
        switch(token) {
        case T_BYTE:
            /* Record the byte */
            state = READ_BYTE;
            write_byte(str);
            break;
        case T_TEXT:
        case T_DIRECTIVE:
        case T_OFFSET:
            state = READ_TEXT;
            break;
        case T_EOL:
            state = START_OF_LINE;
            break;
        default:
            break;
        }
        break;

    /* ----- Processing packet, read byte -------------------------------------*/
    case READ_BYTE:
        switch(token) {
        case T_BYTE:
            /* Record the byte */
            write_byte(str);
            break;
        case T_TEXT:
        case T_DIRECTIVE:
        case T_OFFSET:
            state = READ_TEXT;
            break;
        case T_EOL:
            state = START_OF_LINE;
            break;
        default:
            break;
        }
        break;

    /* ----- Processing packet, read text -------------------------------------*/
    case READ_TEXT:
        switch(token) {
        case T_EOL:
            state = START_OF_LINE;
            break;
        default:
            break;
        }
        break;

    default:
        fprintf(stderr, "FATAL ERROR: Bad state (%d)", state);
        exit(-1);
    }

    if (debug>=2)
        fprintf(stderr, ", %s)\n", state_str[state]);

}
Ejemplo n.º 3
0
/* perform_save():
   Write the state to the output stream. This returns 0 on success,
   1 on failure.
*/
glui32 perform_save(strid_t str)
{
  dest_t dest;
  int ix;
  glui32 res, lx, val;
  glui32 memstart, memlen, stackstart, stacklen, heapstart, heaplen;
  glui32 filestart=0, filelen;

  stream_get_iosys(&val, &lx);
  if (val != 2) {
    /* Not using the Glk I/O system, so bail. This function only
       knows how to write to a Glk stream. */
    fatal_error("Streams are only available in Glk I/O system.");
  }

  if (str == 0)
    return 1;

  dest.ismem = FALSE;
  dest.size = 0;
  dest.pos = 0;
  dest.ptr = NULL;
  dest.str = str;

  res = 0;

  /* Quetzal header. */
  if (res == 0) {
    res = write_long(&dest, IFFID('F', 'O', 'R', 'M'));
  }
  if (res == 0) {
    res = write_long(&dest, 0); /* space for file length */
    filestart = dest.pos;
  }

  if (res == 0) {
    res = write_long(&dest, IFFID('I', 'F', 'Z', 'S')); /* ### ? */
  }

  /* Header chunk. This is the first 128 bytes of memory. */
  if (res == 0) {
    res = write_long(&dest, IFFID('I', 'F', 'h', 'd'));
  }
  if (res == 0) {
    res = write_long(&dest, 128);
  }
  for (ix=0; res==0 && ix<128; ix++) {
    res = write_byte(&dest, Mem1(ix));
  }
  /* Always even, so no padding necessary. */
  
  /* Memory chunk. */
  if (res == 0) {
    res = write_long(&dest, IFFID('C', 'M', 'e', 'm'));
  }
  if (res == 0) {
    res = write_long(&dest, 0); /* space for chunk length */
  }
  if (res == 0) {
    memstart = dest.pos;
    res = write_memstate(&dest);
    memlen = dest.pos - memstart;
  }
  if (res == 0 && (memlen & 1) != 0) {
    res = write_byte(&dest, 0);
  }

  /* Heap chunk. */
  if (res == 0) {
    res = write_long(&dest, IFFID('M', 'A', 'l', 'l'));
  }
  if (res == 0) {
    res = write_long(&dest, 0); /* space for chunk length */
  }
  if (res == 0) {
    heapstart = dest.pos;
    res = write_heapstate(&dest, TRUE);
    heaplen = dest.pos - heapstart;
  }
  /* Always even, so no padding necessary. */

  /* Stack chunk. */
  if (res == 0) {
    res = write_long(&dest, IFFID('S', 't', 'k', 's'));
  }
  if (res == 0) {
    res = write_long(&dest, 0); /* space for chunk length */
  }
  if (res == 0) {
    stackstart = dest.pos;
    res = write_stackstate(&dest, TRUE);
    stacklen = dest.pos - stackstart;
  }
  if (res == 0 && (stacklen & 1) != 0) {
    res = write_byte(&dest, 0);
  }

  filelen = dest.pos - filestart;

  /* Okay, fill in all the lengths. */
  if (res == 0) {
    res = reposition_write(&dest, memstart-4);
  }
  if (res == 0) {
    res = write_long(&dest, memlen);
  }
  if (res == 0) {
    res = reposition_write(&dest, heapstart-4);
  }
  if (res == 0) {
    res = write_long(&dest, heaplen);
  }
  if (res == 0) {
    res = reposition_write(&dest, stackstart-4);
  }
  if (res == 0) {
    res = write_long(&dest, stacklen);
  }
  if (res == 0) {
    res = reposition_write(&dest, filestart-4);
  }
  if (res == 0) {
    res = write_long(&dest, filelen);
  }

  /* All done. */
    
  return res;
}
Ejemplo n.º 4
0
void wait_duration(float seconds) { // SECONDS CAN BE NO LARGER THAN 255  
	int mseconds = (int) (seconds * 10);
	write_byte(OI_WAIT_TIME);
	write_byte(mseconds); // SECONDS SHOULD NOT BE SPLIT INTO A HIGH BYTE AND A LOW BYTE
}
Ejemplo n.º 5
0
Archivo: batch.c Proyecto: AndyA/rsync
/* This routine tries to write out an equivalent --read-batch command
 * given the user's --write-batch args.  However, it doesn't really
 * understand most of the options, so it uses some overly simple
 * heuristics to munge the command line into something that will
 * (hopefully) work. */
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
{
	int fd, i, len, err = 0;
	char *p, filename[MAXPATHLEN];

	stringjoin(filename, sizeof filename,
		   batch_name, ".sh", NULL);
	fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
		     S_IRUSR | S_IWUSR | S_IEXEC);
	if (fd < 0) {
		rsyserr(FERROR, errno, "Batch file %s open error",
			filename);
		exit_cleanup(RERR_FILESELECT);
	}

	/* Write argvs info to BATCH.sh file */
	if (write_arg(fd, argv[0]) < 0)
		err = 1;
	if (filter_list.head) {
		if (protocol_version >= 29)
			write_sbuf(fd, " --filter=._-");
		else
			write_sbuf(fd, " --exclude-from=-");
	}
	for (i = 1; i < argc - file_arg_cnt; i++) {
		p = argv[i];
		if (strncmp(p, "--files-from", 12) == 0
		    || strncmp(p, "--filter", 8) == 0
		    || strncmp(p, "--include", 9) == 0
		    || strncmp(p, "--exclude", 9) == 0) {
			if (strchr(p, '=') == NULL)
				i++;
			continue;
		}
		if (strcmp(p, "-f") == 0) {
			i++;
			continue;
		}
		if (write(fd, " ", 1) != 1)
			err = 1;
		if (strncmp(p, "--write-batch", len = 13) == 0
		 || strncmp(p, "--only-write-batch", len = 18) == 0) {
			if (write(fd, "--read-batch", 12) != 12)
				err = 1;
			if (p[len] == '=') {
				if (write(fd, "=", 1) != 1
				 || write_arg(fd, p + len + 1) < 0)
					err = 1;
			}
		} else {
			if (write_arg(fd, p) < 0)
				err = 1;
		}
	}
	if (!(p = check_for_hostspec(argv[argc - 1], &p, &i)))
		p = argv[argc - 1];
	if (write(fd, " ${1:-", 6) != 6
	 || write_arg(fd, p) < 0)
		err = 1;
	write_byte(fd, '}');
	if (filter_list.head)
		write_filter_rules(fd);
	if (write(fd, "\n", 1) != 1 || close(fd) < 0 || err) {
		rsyserr(FERROR, errno, "Batch file %s write error",
			filename);
		exit_cleanup(RERR_FILEIO);
	}
}
Ejemplo n.º 6
0
/*-----------------------------------------------------------------------
 * Read bytes
 */
int  i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
	int shift;
//	PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
//		chip, addr, alen, buffer, len);

#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
	/*
	 * EEPROM chips that implement "address overflow" are ones
	 * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
	 * address and the extra bits end up in the "chip address"
	 * bit slots. This makes a 24WC08 (1Kbyte) chip look like
	 * four 256 byte chips.
	 *
	 * Note that we consider the length of the address field to
	 * still be one byte because the extra address bits are
	 * hidden in the chip address.
	 */
	chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);

//	PRINTD("i2c_read: fix addr_overflow: chip %02X addr %02X\n",
//		chip, addr);
#endif

	/*
	 * Do the addressing portion of a write cycle to set the
	 * chip's address pointer.  If the address length is zero,
	 * don't do the normal write cycle to set the address pointer,
	 * there is no address pointer in this chip.
	 */
	send_start();
	if(alen > 0) {
		if(write_byte(chip << 1)) {	/* write cycle */
			send_stop();
//			dprintf(INFO, "i2c_read, no chip responded %02X\n", chip);
			return(1);
		}
		shift = (alen-1) * 8;
		while(alen-- > 0) {
			if(write_byte(addr >> shift)) 
			{
//				dprintf(INFO "i2c_read, address not <ACK>\n");
				return(1);
			}
			shift -= 8;
		}

		/* Some I2C chips need a stop/start sequence here,
		 * other chips don't work with a full stop and need
		 * only a start.  Default behaviour is to send the
		 * stop/start sequence.
		 */
#ifdef CONFIG_SOFT_I2C_READ_REPEATED_START
		send_start();
#else
		send_stop();
		send_start();
#endif
	}
	/*
	 * Send the chip address again, this time for a read cycle.
	 * Then read the data.  On the last byte, we do a NACK instead
	 * of an ACK(len == 0) to terminate the read.
	 */
	write_byte((chip << 1) | 1);	/* read cycle */
	while(len-- > 0) {
		*buffer++ = read_byte(len == 0);
	}
	send_stop();
	return(0);
}
Ejemplo n.º 7
0
void _wait_distance(int distance) {
	write_byte(OI_WAIT_DISTANCE);
	write_byte(get_high_byte(distance));
	write_byte(get_low_byte(distance));
}
Ejemplo n.º 8
0
void serial_writei(unsigned int i)
{
#define MASK_BYTE(VALUE, OFFSET) (((VALUE) >> (OFFSET * 8)) & 0xff)
  write_byte(MASK_BYTE(i, 0));
  write_byte(MASK_BYTE(i, 1));
}
Ejemplo n.º 9
0
void serial_writeb(unsigned char b)
{
  write_byte(b);
}
Ejemplo n.º 10
0
Dynamixel::CommStatus Dynamixel::change_id(unsigned char old_id, unsigned char new_id) {
    return write_byte(old_id, 0x03, new_id);
}
Ejemplo n.º 11
0
Dynamixel::CommStatus Dynamixel::set_baud_rate(unsigned char id, unsigned char rate) {
    return write_byte(id, 0x04, rate);
}
Ejemplo n.º 12
0
Dynamixel::CommStatus Dynamixel::torque_disable(unsigned char id) {
    return write_byte(id, 0x18, 0);
}
Ejemplo n.º 13
0
 void write_string(const char *str)
 {
     for (; *str != 0; ++str)
         write_byte(*str);
 }
Ejemplo n.º 14
0
static int handle_in (ECTX ectx,
	void *data, WORDPTR channel, BYTEPTR address, WORD count)
{
	c_state_t *c = (c_state_t *) data;

	if (c->state == C_S_ENCODE_ENTRY) {
		if (count == 1) {
			write_byte_and_type (ectx, address, (BYTE) c->p.symbol->entry, STYPE_DATA);
			
			if (c->p.argc > 0) {
				c->state = C_S_ENCODE;
			} else {
				c->state = C_S_IDLE;
				if (c->p.symbol->dispatch != NULL)
					return c->p.symbol->dispatch (ectx, c);
			}
			
			return ECTX_CONTINUE;
		} else {
			return ectx->set_error_flag (ectx, EFLAG_EXTCHAN);
		}
	} else if (c->state == C_S_ENCODE) {
		int	n	= --c->p.argc;
		p_arg_t *arg	= &(c->p.argv[n]);
		int	i;
		
		if (arg->type == P_A_WORD && count == sizeof (WORD)) {
			write_word_and_type (ectx, (WORDPTR) address, arg->data.word, STYPE_DATA);
		} else if (arg->type == P_A_BYTE && count == 1) {
			write_byte_and_type (ectx, address, arg->data.byte, STYPE_DATA);
		} else if (arg->type == P_A_BYTES && count == arg->length) {
			for (i = 0; i < arg->length; ++i) {
				write_byte_and_type (ectx, address, arg->data.bytes[i], STYPE_DATA);
				address = byteptr_plus (address, 1);
			}
		} else if (arg->type == P_A_ARRAY && count == arg->length) {
			fill_type_shadow (ectx, address, arg->length, STYPE_DATA);
			for (i = 0; i < arg->length; ++i) {
				write_byte (address, arg->data.array[i]);
				address = byteptr_plus (address, 1);
			}
			if (arg->data.array != c->buffer)
				free (arg->data.array);
		} else {
			return ectx->set_error_flag (ectx, EFLAG_EXTCHAN);
		}
		
		if (c->p.argc == 0) {
			c->state = C_S_IDLE;
			if (c->p.symbol->dispatch != NULL)
				return c->p.symbol->dispatch (ectx, c);
		}

		return ECTX_CONTINUE;
	} else {
		WORKSPACE_SET (ectx->wptr, WS_POINTER, (WORD) address);
		WORKSPACE_SET (ectx->wptr, WS_ECTX, (WORD) ectx);
		WORKSPACE_SET (ectx->wptr, WS_PENDING, count);
		WORKSPACE_SET (ectx->wptr, WS_IPTR, (WORD) ectx->iptr);

		c->waiting = ectx->wptr;

		return _ECTX_DESCHEDULE;
	}
}
Ejemplo n.º 15
0
//
// Returns ah: emulated drive, al: error code
//
uint16_t cdrom_boot(void)
{
    // @TODO: a macro or a function for getting the EBDA segment
    uint16_t            ebda_seg=read_word(0x0040,0x000E);
    uint8_t             buffer[2048];
    cdb_atapi           atapicmd;
    uint32_t            lba;
    uint16_t            boot_segment, nbsectors, i, error;
    uint8_t             device;
    uint8_t             read_try;
    cdemu_t __far       *cdemu;
    bio_dsk_t __far     *bios_dsk;

    cdemu    = ebda_seg :> &EbdaData->cdemu;
    bios_dsk = ebda_seg :> &EbdaData->bdisk;

    /* Find the first CD-ROM. */
    for (device = 0; device < BX_MAX_STORAGE_DEVICES; ++device) {
        if (device_is_cdrom(device))
            break;
    }

    /* Fail if not found. */
    if (device >= BX_MAX_STORAGE_DEVICES)
        return 2;

    /* Read the Boot Record Volume Descriptor (BRVD). */
    _fmemset(&atapicmd, 0, sizeof(atapicmd));
    atapicmd.command = 0x28;    // READ 10 command
    atapicmd.lba     = swap_32(0x11);
    atapicmd.nsect   = swap_16(1);

    bios_dsk->drqp.nsect   = 1;
    bios_dsk->drqp.sect_sz = 2048;

    for (read_try = 0; read_try <= 4; ++read_try)
    {
        //@todo: Use indirect calls instead?
        if (device > BX_MAX_ATA_DEVICES)
            error = ahci_cmd_packet(device, 12, (char __far *)&atapicmd, 0, 2048L, ATA_DATA_IN, &buffer);
        else
            error = ata_cmd_packet(device, 12, (char __far *)&atapicmd, 0, 2048L, ATA_DATA_IN, &buffer);
        if (!error)
            break;
    }
    if (error)
        return 3;

    /* Check for a valid BRVD. */
    if (buffer[0] != 0)
        return 4;
    //@todo: what's wrong with memcmp()?
    for (i = 0; i < 5; ++i) {
        if (buffer[1+i] != isotag[i])
            return 5;
    }
    for (i = 0; i < 23; ++i)
        if (buffer[7+i] != eltorito[i])
            return 6;

    // ok, now we calculate the Boot catalog address
    lba = *((uint32_t *)&buffer[0x47]);
    BX_DEBUG_ELTORITO("BRVD at LBA %lx\n", lba);

    /* Now we read the Boot Catalog. */
    atapicmd.command = 0x28;    // READ 10 command
    atapicmd.lba     = swap_32(lba);
    atapicmd.nsect   = swap_16(1);

#if 0   // Not necessary as long as previous values are reused
    bios_dsk->drqp.nsect   = 1;
    bios_dsk->drqp.sect_sz = 512;
#endif

    if (device > BX_MAX_ATA_DEVICES)
        error = ahci_cmd_packet(device, 12, (char __far *)&atapicmd, 0, 2048L, ATA_DATA_IN, &buffer);
    else
        error = ata_cmd_packet(device, 12, (char __far *)&atapicmd, 0, 2048L, ATA_DATA_IN, &buffer);

    if (error != 0)
        return 7;

    //@todo: Define a struct for the Boot Catalog, the hardcoded offsets are so dumb...

    /* Check if the Boot Catalog looks valid. */
    if (buffer[0x00] != 0x01)
        return 8;   // Header
    if (buffer[0x01] != 0x00)
        return 9;   // Platform
    if (buffer[0x1E] != 0x55)
        return 10;  // key 1
    if (buffer[0x1F] != 0xAA)
        return 10;  // key 2

    // Initial/Default Entry
    if (buffer[0x20] != 0x88)
        return 11; // Bootable

    cdemu->media = buffer[0x21];
    if (buffer[0x21] == 0) {
        // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0.
        // Win2000 cd boot needs to know it booted from cd
        cdemu->emulated_drive = 0xE0;
    }
    else if (buffer[0x21] < 4)
        cdemu->emulated_drive = 0x00;
    else
        cdemu->emulated_drive = 0x80;

    cdemu->controller_index = device / 2;
    cdemu->device_spec      = device % 2;

    boot_segment  = *((uint16_t *)&buffer[0x22]);
    if (boot_segment == 0)
        boot_segment = 0x07C0;

    cdemu->load_segment   = boot_segment;
    cdemu->buffer_segment = 0x0000;

    nbsectors = ((uint16_t *)buffer)[0x26 / 2];
    cdemu->sector_count = nbsectors;

    lba = *((uint32_t *)&buffer[0x28]);
    cdemu->ilba = lba;

    BX_DEBUG_ELTORITO("Emulate drive %02x, type %02x, LBA %lu\n", 
                      cdemu->emulated_drive, cdemu->media, cdemu->ilba);

    /* Read the disk image's boot sector into memory. */
    atapicmd.command = 0x28;    // READ 10 command
    atapicmd.lba     = swap_32(lba);
    atapicmd.nsect   = swap_16(1 + (nbsectors - 1) / 4);

    bios_dsk->drqp.nsect   = 1 + (nbsectors - 1) / 4;
    bios_dsk->drqp.sect_sz = 512;

    bios_dsk->drqp.skip_a = 2048 - nbsectors * 512UL % 2048;

    if (device > BX_MAX_ATA_DEVICES)
        error = ahci_cmd_packet(device, 12, (char __far *)&atapicmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0));
    else
        error = ata_cmd_packet(device, 12, (char __far *)&atapicmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0));

    bios_dsk->drqp.skip_a = 0;

    if (error != 0)
        return 12;

    BX_DEBUG_ELTORITO("Emulate drive %02x, type %02x, LBA %lu\n", 
                      cdemu->emulated_drive, cdemu->media, cdemu->ilba);
    /* Set up emulated drive geometry based on the media type. */
    switch (cdemu->media) {
    case 0x01:  /* 1.2M floppy */
        cdemu->vdevice.spt       = 15;
        cdemu->vdevice.cylinders = 80;
        cdemu->vdevice.heads     = 2;
        break;
    case 0x02:  /* 1.44M floppy */
        cdemu->vdevice.spt       = 18;
        cdemu->vdevice.cylinders = 80;
        cdemu->vdevice.heads     = 2;
        break;
    case 0x03:  /* 2.88M floppy */
        cdemu->vdevice.spt       = 36;
        cdemu->vdevice.cylinders = 80;
        cdemu->vdevice.heads     = 2;
        break;
    case 0x04:  /* Hard disk */
        cdemu->vdevice.spt       = read_byte(boot_segment,446+6)&0x3f;
        cdemu->vdevice.cylinders = (read_byte(boot_segment,446+6)<<2) + read_byte(boot_segment,446+7) + 1;
        cdemu->vdevice.heads     = read_byte(boot_segment,446+5) + 1;
        break;
    }
    BX_DEBUG_ELTORITO("VCHS=%u/%u/%u\n", cdemu->vdevice.cylinders,
                      cdemu->vdevice.heads, cdemu->vdevice.spt);

    if (cdemu->media != 0) {
        /* Increase BIOS installed number of drives (floppy or fixed). */
        if (cdemu->emulated_drive == 0x00)
            write_byte(0x40,0x10,read_byte(0x40,0x10)|0x41);
        else
            write_byte(ebda_seg,(uint16_t)&EbdaData->bdisk.hdcount, read_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.hdcount) + 1);
    }

    // everything is ok, so from now on, the emulation is active
    if (cdemu->media != 0)
        cdemu->active = 0x01;

    // return the boot drive + no error
    return (cdemu->emulated_drive*0x100)+0;
}
Ejemplo n.º 16
0
Archivo: flash.c Proyecto: EvaPilot/Eva
/*-----------------------------------------------------------------------
 * Copy memory to flash.
 */
int write_buff (unsigned char * src, unsigned long addr, unsigned long cnt)
{
	int rc;
	unsigned long i;
	
	unsigned long	blockaddr;
	unsigned long	destaddr;
	unsigned long	lpacket;
	
	if((addr < CFG_FLASH_BASE) || (addr >= (CFG_FLASH_BASE + 64 * 128 * 1024)))
		return ERR_INVAL;
	
	i = 0;
	blockaddr = CFG_FLASH_BASE;
	
	do
	{
		blockaddr += 128*1024;	
	}while(blockaddr <= addr);
	blockaddr = blockaddr - 128*1024;
	
	destaddr = addr;
	
	if(cnt == 1)
	{
		rc = write_byte (addr, *src);			//只有一个字节,直接写入完毕
		return rc;
	}
	
	lpacket = 0x20 - (addr & 0x1f); 
	if(lpacket < cnt)
		writebytes(src, blockaddr, destaddr, lpacket);
	else
	{
		writebytes(src, blockaddr, destaddr, cnt);	// 没有到边界,直接一次写入完毕
		return ERR_OK;
	}
	destaddr += lpacket;
	src += lpacket;
	lpacket = cnt - lpacket;

	
	while(lpacket > 32)
	{		
		do
		{
			blockaddr += 128*1024;	
		}while(blockaddr <= destaddr);
		blockaddr = blockaddr - 128*1024;
		
		writebytes(src, blockaddr, destaddr, 32);	//  循环写入32字节数据
		
		src += 32;
		destaddr += 32;
		lpacket -= 32;		
	}
	
	if(lpacket != 0)
	{
		do
		{
			blockaddr += 128*1024;	
		}while(blockaddr <= destaddr);
		blockaddr = blockaddr - 128*1024;
		
		writebytes(src, blockaddr, destaddr, lpacket);	
	}
	
	return ERR_OK;
}
Ejemplo n.º 17
0
int main(int argc, char **argv) {
    unsigned char reg;

    unsigned int num;
    int i;
    unsigned int mode;

    unsigned long long source_ksv = 0LL;
    unsigned long long sink_ksv = 0LL;
    unsigned long long ksv_temp = 0LL;
    unsigned long long Km = 0LL;
    unsigned long long Kmp = 0LL;
    
    unsigned long long old_Km = 0LL;
    
    unsigned long long source_pkey[40];
    unsigned long long sink_pkey[40];

    unsigned char compctl;
    unsigned char snoopctl;

    FILE *km_file;

    if(argc != 1) {
        fprintf(stderr, "Usage: %s\n", argv[0]);
        return 1;
    }

    // km sense changed to be a "semaphore" bit, use it here accordingly.

    /////////////
    // this region should be atomic
    compctl = read_byte(0x3);
    printf( "Checking semaphore...\n" );
    if( (compctl & 0x80) ) {
      // semaphore is set
      printf( "Semaphore set, someone else is running: exiting.\n" );
      return 1;
    }
    // however, atomicity can be broken here: on the other hand, structurally,
    // we guarantee nobody can steal the lock here by never triggering the HPD
    // event between the read and the modify-write

    // if we have atomicity problems, the solution is to implement the RMW operation
    // in the FPGA (i.e., a command that can read and grab the semaphore in one operation)
    compctl |= 0x80; // set the semaphore
    write_byte( 0x3, compctl );
    printf( "Grabbed semaphore!\n" );
    // this region should be atomic
    //////////////
    fflush(stdout);
    
    for( i = 6; i >= 0; i-- ) {
      old_Km <<= 8;
      old_Km |= read_byte( i + 0x19 ) & 0xff;
    }

    for( i = 0; i < 5; i++ ) {
      sink_ksv <<= 8;
      sink_ksv |= (snoop_hdcp_byte(4 - i) & 0xff);
    }

    for( i = 0; i < 5; i++ ) {
      source_ksv <<= 8;
      source_ksv |= (snoop_hdcp_byte(4 - i + 0x10) & 0xff);
    }

    printf( "source public ksv: %010llx\n", source_ksv );
    printf( "sink public ksv: %010llx\n", sink_ksv );
    compute_keys( source_ksv, SOURCE, source_pkey );
    compute_keys( sink_ksv, SINK, sink_pkey );


    ksv_temp = source_ksv; // source Ksv
    num = 0;
    for( i = 0; i < 40; i++ ) {
      if( ksv_temp & 1LL ) {
	num++;
	Km += sink_pkey[i]; // used to select sink's keys
	Km %=  72057594037927936LL;
	//	printf( "Km %014llx\n", Km );
      }
      ksv_temp >>= 1LL;
    }
    //    printf( "num 1's: %d\n", num );
    // km is the sink km

    ksv_temp = sink_ksv; // sink Ksv
    num = 0;
    for( i = 0; i < 40; i++ ) {
      if( ksv_temp & 1LL ) {
	num++;
	Kmp += source_pkey[i]; // used to select source's keys
	Kmp %=  72057594037927936LL;
	//	printf( "Kmp %014llx\n", Kmp );
      }
      ksv_temp >>= 1LL;
    }
    //    printf( "num 1's: %d\n", num );
    // Kmp is the source Km
  
    Km &= 0xFFFFFFFFFFFFFFLL;
    Kmp &= 0xFFFFFFFFFFFFFFLL;
  
    printf( "\n" );
    printf( "Km : %014llx\n", Km );
    printf( "Km': %014llx\n", Kmp );

    fflush(stdout);

    if( Km != Kmp ) {
      printf( "Km is not equal to Km', can't encrypt this stream.\n" );
      printf( "Releasing semaphore.\n" );
      compctl = read_byte(0x3); // refresh compctl in case other bits changed

      compctl &= 0x7F; // release semaphore
      write_byte( 0x3, compctl );
      exit(0);
    }

    if( Km == old_Km ) {
      printf( "Km is same as cached value, doing nothing.\n" );
      printf( "Releasing semaphore.\n" );
      compctl = read_byte(0x3); // refresh compctl in case other bits changed

      compctl &= 0x7F; // release semaphore
      write_byte( 0x3, compctl );
      
      // don't need to do anything, Km is correct
      return 0;
    } else if( Km == 0 ) {
      printf( "Km is zero. This probably means derive_km was fired spuriously on disconnect.\n" );
      printf( "Aborting without doing anything, since Km = 0 is never a correct condition\n" );
      printf( "Releasing semaphore.\n" );
      compctl = read_byte(0x3); // refresh compctl in case other bits changed

      compctl &= 0x7F; // release semaphore
      write_byte( 0x3, compctl );
      
      return 0;
    } else {
      
      km_file = fopen( "/psp/km_cache", "wb" );
      if( km_file == NULL ) {
	printf( "can't open km_file to write cache...but letting life go on.\n" );
      } else {
	// write out the Km to the cache file

	// this is a totally-device and compiler-dependent way to do this
	// but it's fast and easy and it's just cache data so who cares
	fwrite(&Km, sizeof(unsigned long long), 1, km_file);
	fflush(km_file);
	fclose(km_file);
      }
      
      // now commit Km to the fpga
      for( i = 0; i < 7; i++ ) {
	write_byte( i + 0x19, Km & 0xFF );
	Km >>= 8;
      }
      
      // invoke HPD to re-load the stream
      snoopctl = read_byte(0x0);
      snoopctl |= 0x08;  // force HPD, leave all other bits intact
      write_byte( 0x0, snoopctl ); // hpd is now forcing

      printf( "Km has changed since last value, initiating HPD reset of stream and updating cache. This will take 3 seconds.");
      fflush(stdout);
      // wait
      sleep(2);
      printf( "." );
      fflush(stdout);
      snoopctl &= 0xF7;
      write_byte( 0x0, snoopctl ); // hpd is now releasing

      // wait
      for( i = 0; i < 2; i ++ ) {
	printf( "." );
	fflush(stdout);
	sleep(1); // this is the dead-zone where we try to keep the semaphore locked down
	// to prevent a recursive derive_km/HPD loop nightmare
	// if someone is just jamming cables in and out really fast, it could cause
	// problems
      }
      
      printf( "\nDone. Releasing semaphore.\n" );
      // then release semaphore
      compctl = read_byte(0x3); // refresh compctl in case other bits changed

      compctl &= 0x7F; // release semaphore
      write_byte( 0x3, compctl );
    }

    return 0;
}
Ejemplo n.º 18
0
Archivo: disk.c Proyecto: apaka/vbox
void BIOSCALL int13_harddisk(disk_regs_t r)
{
    uint32_t            lba;
    uint16_t            cylinder, head, sector;
    uint16_t            nlc, nlh, nlspt;
    uint16_t            count;
    uint8_t             device, status;
    bio_dsk_t __far     *bios_dsk;

    BX_DEBUG_INT13_HD("%s: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", __func__, AX, BX, CX, DX, ES);

    bios_dsk = read_word(0x0040,0x000E) :> &EbdaData->bdisk;
    write_byte(0x0040, 0x008e, 0);  // clear completion flag
    
    // basic check : device has to be defined
    if ( (GET_ELDL() < 0x80) || (GET_ELDL() >= 0x80 + BX_MAX_STORAGE_DEVICES) ) {
        BX_DEBUG("%s: function %02x, ELDL out of range %02x\n", __func__, GET_AH(), GET_ELDL());
        goto int13_fail;
    }
    
    // Get the ata channel
    device = bios_dsk->hdidmap[GET_ELDL()-0x80];
    
    // basic check : device has to be valid
    if (device >= BX_MAX_STORAGE_DEVICES) {
        BX_DEBUG("%s: function %02x, unmapped device for ELDL=%02x\n", __func__, GET_AH(), GET_ELDL());
        goto int13_fail;
    }

    switch (GET_AH()) {

    case 0x00: /* disk controller reset */
#ifdef VBOX_WITH_SCSI
        /* SCSI controller does not need a reset. */
        if (!VBOX_IS_SCSI_DEVICE(device))
#endif
        ata_reset (device);
        goto int13_success;
        break;

    case 0x01: /* read disk status */
        status = read_byte(0x0040, 0x0074);
        SET_AH(status);
        SET_DISK_RET_STATUS(0);
        /* set CF if error status read */
        if (status) goto int13_fail_nostatus;
        else        goto int13_success_noah;
        break;

    case 0x02: // read disk sectors
    case 0x03: // write disk sectors
    case 0x04: // verify disk sectors

        count       = GET_AL();
        cylinder    = GET_CH();
        cylinder   |= ( ((uint16_t) GET_CL()) << 2) & 0x300;
        sector      = (GET_CL() & 0x3f);
        head        = GET_DH();
        
        /* Segment and offset are in ES:BX. */        
        if ( (count > 128) || (count == 0) ) {
            BX_INFO("%s: function %02x, count out of range!\n", __func__, GET_AH());
            goto int13_fail;
        }

        /* Get the logical CHS geometry. */
        nlc   = bios_dsk->devices[device].lchs.cylinders;
        nlh   = bios_dsk->devices[device].lchs.heads;
        nlspt = bios_dsk->devices[device].lchs.spt;

        /* Sanity check the geometry. */
        if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt )) {
            BX_INFO("%s: function %02x, disk %02x, parameters out of range %04x/%04x/%04x!\n", __func__, GET_AH(), GET_DL(), cylinder, head, sector);
            goto int13_fail;
        }
        
        // FIXME verify
        if ( GET_AH() == 0x04 )
            goto int13_success;

        /* If required, translate LCHS to LBA and execute command. */
        //@todo: The IS_SCSI_DEVICE check should be redundant...
        if (( (bios_dsk->devices[device].pchs.heads != nlh) || (bios_dsk->devices[device].pchs.spt != nlspt)) || VBOX_IS_SCSI_DEVICE(device)) {
            lba = ((((uint32_t)cylinder * (uint32_t)nlh) + (uint32_t)head) * (uint32_t)nlspt) + (uint32_t)sector - 1;
            sector = 0; // this forces the command to be lba
        }

        /* Clear the count of transferred sectors/bytes. */
        bios_dsk->drqp.trsfsectors = 0;
        bios_dsk->drqp.trsfbytes   = 0;

        /* Pass request information to low level disk code. */
        bios_dsk->drqp.lba      = lba;
        bios_dsk->drqp.buffer   = MK_FP(ES, BX);
        bios_dsk->drqp.nsect    = count;
        bios_dsk->drqp.sect_sz  = 512;  //@todo: device specific?
        bios_dsk->drqp.cylinder = cylinder;
        bios_dsk->drqp.head     = head;
        bios_dsk->drqp.sector   = sector;
        bios_dsk->drqp.dev_id   = device;

        status = dskacc[bios_dsk->devices[device].type].a[GET_AH() - 0x02](bios_dsk);

        // Set nb of sector transferred
        SET_AL(bios_dsk->drqp.trsfsectors);
        
        if (status != 0) {
            BX_INFO("%s: function %02x, error %02x !\n", __func__, GET_AH(), status);
            SET_AH(0x0c);
            goto int13_fail_noah;
        }
        
        goto int13_success;
        break;

    case 0x05: /* format disk track */
          BX_INFO("format disk track called\n");
          goto int13_success;
          return;
          break;

    case 0x08: /* read disk drive parameters */

        /* Get the logical geometry from internal table. */
        nlc   = bios_dsk->devices[device].lchs.cylinders;
        nlh   = bios_dsk->devices[device].lchs.heads;
        nlspt = bios_dsk->devices[device].lchs.spt;

        count = bios_dsk->hdcount;
        /* Maximum cylinder number is just one less than the number of cylinders. */
        nlc = nlc - 1; /* 0 based , last sector not used */
        SET_AL(0);
        SET_CH(nlc & 0xff);
        SET_CL(((nlc >> 2) & 0xc0) | (nlspt & 0x3f));
        SET_DH(nlh - 1);
        SET_DL(count); /* FIXME returns 0, 1, or n hard drives */
        
        // FIXME should set ES & DI
        // @todo: Actually, the above comment is nonsense.
        
        goto int13_success;
        break;

    case 0x10: /* check drive ready */
        // should look at 40:8E also???

        // Read the status from controller
        status = inb(bios_dsk->channels[device/2].iobase1 + ATA_CB_STAT);
        if ( (status & ( ATA_CB_STAT_BSY | ATA_CB_STAT_RDY )) == ATA_CB_STAT_RDY ) {
            goto int13_success;
        } else {
            SET_AH(0xAA);
            goto int13_fail_noah;
        }
        break;

    case 0x15: /* read disk drive size */

        /* Get the physical geometry from internal table. */
        cylinder = bios_dsk->devices[device].pchs.cylinders;
        head     = bios_dsk->devices[device].pchs.heads;
        sector   = bios_dsk->devices[device].pchs.spt;

        /* Calculate sector count seen by old style INT 13h. */
        lba = (uint32_t)cylinder * head * sector;
        CX = lba >> 16;
        DX = lba & 0xffff;
        
        SET_AH(3);  // hard disk accessible
        goto int13_success_noah;
        break;

    case 0x09: /* initialize drive parameters */
    case 0x0c: /* seek to specified cylinder */
    case 0x0d: /* alternate disk reset */
    case 0x11: /* recalibrate */
    case 0x14: /* controller internal diagnostic */
        BX_INFO("%s: function %02xh unimplemented, returns success\n", __func__, GET_AH());
        goto int13_success;
        break;

    case 0x0a: /* read disk sectors with ECC */
    case 0x0b: /* write disk sectors with ECC */
    case 0x18: // set media type for format
    default:
        BX_INFO("%s: function %02xh unsupported, returns fail\n", __func__, GET_AH());
        goto int13_fail;
        break;
    }

int13_fail:
    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
int13_fail_noah:
    SET_DISK_RET_STATUS(GET_AH());
int13_fail_nostatus:
    SET_CF();     // error occurred
    return;

int13_success:
    SET_AH(0x00); // no error
int13_success_noah:
    SET_DISK_RET_STATUS(0x00);
    CLEAR_CF();   // no error
    return;
}
Ejemplo n.º 19
0
void init_accel(void){
	val = read_byte(0x00); //read dev id
	write_byte(0x2D, 0x08); // set to measurement mode
	write_byte(0x31, 0x00); // set data format - +/- 2g, right justified with SE

}
Ejemplo n.º 20
0
Archivo: disk.c Proyecto: apaka/vbox
void BIOSCALL int13_harddisk_ext(disk_regs_t r)
{
    uint32_t            lba;
    uint16_t            ebda_seg = read_word(0x0040,0x000E);
    uint16_t            segment, offset;
    uint16_t            npc, nph, npspt;
    uint16_t            size, count;
    uint8_t             device, status;
    uint8_t             type;
    bio_dsk_t __far     *bios_dsk;
    int13ext_t __far    *i13_ext;
    dpt_t __far         *dpt;

    bios_dsk = read_word(0x0040,0x000E) :> &EbdaData->bdisk;

    BX_DEBUG_INT13_HD("%s: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", __func__, AX, BX, CX, DX, ES);
    
    write_byte(0x0040, 0x008e, 0);  // clear completion flag
    
    // basic check : device has to be defined
    if ( (GET_ELDL() < 0x80) || (GET_ELDL() >= 0x80 + BX_MAX_STORAGE_DEVICES) ) {
        BX_DEBUG("%s: function %02x, ELDL out of range %02x\n", __func__, GET_AH(), GET_ELDL());
        goto int13x_fail;
    }
    
    // Get the ata channel
    device = bios_dsk->hdidmap[GET_ELDL()-0x80];
    
    // basic check : device has to be valid
    if (device >= BX_MAX_STORAGE_DEVICES) {
        BX_DEBUG("%s: function %02x, unmapped device for ELDL=%02x\n", __func__, GET_AH(), GET_ELDL());
        goto int13x_fail;
    }

    switch (GET_AH()) {
    case 0x41: // IBM/MS installation check
        BX=0xaa55;     // install check
        SET_AH(0x30);  // EDD 3.0
        CX=0x0007;     // ext disk access and edd, removable supported
        goto int13x_success_noah;
        break;

    case 0x42: // IBM/MS extended read
    case 0x43: // IBM/MS extended write
    case 0x44: // IBM/MS verify
    case 0x47: // IBM/MS extended seek

        /* Get a pointer to the extended structure. */
        i13_ext = DS :> (int13ext_t *)SI;

        count   = i13_ext->count;
        segment = i13_ext->segment;
        offset  = i13_ext->offset;

        BX_DEBUG_INT13_HD("%s: %d sectors from lba %u @ %04x:%04x\n", __func__, 
                          count, i13_ext->lba1, segment, offset);

        // Can't use 64 bits lba
        lba = i13_ext->lba2;
        if (lba != 0L) {
            BX_PANIC("%s: function %02x. Can't use 64bits lba\n", __func__, GET_AH());
            goto int13x_fail;
        }
        
        // Get 32 bits lba and check
        lba = i13_ext->lba1;

        type = bios_dsk->devices[device].type;
        if (lba >= bios_dsk->devices[device].sectors) {
              BX_INFO("%s: function %02x. LBA out of range\n", __func__, GET_AH());
              goto int13x_fail;
        }

        /* Don't bother with seek or verify. */
        if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
            goto int13x_success;

        /* Clear the count of transferred sectors/bytes. */
        bios_dsk->drqp.trsfsectors = 0;
        bios_dsk->drqp.trsfbytes   = 0;

        /* Pass request information to low level disk code. */
        bios_dsk->drqp.lba     = lba;
        bios_dsk->drqp.buffer  = MK_FP(segment, offset);
        bios_dsk->drqp.nsect   = count;
        bios_dsk->drqp.sect_sz = 512;   //@todo: device specific?
        bios_dsk->drqp.sector  = 0;     /* Indicate LBA. */
        bios_dsk->drqp.dev_id  = device;
        
        /* Execute the read or write command. */
        status = dskacc[type].a[GET_AH() - 0x42](bios_dsk);
        count  = bios_dsk->drqp.trsfsectors;
        i13_ext->count = count;
        
        if (status != 0) {
            BX_INFO("%s: function %02x, error %02x !\n", __func__, GET_AH(), status);
            SET_AH(0x0c);
            goto int13x_fail_noah;
        }
        
        goto int13x_success;
        break;

    case 0x45: // IBM/MS lock/unlock drive
    case 0x49: // IBM/MS extended media change
        goto int13x_success;   // Always success for HD
        break;

    case 0x46: // IBM/MS eject media
        SET_AH(0xb2);          // Volume Not Removable
        goto int13x_fail_noah; // Always fail for HD
        break;

    case 0x48: // IBM/MS get drive parameters
        dpt = DS :> (dpt_t *)SI;
        size = dpt->size;

        /* Check if buffer is large enough. */
        if (size < 0x1a)
            goto int13x_fail;
        
        /* Fill in EDD 1.x table. */
        if (size >= 0x1a) {
            uint16_t   blksize;

            npc     = bios_dsk->devices[device].pchs.cylinders;
            nph     = bios_dsk->devices[device].pchs.heads;
            npspt   = bios_dsk->devices[device].pchs.spt;
            lba     = bios_dsk->devices[device].sectors;
            blksize = bios_dsk->devices[device].blksize;

            dpt->size      = 0x1a;
            dpt->infos     = 0x02;  // geometry is valid
            dpt->cylinders = npc;
            dpt->heads     = nph;
            dpt->spt       = npspt;
            dpt->blksize   = blksize;
            dpt->sector_count1 = lba;   // FIXME should be Bit64
            dpt->sector_count2 = 0;
        }

        /* Fill in EDD 2.x table. */
        if (size >= 0x1e) {
            uint8_t     channel, irq, mode, checksum, i, translation;
            uint16_t    iobase1, iobase2, options;
            
            dpt->size = 0x1e;
            dpt->dpte_segment = ebda_seg;
            dpt->dpte_offset  = (uint16_t)&EbdaData->bdisk.dpte;
            
            // Fill in dpte
            channel = device / 2;
            iobase1 = bios_dsk->channels[channel].iobase1;
            iobase2 = bios_dsk->channels[channel].iobase2;
            irq     = bios_dsk->channels[channel].irq;
            mode    = bios_dsk->devices[device].mode;
            translation = bios_dsk->devices[device].translation;
            
            options  = (translation == GEO_TRANSLATION_NONE ? 0 : 1 << 3);  // chs translation
            options |= (1 << 4);    // lba translation
            options |= (mode == ATA_MODE_PIO32 ? 1 : 0 << 7);
            options |= (translation == GEO_TRANSLATION_LBA ? 1 : 0 << 9);
            options |= (translation == GEO_TRANSLATION_RECHS ? 3 : 0 << 9);
            
            bios_dsk->dpte.iobase1  = iobase1;
            bios_dsk->dpte.iobase2  = iobase2;
            bios_dsk->dpte.prefix   = (0xe | (device % 2)) << 4;
            bios_dsk->dpte.unused   = 0xcb;
            bios_dsk->dpte.irq      = irq;
            bios_dsk->dpte.blkcount = 1;
            bios_dsk->dpte.dma      = 0;
            bios_dsk->dpte.pio      = 0;
            bios_dsk->dpte.options  = options;
            bios_dsk->dpte.reserved = 0;
            bios_dsk->dpte.revision = 0x11;
            
            checksum = 0;
            for (i = 0; i < 15; ++i)
                checksum += read_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.dpte + i);
            checksum = -checksum;
            bios_dsk->dpte.checksum = checksum;
        }

        /* Fill in EDD 3.x table. */
        if(size >= 0x42) {
            uint8_t     channel, iface, checksum, i;
            uint16_t    iobase1;

            channel = device / 2;
            iface   = bios_dsk->channels[channel].iface;
            iobase1 = bios_dsk->channels[channel].iobase1;
            
            dpt->size       = 0x42;
            dpt->key        = 0xbedd;
            dpt->dpi_length = 0x24;
            dpt->reserved1  = 0;
            dpt->reserved2  = 0;
            
            if (iface == ATA_IFACE_ISA) {
                dpt->host_bus[0] = 'I';
                dpt->host_bus[1] = 'S';
                dpt->host_bus[2] = 'A';
                dpt->host_bus[3] = ' ';
            }
            else {
                // FIXME PCI
            }
            dpt->iface_type[0] = 'A';
            dpt->iface_type[1] = 'T';
            dpt->iface_type[2] = 'A';
            dpt->iface_type[3] = ' ';
            dpt->iface_type[4] = ' ';
            dpt->iface_type[5] = ' ';
            dpt->iface_type[6] = ' ';
            dpt->iface_type[7] = ' ';
            
            if (iface == ATA_IFACE_ISA) {
                ((uint16_t __far *)dpt->iface_path)[0] = iobase1;
                ((uint16_t __far *)dpt->iface_path)[1] = 0;
                ((uint32_t __far *)dpt->iface_path)[1] = 0;
            }
            else {
                // FIXME PCI
            }
            ((uint16_t __far *)dpt->device_path)[0] = device & 1; // device % 2; @todo: correct?
            ((uint16_t __far *)dpt->device_path)[1] = 0;
            ((uint32_t __far *)dpt->device_path)[1] = 0;
            
            checksum = 0;
            for (i = 30; i < 64; i++)
                checksum += read_byte(DS, SI + i);
            checksum = -checksum;
            dpt->checksum = checksum;
        }

        goto int13x_success;
        break;

    case 0x4e: // // IBM/MS set hardware configuration
        // DMA, prefetch, PIO maximum not supported
        switch (GET_AL()) {
        case 0x01:
        case 0x03:
        case 0x04:
        case 0x06:
            goto int13x_success;
            break;
        default :
            goto int13x_fail;
        }
        break;

    case 0x50: // IBM/MS send packet command
    default:
        BX_INFO("%s: function %02xh unsupported, returns fail\n", __func__, GET_AH());
        goto int13x_fail;
        break;
    }

int13x_fail:
    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
int13x_fail_noah:
    SET_DISK_RET_STATUS(GET_AH());
    SET_CF();     // error occurred
    return;

int13x_success:
    SET_AH(0x00); // no error
int13x_success_noah:
    SET_DISK_RET_STATUS(0x00);
    CLEAR_CF();   // no error
    return;
}
Ejemplo n.º 21
0
void _wait_degrees(int degrees) {
	write_byte(OI_WAIT_ANGLE);
	write_byte(get_high_byte(degrees));
	write_byte(get_low_byte(degrees));
}
Ejemplo n.º 22
0
void setup_protocol(int f_out,int f_in)
{
	if (am_sender)
		file_extra_cnt += PTR_EXTRA_CNT;
	else
		file_extra_cnt++;
	if (preserve_uid)
		uid_ndx = ++file_extra_cnt;
	if (preserve_gid)
		gid_ndx = ++file_extra_cnt;
	if (preserve_acls && !am_sender)
		acls_ndx = ++file_extra_cnt;
	if (preserve_xattrs)
		xattrs_ndx = ++file_extra_cnt;

	if (am_server)
		set_allow_inc_recurse();

	if (remote_protocol == 0) {
		if (am_server && !local_server)
			check_sub_protocol();
		if (!read_batch)
			write_int(f_out, protocol_version);
		remote_protocol = read_int(f_in);
		if (protocol_version > remote_protocol)
			protocol_version = remote_protocol;
	}
	if (read_batch && remote_protocol > protocol_version) {
		rprintf(FERROR, "The protocol version in the batch file is too new (%d > %d).\n",
			remote_protocol, protocol_version);
		exit_cleanup(RERR_PROTOCOL);
	}

	if (DEBUG_GTE(PROTO, 1)) {
		rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
			am_server? "Server" : "Client", remote_protocol, protocol_version);
	}
	if (remote_protocol < MIN_PROTOCOL_VERSION
	 || remote_protocol > MAX_PROTOCOL_VERSION) {
		rprintf(FERROR,"protocol version mismatch -- is your shell clean?\n");
		rprintf(FERROR,"(see the rsync man page for an explanation)\n");
		exit_cleanup(RERR_PROTOCOL);
	}
	if (remote_protocol < OLD_PROTOCOL_VERSION) {
		rprintf(FINFO,"%s is very old version of rsync, upgrade recommended.\n",
			am_server? "Client" : "Server");
	}
	if (protocol_version < MIN_PROTOCOL_VERSION) {
		rprintf(FERROR, "--protocol must be at least %d on the %s.\n",
			MIN_PROTOCOL_VERSION, am_server? "Server" : "Client");
		exit_cleanup(RERR_PROTOCOL);
	}
	if (protocol_version > PROTOCOL_VERSION) {
		rprintf(FERROR, "--protocol must be no more than %d on the %s.\n",
			PROTOCOL_VERSION, am_server? "Server" : "Client");
		exit_cleanup(RERR_PROTOCOL);
	}
	if (read_batch)
		check_batch_flags();

#ifndef SUPPORT_PREALLOCATION
	if (preallocate_files && !am_sender) {
		rprintf(FERROR, "preallocation is not supported on this %s\n",
			am_server ? "Server" : "Client");
		exit_cleanup(RERR_SYNTAX);
	}
#endif

	if (protocol_version < 30) {
		if (append_mode == 1)
			append_mode = 2;
		if (preserve_acls && !local_server) {
			rprintf(FERROR,
			    "--acls requires protocol 30 or higher"
			    " (negotiated %d).\n",
			    protocol_version);
			exit_cleanup(RERR_PROTOCOL);
		}
		if (preserve_xattrs && !local_server) {
			rprintf(FERROR,
			    "--xattrs requires protocol 30 or higher"
			    " (negotiated %d).\n",
			    protocol_version);
			exit_cleanup(RERR_PROTOCOL);
		}
	}

	if (delete_mode && !(delete_before+delete_during+delete_after)) {
		if (protocol_version < 30)
			delete_before = 1;
		else
			delete_during = 1;
	}

	if (protocol_version < 29) {
		if (fuzzy_basis) {
			rprintf(FERROR,
			    "--fuzzy requires protocol 29 or higher"
			    " (negotiated %d).\n",
			    protocol_version);
			exit_cleanup(RERR_PROTOCOL);
		}

		if (basis_dir_cnt && inplace) {
			rprintf(FERROR,
			    "%s with --inplace requires protocol 29 or higher"
			    " (negotiated %d).\n",
			    dest_option, protocol_version);
			exit_cleanup(RERR_PROTOCOL);
		}

		if (basis_dir_cnt > 1) {
			rprintf(FERROR,
			    "Using more than one %s option requires protocol"
			    " 29 or higher (negotiated %d).\n",
			    dest_option, protocol_version);
			exit_cleanup(RERR_PROTOCOL);
		}

		if (prune_empty_dirs) {
			rprintf(FERROR,
			    "--prune-empty-dirs requires protocol 29 or higher"
			    " (negotiated %d).\n",
			    protocol_version);
			exit_cleanup(RERR_PROTOCOL);
		}
	} else if (protocol_version >= 30) {
		if (am_server) {
			compat_flags = allow_inc_recurse ? CF_INC_RECURSE : 0;
#ifdef CAN_SET_SYMLINK_TIMES
			compat_flags |= CF_SYMLINK_TIMES;
#endif
#ifdef ICONV_OPTION
			compat_flags |= CF_SYMLINK_ICONV;
#endif
			if (local_server || strchr(client_info, 'f') != NULL)
				compat_flags |= CF_SAFE_FLIST;
			if (local_server || strchr(client_info, 'x') != NULL)
				compat_flags |= CF_AVOID_XATTR_OPTIM;
			write_byte(f_out, compat_flags);
		} else
			compat_flags = read_byte(f_in);
		/* The inc_recurse var MUST be set to 0 or 1. */
		inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0;
		want_xattr_optim = protocol_version >= 31 && !(compat_flags & CF_AVOID_XATTR_OPTIM);
		if (am_sender) {
			receiver_symlink_times = am_server
			    ? strchr(client_info, 'L') != NULL
			    : !!(compat_flags & CF_SYMLINK_TIMES);
		}
#ifdef CAN_SET_SYMLINK_TIMES
		else
			receiver_symlink_times = 1;
#endif
#ifdef ICONV_OPTION
		sender_symlink_iconv = iconv_opt && (am_server
		    ? local_server || strchr(client_info, 's') != NULL
		    : !!(compat_flags & CF_SYMLINK_ICONV));
#endif
		if (inc_recurse && !allow_inc_recurse) {
			/* This should only be able to happen in a batch. */
			fprintf(stderr,
			    "Incompatible options specified for inc-recursive %s.\n",
			    read_batch ? "batch file" : "connection");
			exit_cleanup(RERR_SYNTAX);
		}
		use_safe_inc_flist = (compat_flags & CF_SAFE_FLIST) || protocol_version >= 31;
		need_messages_from_generator = 1;
#ifdef CAN_SET_SYMLINK_TIMES
	} else if (!am_sender) {
		receiver_symlink_times = 1;
#endif
	}

	if (need_unsorted_flist && (!am_sender || inc_recurse))
		unsort_ndx = ++file_extra_cnt;

	if (partial_dir && *partial_dir != '/' && (!am_server || local_server)) {
		int rflags = FILTRULE_NO_PREFIXES | FILTRULE_DIRECTORY;
		if (!am_sender || protocol_version >= 30)
			rflags |= FILTRULE_PERISHABLE;
		parse_filter_str(&filter_list, partial_dir, rule_template(rflags), 0);
	}


#ifdef ICONV_OPTION
	if (protect_args && files_from) {
		if (am_sender)
			filesfrom_convert = filesfrom_host && ic_send != (iconv_t)-1;
		else
			filesfrom_convert = !filesfrom_host && ic_recv != (iconv_t)-1;
	}
#endif

	if (am_server) {
		if (!checksum_seed)
			checksum_seed = time(NULL);
		write_int(f_out, checksum_seed);
	} else {
		checksum_seed = read_int(f_in);
	}
}
Ejemplo n.º 23
0
irqreturn_t tms9914_interrupt_have_status(gpib_board_t *board, tms9914_private_t *priv, int status0,
		int status1)
{
	// record reception of END
	if(status0 & HR_END)
	{
		set_bit(RECEIVED_END_BN, &priv->state);
	}

	// get incoming data in PIO mode
	if((status0 & HR_BI))
	{
		set_bit(READ_READY_BN, &priv->state);
	}

	if((status0 & HR_BO))
	{
		if(read_byte(priv, ADSR) & HR_ATN)
		{
			set_bit(COMMAND_READY_BN, &priv->state);
		}else
		{
			set_bit(WRITE_READY_BN, &priv->state);
		}
	}

	if(status0 & HR_SPAS)
	{
		priv->spoll_status &= ~request_service_bit;
		write_byte(priv, priv->spoll_status, SPMR);
		//FIXME: set SPOLL status bit
	}

	// record service request in status
	if(status1 & HR_SRQ)
	{
		set_bit(SRQI_NUM, &board->status);
	}

	// have been addressed (with secondary addressing disabled)
	if(status1 & HR_MA)
	{
		// clear dac holdoff
		write_byte(priv, AUX_VAL, AUXCR);
	}

	// unrecognized command received
	if(status1 & HR_UNC)
	{
		unsigned short command_byte = read_byte(priv, CPTR);
// 		printk("tms9914: command pass thru 0x%x\n", command_byte);
		switch(command_byte)
		{
		case PPConfig:
			priv->ppoll_configure_state = 1;
			write_byte(priv, AUX_PTS, AUXCR);
			write_byte(priv, AUX_VAL, AUXCR);
			break;
		case PPU:
			tms9914_parallel_poll_configure(board, priv, PPD);
			write_byte(priv, AUX_VAL, AUXCR);	
		default:
			if(priv->ppoll_configure_state)
			{
				priv->ppoll_configure_state = 0;
				if(command_byte >= PPE && command_byte <= PPD + 0xd)
				{
					tms9914_parallel_poll_configure(board, priv, command_byte);
					write_byte(priv, AUX_VAL, AUXCR);
				}else
				{
					printk("tms9914: bad parallel poll configure byte, command pass thru 0x%x\n", command_byte);
					write_byte(priv, AUX_INVAL, AUXCR);
				}
				break;
			}
			printk("tms9914: unknown gpib command pass thru 0x%x\n", command_byte);
			// clear dac holdoff
			write_byte(priv, AUX_INVAL, AUXCR);
			break;
		}
	}

	if(status1 & HR_ERR)
	{
		GPIB_DPRINTK( "gpib bus error\n");
		set_bit( BUS_ERROR_BN, &priv->state );
	}

	if( status1 & HR_IFC )
	{
		push_gpib_event( board, EventIFC );
		clear_bit(CIC_NUM, &board->status);
	}

	if( status1 & HR_GET )
	{
		push_gpib_event( board, EventDevTrg );
		// clear dac holdoff
		write_byte(priv, AUX_VAL, AUXCR);
	}

	if( status1 & HR_DCAS )
	{
		push_gpib_event( board, EventDevClr );
		// clear dac holdoff
		write_byte(priv, AUX_VAL, AUXCR);
		set_bit( DEV_CLEAR_BN, &priv->state );
	}

	// check for being addressed with secondary addressing
	if( status1 & HR_APT )
	{
		if( board->sad < 0 )
		{
			printk( "tms9914: bug, APT interrupt without secondary addressing?\n" );
		}
		if( read_byte( priv, CPTR ) == MSA( board->sad ) )
		{
			write_byte(priv, AUX_VAL, AUXCR);
		}else
			write_byte(priv, AUX_INVAL, AUXCR);
	}

	if( ( status0 & priv->imr0_bits ) || ( status1 & priv->imr1_bits ) )
	{
		GPIB_DPRINTK("isr0 0x%x, imr0 0x%x, isr1 0x%x, imr1 0x%x\n",
			status0, priv->imr0_bits, status1, priv->imr1_bits );
		update_status_nolock( board, priv );
		wake_up_interruptible( &board->wait );
	}
	return IRQ_HANDLED;
}
Ejemplo n.º 24
0
/**
 * Enumerate attached devices.
 *
 * @returns nothing.
 * @param   io_base    The I/O base port of the controller.
 */
void scsi_enumerate_attached_devices(uint16_t io_base)
{
    int                 i;
    uint8_t             buffer[0x0200];
    bio_dsk_t __far     *bios_dsk;

    bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;

    /* Go through target devices. */
    for (i = 0; i < VBSCSI_MAX_DEVICES; i++)
    {
        uint8_t     rc;
        uint8_t     aCDB[10];

        aCDB[0] = SCSI_INQUIRY;
        aCDB[1] = 0;
        aCDB[2] = 0;
        aCDB[3] = 0;
        aCDB[4] = 5; /* Allocation length. */
        aCDB[5] = 0;

        rc = scsi_cmd_data_in(io_base, i, aCDB, 6, buffer, 5);
        if (rc != 0)
            BX_PANIC("scsi_enumerate_attached_devices: SCSI_INQUIRY failed\n");

        /* Check if there is a disk attached. */
        if (   ((buffer[0] & 0xe0) == 0)
            && ((buffer[0] & 0x1f) == 0x00))
        {
            VBSCSI_DEBUG("scsi_enumerate_attached_devices: Disk detected at %d\n", i);

            /* We add the disk only if the maximum is not reached yet. */
            if (bios_dsk->scsi_hdcount < BX_MAX_SCSI_DEVICES)
            {
                uint32_t    sectors, sector_size, cylinders;
                uint16_t    heads, sectors_per_track;
                uint8_t     hdcount, hdcount_scsi, hd_index;

                /* Issue a read capacity command now. */
                _fmemset(aCDB, 0, sizeof(aCDB));
                aCDB[0] = SCSI_READ_CAPACITY;

                rc = scsi_cmd_data_in(io_base, i, aCDB, 10, buffer, 8);
                if (rc != 0)
                    BX_PANIC("scsi_enumerate_attached_devices: SCSI_READ_CAPACITY failed\n");

                /* Build sector number and size from the buffer. */
                //@todo: byte swapping for dword sized items should be farmed out...
                sectors =   ((uint32_t)buffer[0] << 24)
                          | ((uint32_t)buffer[1] << 16)
                          | ((uint32_t)buffer[2] << 8)
                          | ((uint32_t)buffer[3]);

                sector_size =   ((uint32_t)buffer[4] << 24)
                              | ((uint32_t)buffer[5] << 16)
                              | ((uint32_t)buffer[6] << 8)
                              | ((uint32_t)buffer[7]);

                /* We only support the disk if sector size is 512 bytes. */
                if (sector_size != 512)
                {
                    /* Leave a log entry. */
                    BX_INFO("Disk %d has an unsupported sector size of %u\n", i, sector_size);
                    continue;
                }

                /* We need to calculate the geometry for the disk. From 
                 * the BusLogic driver in the Linux kernel. 
                 */
                if (sectors >= (uint32_t)4 * 1024 * 1024)
                {
                    heads = 255;
                    sectors_per_track = 63;
                }
                else if (sectors >= (uint32_t)2 * 1024 * 1024)
                {
                    heads = 128;
                    sectors_per_track = 32;
                }
                else
                {
                    heads = 64;
                    sectors_per_track = 32;
                }
                cylinders = (uint32_t)(sectors / (heads * sectors_per_track));
                hdcount_scsi = bios_dsk->scsi_hdcount;

                /* Calculate index into the generic disk table. */
                hd_index = hdcount_scsi + BX_MAX_ATA_DEVICES;

                bios_dsk->scsidev[hdcount_scsi].io_base   = io_base;
                bios_dsk->scsidev[hdcount_scsi].target_id = i;
                bios_dsk->devices[hd_index].type        = DSK_TYPE_SCSI;
                bios_dsk->devices[hd_index].device      = DSK_DEVICE_HD;
                bios_dsk->devices[hd_index].removable   = 0;
                bios_dsk->devices[hd_index].lock        = 0;
                bios_dsk->devices[hd_index].blksize     = sector_size;
                bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_LBA;

                /* Write LCHS values. */
                bios_dsk->devices[hd_index].lchs.heads = heads;
                bios_dsk->devices[hd_index].lchs.spt   = sectors_per_track;
                if (cylinders > 1024)
                    bios_dsk->devices[hd_index].lchs.cylinders = 1024;
                else
                    bios_dsk->devices[hd_index].lchs.cylinders = (uint16_t)cylinders;

                /* Write PCHS values. */
                bios_dsk->devices[hd_index].pchs.heads = heads;
                bios_dsk->devices[hd_index].pchs.spt   = sectors_per_track;
                if (cylinders > 1024)
                    bios_dsk->devices[hd_index].pchs.cylinders = 1024;
                else
                    bios_dsk->devices[hd_index].pchs.cylinders = (uint16_t)cylinders;

                bios_dsk->devices[hd_index].sectors = sectors;

                /* Store the id of the disk in the ata hdidmap. */
                hdcount = bios_dsk->hdcount;
                bios_dsk->hdidmap[hdcount] = hdcount_scsi + BX_MAX_ATA_DEVICES;
                hdcount++;
                bios_dsk->hdcount = hdcount;

                /* Update hdcount in the BDA. */
                hdcount = read_byte(0x40, 0x75);
                hdcount++;
                write_byte(0x40, 0x75, hdcount);

                hdcount_scsi++;
                bios_dsk->scsi_hdcount = hdcount_scsi;
            }
            else
            {
                /* We reached the maximum of SCSI disks we can boot from. We can quit detecting. */
                break;
            }
        }
        else
            VBSCSI_DEBUG("scsi_enumerate_attached_devices: No disk detected at %d\n", i);
    }
}
Ejemplo n.º 25
0
static void write_header(TABDCA *dca, struct dbf *dbf)
{     /* write xBASE data file header */
      int j, k, temp;
      const char *name;
      /* version number */
      write_byte(dbf, 0x03 /* file without DBT */);
      /* date of last update (YYMMDD) */
      write_byte(dbf, 70 /* 1970 */);
      write_byte(dbf, 1 /* January */);
      write_byte(dbf, 1 /* 1st */);
      /* number of records (unknown so far) */
      for (j = 1; j <= 4; j++)
         write_byte(dbf, 0xFF);
      /* length of the header, in bytes */
      temp = 32 + dbf->nf * 32 + 1;
      write_byte(dbf, temp);
      write_byte(dbf, temp >> 8);
      /* length of each record, in bytes */
      temp = 1;
      for (k = 1; k <= dbf->nf; k++)
         temp += dbf->len[k];
      write_byte(dbf, temp);
      write_byte(dbf, temp >> 8);
      /* (reserved) */
      for (j = 1; j <= 20; j++)
         write_byte(dbf, 0x00);
      /* field descriptor array */
      for (k = 1; k <= dbf->nf; k++)
      {  /* field name (terminated by 0x00) */
         name = mpl_tab_get_name(dca, k);
         for (j = 0; j < 10 && name[j] != '\0'; j++)
            write_byte(dbf, name[j]);
         for (j = j; j < 11; j++)
            write_byte(dbf, 0x00);
         /* field type */
         write_byte(dbf, dbf->type[k]);
         /* (reserved) */
         for (j = 1; j <= 4; j++)
            write_byte(dbf, 0x00);
         /* field length */
         write_byte(dbf, dbf->len[k]);
         /* field precision */
         write_byte(dbf, dbf->prec[k]);
         /* (reserved) */
         for (j = 1; j <= 14; j++)
            write_byte(dbf, 0x00);
      }
      /* end of header */
      write_byte(dbf, 0x0D);
      return;
}
Ejemplo n.º 26
0
// ------------------------------------------------
// Function:        dhcp_send()
// ------------------------------------------------
// Input:           Message type
//                  TRUE to broadcast answer
// Output:          TRUE if succesful
// ------------------------------------------------
// Description:     Send a DHCP message
// ------------------------------------------------
BOOL dhcp_send(BYTE type, BOOL broadcast)
{
    PPBUF buf;

    buf = udp_new(SOCKET_DHCP);
    if(buf == NULL) return FALSE;

    DHCP(buf->data)->op = 1;                            // BOOTREQUEST
    DHCP(buf->data)->htype = 1;                         // ETH 10MBPS
    DHCP(buf->data)->hlen = 6;                          // 6 bytes ETH MAC
    DHCP(buf->data)->hops = 0;
    DHCP(buf->data)->xid = xid.d;
    DHCP(buf->data)->secs = 0;

    if(broadcast) {
        DHCP(buf->data)->flags = HTONS(0x8000);         // server must broadcast answer
        DHCP(buf->data)->ci.d = 0;
    } else {
        DHCP(buf->data)->flags = 0;                     // server must send unicast answer
        DHCP(buf->data)->ci.d = ip_local[INTERFACE_ETH].d;
    }

    DHCP(buf->data)->yi.d = 0;
    DHCP(buf->data)->gi.d = 0;
    DHCP(buf->data)->si.d = ip_dhcp.d;

    os_set((BYTE *)(&DHCP(buf->data)->chaddr), 0, 16+64+128);
    os_copy((BYTE *)&mac_local,
            (BYTE *)(&DHCP(buf->data)->chaddr),
            sizeof(MACADDR));

    // --------------
    // insert options
    // --------------
    skip(buf, BOOTP_HDR_SIZE);
    buf->size = BOOTP_HDR_SIZE;
    write_uint32(buf, 0x63825363);                      // magic cookie

    write_byte(buf, DHCP_OPT_TYPE);                     // DHCP message type
    write_byte(buf, 1);
    write_byte(buf, type);

    write_byte(buf, DHCP_OPT_ID);                       // DHCP source ID
    write_byte(buf, 7);
    write_byte(buf, 1);
    write_buf(buf, (BYTE *)&mac_local, sizeof(MACADDR));

    write_byte(buf, DHCP_OPT_IP);                       // Request IP address
    write_byte(buf, 4);
    write_ip(buf, ip_tmp);

#ifdef _DNS
    write_byte(buf, DHCP_OPT_REQ);                      // Request options
    write_byte(buf, 3);
    write_byte(buf, DHCP_OPT_MASK);
    write_byte(buf, DHCP_OPT_ROUTER);
    write_byte(buf, DHCP_OPT_DNS);
#else
    write_byte(buf, DHCP_OPT_REQ);                      // Request options
    write_byte(buf, 2);
    write_byte(buf, DHCP_OPT_MASK);
    write_byte(buf, DHCP_OPT_ROUTER);
#endif

    write_byte(buf, DHCP_OPT_END);                      // done with options

    udp_send(buf);
    release_buffer(buf);
    return TRUE;
}	
Ejemplo n.º 27
0
void show_logo(void)
{
    uint16_t    ebda_seg = read_word(0x0040,0x000E);
    uint8_t     f12_pressed = 0;
    uint8_t     scode;
    uint16_t    tmp, i;

    LOGOHDR     *logo_hdr = 0;
    uint8_t     is_fade_in, is_fade_out, uBootMenu;
    uint16_t    logo_time;
    uint16_t    old_mode;


    // Set PIT to 64hz.
    wait_init();

    // Get main signature
    tmp = read_logo_word((uint8_t)&logo_hdr->u16Signature);
    if (tmp != 0x66BB)
        goto done;

    // If there is no VBE, just skip this
    if (vesa_get_mode(&old_mode) != 0x004f )
        goto done;

    // Get options
    is_fade_in  = read_logo_byte((uint8_t)&logo_hdr->fu8FadeIn);
    is_fade_out = read_logo_byte((uint8_t)&logo_hdr->fu8FadeOut);
    logo_time   = read_logo_word((uint8_t)&logo_hdr->u16LogoMillies);
    uBootMenu   = read_logo_byte((uint8_t)&logo_hdr->fu8ShowBootMenu);

    // Is Logo disabled?
    if (!is_fade_in && !is_fade_out && !logo_time)
        goto done;

    // Set video mode #0x142 640x480x32bpp
    vesa_set_mode(0x142);

    if (is_fade_in)
    {
        for (i = 0; i <= LOGO_SHOW_STEPS; i++)
        {
            outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | i);
            scode = wait(16 / WAIT_MS, 0);
            if (scode == F12_SCAN_CODE)
            {
                f12_pressed = 1;
                break;
            }
        }
    }
    else
        outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | LOGO_SHOW_STEPS);

    // Wait (interval in milliseconds)
    if (!f12_pressed)
    {
        scode = wait(logo_time / WAIT_MS, 1);
        if (scode == F12_SCAN_CODE)
            f12_pressed = 1;
    }

    // Fade out (only if F12 was not pressed)
    if (is_fade_out && !f12_pressed)
    {
        for (i = LOGO_SHOW_STEPS; i > 0 ; i--)
        {
            outw(LOGO_IO_PORT, LOGO_CMD_SHOW_BMP | i);
            scode = wait(16 / WAIT_MS, 0);
            if (scode == F12_SCAN_CODE)
            {
                f12_pressed = 1;
                break;
            }
        }
    }

done:
    // Clear forced boot drive setting.
    write_byte(ebda_seg, (uint16_t)&EbdaData->uForceBootDevice, 0);

    // Don't restore previous video mode
    // The default text mode should be set up. (defect @bugref{1235})
    set_mode(0x0003);

    // If Setup menu enabled
    if (uBootMenu)
    {
        // If the graphics logo disabled
        if (!is_fade_in && !is_fade_out && !logo_time)
        {
            if (uBootMenu == 2)
                printf("Press F12 to select boot device.\n");

            // if the user has pressed F12 don't wait here
            if (!f12_pressed)
            {
                // Wait for timeout or keystroke
                scode = wait(F12_WAIT_TIME, 1);
                if (scode == F12_SCAN_CODE)
                    f12_pressed = 1;
            }
        }

        // If F12 pressed, show boot menu
        if (f12_pressed)
        {
            uint8_t boot_device = 0;
            uint8_t boot_drive = 0;

            clear_screen();

            // Show menu. Note that some versions of bcc freak out if we split these strings.
            printf("\nVirtualBox temporary boot device selection\n\nDetected Hard disks:\n\n");
            print_detected_harddisks();
            printf("\nOther boot devices:\n f) Floppy\n c) CD-ROM\n l) LAN\n\n b) Continue booting\n");



            // Wait for keystroke
            for (;;)
            {
                do
                {
                    scode = wait(WAIT_HZ, 1);
                } while (scode == 0);

                if (scode == 0x30)
                {
                    // 'b' ... continue
                    break;
                }

                // Check if hard disk was selected
                if ((scode >= 0x02) && (scode <= 0x09))
                {
                    boot_drive = get_boot_drive(scode);

                    /*
                     * 0xff indicates that there is no mapping
                     * from the scan code to a hard drive.
                     * Wait for next keystroke.
                     */
                    if (boot_drive == 0xff)
                        continue;

                    write_byte(ebda_seg, (uint16_t)&EbdaData->uForceBootDrive, boot_drive);
                    boot_device = 0x02;
                    break;
                }

                switch (scode)
                {
                    case 0x21:
                        // Floppy
                        boot_device = 0x01;
                        break;
                    case 0x2e:
                        // CD-ROM
                        boot_device = 0x03;
                        break;
                    case 0x26:
                        // LAN
                        boot_device = 0x04;
                        break;
                }

                if (boot_device != 0)
                    break;
            }

            write_byte(ebda_seg, (uint16_t)&EbdaData->uForceBootDevice, boot_device);

            // Switch to text mode. Clears screen and enables cursor again.
            set_mode(0x0003);
        }
    }

    // Restore PIT ticks
    wait_uninit();

    return;
}
Ejemplo n.º 28
0
void BIOSCALL int13_eltorito(disk_regs_t r)
{
    // @TODO: a macro or a function for getting the EBDA segment
    uint16_t        ebda_seg=read_word(0x0040,0x000E);
    cdemu_t __far   *cdemu;

    cdemu = ebda_seg :> &EbdaData->cdemu;

    
    BX_DEBUG_INT13_ET("%s: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", __func__, AX, BX, CX, DX, ES);
    // BX_DEBUG_INT13_ET("%s: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n", __func__, get_SS(), DS, ES, DI, SI);
    
    switch (GET_AH()) {

    // FIXME ElTorito Various. Should be implemented
    case 0x4a: // ElTorito - Initiate disk emu
    case 0x4c: // ElTorito - Initiate disk emu and boot
    case 0x4d: // ElTorito - Return Boot catalog
        BX_PANIC("%s: call with AX=%04x. Please report\n", __func__, AX);
        goto int13_fail;
        break;

    case 0x4b: // ElTorito - Terminate disk emu
        // FIXME ElTorito Hardcoded
        //@todo: maybe our cdemu struct should match El Torito to allow memcpy()?
        write_byte(DS,SI+0x00,0x13);
        write_byte(DS,SI+0x01,cdemu->media);
        write_byte(DS,SI+0x02,cdemu->emulated_drive);
        write_byte(DS,SI+0x03,cdemu->controller_index);
        write_dword(DS,SI+0x04,cdemu->ilba);
        write_word(DS,SI+0x08,cdemu->device_spec);
        write_word(DS,SI+0x0a,cdemu->buffer_segment);
        write_word(DS,SI+0x0c,cdemu->load_segment);
        write_word(DS,SI+0x0e,cdemu->sector_count);
        write_byte(DS,SI+0x10,cdemu->vdevice.cylinders);
        write_byte(DS,SI+0x11,cdemu->vdevice.spt);
        write_byte(DS,SI+0x12,cdemu->vdevice.heads);
        
        // If we have to terminate emulation
        if(GET_AL() == 0x00) {
            // FIXME ElTorito Various. Should be handled accordingly to spec
            cdemu->active = 0;  // bye bye
        }

        goto int13_success;
        break;

    default:
          BX_INFO("%s: unsupported AH=%02x\n", __func__, GET_AH());
          goto int13_fail;
          break;
    }

int13_fail:
    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
    SET_DISK_RET_STATUS(GET_AH());
    SET_CF();     // error occurred
    return;

int13_success:
    SET_AH(0x00); // no error
    SET_DISK_RET_STATUS(0x00);
    CLEAR_CF();   // no error
    return;
}
Ejemplo n.º 29
0
static glui32 write_stackstate(dest_t *dest, int portable)
{
  glui32 res;
  glui32 lx;
  glui32 lastframe;

  /* If we're storing for the purpose of undo, we don't need to do any
     byte-swapping, because the result will only be used by this session. */
  if (!portable) {
    res = write_buffer(dest, stack, stackptr);
    if (res)
      return res;
    return 0;
  }

  /* Write a portable stack image. To do this, we have to write stack
     frames in order, bottom to top. Remember that the last word of
     every stack frame is a pointer to the beginning of that stack frame.
     (This includes the last frame, because the save opcode pushes on
     a call stub before it calls perform_save().) */

  lastframe = (glui32)(-1);
  while (1) {
    glui32 frameend, frm, frm2, frm3;
    unsigned char loctype, loccount;
    glui32 numlocals, frlen, locpos;

    /* Find the next stack frame (after the one in lastframe). Sadly,
       this requires searching the stack from the top down. We have to
       do this for *every* frame, which takes N^2 time overall. But
       save routines usually aren't nested very deep. 
       If it becomes a practical problem, we can build a stack-frame 
       array, which requires dynamic allocation. */
    for (frm = stackptr, frameend = stackptr;
         frm != 0 && (frm2 = Stk4(frm-4)) != lastframe;
         frameend = frm, frm = frm2) { };

    /* Write out the frame. */
    frm2 = frm;

    frlen = Stk4(frm2);
    frm2 += 4;
    res = write_long(dest, frlen);
    if (res)
      return res;
    locpos = Stk4(frm2);
    frm2 += 4;
    res = write_long(dest, locpos);
    if (res)
      return res;

    frm3 = frm2;

    numlocals = 0;
    while (1) {
      loctype = Stk1(frm2);
      frm2 += 1;
      loccount = Stk1(frm2);
      frm2 += 1;

      res = write_byte(dest, loctype);
      if (res)
        return res;
      res = write_byte(dest, loccount);
      if (res)
        return res;

      if (loctype == 0 && loccount == 0)
        break;

      numlocals++;
    }

    if ((numlocals & 1) == 0) {
      res = write_byte(dest, 0);
      if (res)
        return res;
      res = write_byte(dest, 0);
      if (res)
        return res;
      frm2 += 2;
    }

    if (frm2 != frm+locpos)
      fatal_error("Inconsistent stack frame during save.");

    /* Write out the locals. */
    for (lx=0; lx<numlocals; lx++) {
      loctype = Stk1(frm3);
      frm3 += 1;
      loccount = Stk1(frm3);
      frm3 += 1;
      
      if (loctype == 0 && loccount == 0)
        break;

      /* Put in up to 0, 1, or 3 bytes of padding, depending on loctype. */
      while (frm2 & (loctype-1)) {
        res = write_byte(dest, 0);
        if (res)
          return res;
        frm2 += 1;
      }

      /* Put in this set of locals. */
      switch (loctype) {

      case 1:
        do {
          res = write_byte(dest, Stk1(frm2));
          if (res)
            return res;
          frm2 += 1;
          loccount--;
        } while (loccount);
        break;

      case 2:
        do {
          res = write_short(dest, Stk2(frm2));
          if (res)
            return res;
          frm2 += 2;
          loccount--;
        } while (loccount);
        break;

      case 4:
        do {
          res = write_long(dest, Stk4(frm2));
          if (res)
            return res;
          frm2 += 4;
          loccount--;
        } while (loccount);
        break;

      }
    }

    if (frm2 != frm+frlen)
      fatal_error("Inconsistent stack frame during save.");

    while (frm2 < frameend) {
      res = write_long(dest, Stk4(frm2));
      if (res)
        return res;
      frm2 += 4;
    }

    /* Go on to the next frame. */
    if (frameend == stackptr)
      break; /* All done. */
    lastframe = frm;
  }

  return 0;
}
Ejemplo n.º 30
0
/*---------------------------------------------------------------------------*/
static void
thread_checkpoint(int fd)
{
#if INCLUDE_RAM
  unsigned char *addr;
  uint16_t size = 0;
  unsigned char *thread_mem_start = (unsigned char *)&checkpoint_thread.thread.stack;
  unsigned char *thread_mem_end = thread_mem_start + sizeof(checkpoint_thread.thread.stack) - 1;
  unsigned char *coffee_mem_start = cfs_coffee_get_protected_mem(&size);
  unsigned char *coffee_mem_end = coffee_mem_start + size - 1;
#endif /* INCLUDE_RAM */

  /*printf("protected thread memory: %u, size=%u\n", (uint16_t) thread_mem_start, sizeof(checkpoint_thread.thread.stack));*/
  /*printf("protected coffee memory: %u, size=%u\n", (uint16_t) coffee_mem_start, size);*/

  /* RAM */
#if INCLUDE_RAM
  for(addr = (unsigned char *)RAM_START;
      addr < (unsigned char *)RAM_END;
      addr++) {

    if((addr >= thread_mem_start && addr <= thread_mem_end)) {
      /* Writing dummy memory */
      /*write_byte(fd, 1);*/
      continue;
    }

    if((addr >= coffee_mem_start && addr <= coffee_mem_end)) {
      /* Writing dummy memory */
      /*write_byte(fd, 2);*/
      continue;
    }

    /* TODO Use write_array() */
    write_byte(fd, *addr);

    if(((int)addr % 512) == 0) {
      PRINTF(".");
    }
  }

#endif /* INCLUDE_RAM */

  /* Timers */
#if INCLUDE_TIMERS
/*  write_word(fd, TACTL);
  write_word(fd, TACCTL1);
  write_word(fd, TACCR1);
  write_word(fd, TAR);

  write_word(fd, TBCTL);
  write_word(fd, TBCCTL1);
  write_word(fd, TBCCR1);
  write_word(fd, TBR);*/
#endif /* INCLUDE_TIMERS */

  /* LEDs */
#if INCLUDE_LEDS
  write_byte(fd, leds_arch_get());
#endif /* INCLUDE_LEDS */

  /* Radio */
  /* ADC */
  /* ... */

  write_byte(fd, -1); /* Coffee padding byte */
}