Ejemplo n.º 1
0
/**
 * Set retval to internal ID for requested Native Feature,
 * or zero if feature is unknown/unsupported.
 * 
 * Return true if caller is to proceed normally,
 * false if there was an exception.
 */
bool NatFeat_ID(Uint32 stack, Uint32 *retval)
{
	const char *name;
	Uint32 ptr;
	int i;

	ptr = STMemory_ReadLong(stack);
	if (!STMemory_ValidArea(ptr, FEATNAME_MAX)) {
		M68000_BusError(ptr, BUS_ERROR_READ);
		return false;
	}

	name = (const char *)STRAM_ADDR(ptr);
	Dprintf(("NF ID(0x%x)\n", ptr));
	Dprintf(("   \"%s\"\n", name));

	for (i = 0; i < ARRAYSIZE(features); i++) {
		if (strcmp(features[i].name, name) == 0) {
			*retval = IDX2MASTERID(i);
			return true;
		}
	}
	/* unknown feature */
	*retval = 0;
	return true;
}
Ejemplo n.º 2
0
/**
 * XBIOS remote control interface for Hatari
 * Call 255
 */
static bool XBios_HatariControl(Uint32 Params)
{
	const char *pText;
	pText = (const char *)STRAM_ADDR(STMemory_ReadLong(Params));
	LOG_TRACE(TRACE_OS_XBIOS, "XBIOS 0x%02X HatariControl(%s) at PC 0x%X\n", HATARI_CONTROL_OPCODE, pText, M68000_GetPC());

	if (!bXBiosCommands)
		return false;

	Control_ProcessBuffer(pText);
	Regs[REG_D0] = 0;
	return true;
}
Ejemplo n.º 3
0
/**
 * BIOS Read/Write disk sector
 * Call 4
 */
static void Bios_RWabs(Uint32 Params)
{
	Uint32 pBuffer;
	Uint16 RWFlag, Number, RecNo, Dev;

	/* Read details from stack */
	RWFlag = STMemory_ReadWord(Params);
	pBuffer = STMemory_ReadLong(Params+SIZE_WORD);
	Number = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
	RecNo = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG+SIZE_WORD);
	Dev = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG+SIZE_WORD+SIZE_WORD);

	LOG_TRACE(TRACE_OS_BIOS, "BIOS 0x04 Rwabs(%d,0x%lX,%d,%d,%i)\n",
	          RWFlag, STRAM_ADDR(pBuffer), Number, RecNo, Dev);
}
Ejemplo n.º 4
0
static bool nf_stderr(Uint32 stack, Uint32 subid, Uint32 *retval)
{
	const char *str;
	Uint32 ptr;

	ptr = STMemory_ReadLong(stack);
	//Dprintf(("NF stderr(0x%x)\n", ptr));

	if (!STMemory_ValidArea(ptr, 1)) {
		M68000_BusError(ptr, BUS_ERROR_READ);
		return false;
	}
	str = (const char *)STRAM_ADDR(ptr);
	*retval = fprintf(stderr, "%s", str);
	fflush(stderr);
	return true;
}
Ejemplo n.º 5
0
/**
 * BIOS Read/Write disk sector
 * Call 4
 */
static bool Bios_RWabs(Uint32 Params)
{
	Uint32 pBuffer;
	Uint16 RWFlag, Number, RecNo, Dev;

	/* Read details from stack */
	RWFlag = STMemory_ReadWord(Params+SIZE_WORD);
	pBuffer = STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD);
	Number = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG);
	RecNo = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG+SIZE_WORD);
	Dev = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG+SIZE_WORD+SIZE_WORD);

	HATARI_TRACE(HATARI_TRACE_OS_BIOS, "BIOS RWabs %i,%d,0x%lX,%d,%d\n",
			Dev, RWFlag, STRAM_ADDR(pBuffer), RecNo, Number);

	return FALSE;
}
Ejemplo n.º 6
0
static bool nf_name(Uint32 stack, Uint32 subid, Uint32 *retval)
{
	Uint32 ptr, len;
	const char *str;
	char *buf;

	ptr = STMemory_ReadLong(stack);
	len = STMemory_ReadLong(stack + SIZE_LONG);
	Dprintf(("NF name[%d](0x%x, %d)\n", subid, ptr, len));

	if (!STMemory_ValidArea(ptr, len)) {
		M68000_BusError(ptr, BUS_ERROR_WRITE);
		return false;
	}
	if (subid) {
		str = PROG_NAME;
	} else {
		str = "Hatari";
	}
	buf = (char *)STRAM_ADDR(ptr);
	*retval = snprintf(buf, len, "%s", str);
	return true;
}
Ejemplo n.º 7
0
unsigned long atari_scsi_dma_setup( struct Scsi_Host *instance, void *data,
				   unsigned long count, int dir )
{
	unsigned long addr = virt_to_phys( data );

	DMA_PRINTK("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, "
		   "dir = %d\n", instance->host_no, data, addr, count, dir);

	if (!IS_A_TT() && !STRAM_ADDR(addr)) {
		/* If we have a non-DMAable address on a Falcon, use the dribble
		 * buffer; 'orig_addr' != 0 in the read case tells the interrupt
		 * handler to copy data from the dribble buffer to the originally
		 * wanted address.
		 */
		if (dir)
			memcpy( atari_dma_buffer, data, count );
		else
			atari_dma_orig_addr = data;
		addr = atari_dma_phys_buffer;
	}
	
	atari_dma_startaddr = addr;	/* Needed for calculating residual later. */
  
	/* Cache cleanup stuff: On writes, push any dirty cache out before sending
	 * it to the peripheral. (Must be done before DMA setup, since at least
	 * the ST-DMA begins to fill internal buffers right after setup. For
	 * reads, invalidate any cache, may be altered after DMA without CPU
	 * knowledge.
	 * 
	 * ++roman: For the Medusa, there's no need at all for that cache stuff,
	 * because the hardware does bus snooping (fine!).
	 */
	dma_cache_maintenance( addr, count, dir );

	if (count == 0)
		printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !\n");

	if (IS_A_TT()) {
		tt_scsi_dma.dma_ctrl = dir;
		SCSI_DMA_WRITE_P( dma_addr, addr );
		SCSI_DMA_WRITE_P( dma_cnt, count );
		tt_scsi_dma.dma_ctrl = dir | 2;
	}
	else { /* ! IS_A_TT */
  
		/* set address */
		SCSI_DMA_SETADR( addr );

		/* toggle direction bit to clear FIFO and set DMA direction */
		dir <<= 8;
		st_dma.dma_mode_status = 0x90 | dir;
		st_dma.dma_mode_status = 0x90 | (dir ^ 0x100);
		st_dma.dma_mode_status = 0x90 | dir;
		udelay(40);
		/* On writes, round up the transfer length to the next multiple of 512
		 * (see also comment at atari_dma_xfer_len()). */
		st_dma.fdc_acces_seccount = (count + (dir ? 511 : 0)) >> 9;
		udelay(40);
		st_dma.dma_mode_status = 0x10 | dir;
		udelay(40);
		/* need not restore value of dir, only boolean value is tested */
		atari_dma_active = 1;
	}

	return( count );
}
Ejemplo n.º 8
0
static unsigned long atari_dma_xfer_len( unsigned long wanted_len,
					Scsi_Cmnd *cmd,
					int write_flag )
{
	unsigned long	possible_len, limit;
#ifndef CONFIG_TT_DMA_EMUL
	if (MACH_IS_HADES)
		/* Hades has no SCSI DMA at all :-( Always force use of PIO */
		return( 0 );
#endif	
	if (IS_A_TT())
		/* TT SCSI DMA can transfer arbitrary #bytes */
		return( wanted_len );

	/* ST DMA chip is stupid -- only multiples of 512 bytes! (and max.
	 * 255*512 bytes, but this should be enough)
	 *
	 * ++roman: Aaargl! Another Falcon-SCSI problem... There are some commands
	 * that return a number of bytes which cannot be known beforehand. In this
	 * case, the given transfer length is an "allocation length". Now it
	 * can happen that this allocation length is a multiple of 512 bytes and
	 * the DMA is used. But if not n*512 bytes really arrive, some input data
	 * will be lost in the ST-DMA's FIFO :-( Thus, we have to distinguish
	 * between commands that do block transfers and those that do byte
	 * transfers. But this isn't easy... there are lots of vendor specific
	 * commands, and the user can issue any command via the
	 * SCSI_IOCTL_SEND_COMMAND.
	 *
	 * The solution: We classify SCSI commands in 1) surely block-mode cmd.s,
	 * 2) surely byte-mode cmd.s and 3) cmd.s with unknown mode. In case 1)
	 * and 3), the thing to do is obvious: allow any number of blocks via DMA
	 * or none. In case 2), we apply some heuristic: Byte mode is assumed if
	 * the transfer (allocation) length is < 1024, hoping that no cmd. not
	 * explicitly known as byte mode have such big allocation lengths...
	 * BTW, all the discussion above applies only to reads. DMA writes are
	 * unproblematic anyways, since the targets aborts the transfer after
	 * receiving a sufficient number of bytes.
	 *
	 * Another point: If the transfer is from/to an non-ST-RAM address, we
	 * use the dribble buffer and thus can do only STRAM_BUFFER_SIZE bytes.
	 */

	if (write_flag) {
		/* Write operation can always use the DMA, but the transfer size must
		 * be rounded up to the next multiple of 512 (atari_dma_setup() does
		 * this).
		 */
		possible_len = wanted_len;
	}
	else {
		/* Read operations: if the wanted transfer length is not a multiple of
		 * 512, we cannot use DMA, since the ST-DMA cannot split transfers
		 * (no interrupt on DMA finished!)
		 */
		if (wanted_len & 0x1ff)
			possible_len = 0;
		else {
			/* Now classify the command (see above) and decide whether it is
			 * allowed to do DMA at all */
			switch( falcon_classify_cmd( cmd )) {
			  case CMD_SURELY_BLOCK_MODE:
				possible_len = wanted_len;
				break;
			  case CMD_SURELY_BYTE_MODE:
				possible_len = 0; /* DMA prohibited */
				break;
			  case CMD_MODE_UNKNOWN:
			  default:
				/* For unknown commands assume block transfers if the transfer
				 * size/allocation length is >= 1024 */
				possible_len = (wanted_len < 1024) ? 0 : wanted_len;
				break;
			}
		}
	}
	
	/* Last step: apply the hard limit on DMA transfers */
	limit = (atari_dma_buffer && !STRAM_ADDR( virt_to_phys(cmd->SCp.ptr) )) ?
		    STRAM_BUFFER_SIZE : 255*512;
	if (possible_len > limit)
		possible_len = limit;

	if (possible_len != wanted_len)
		DMA_PRINTK("Sorry, must cut DMA transfer size to %ld bytes "
			   "instead of %ld\n", possible_len, wanted_len);

	return( possible_len );
}
Ejemplo n.º 9
0
static int
bionet_send_packet(struct sk_buff *skb, struct net_device *dev) {
    struct net_local *lp = netdev_priv(dev);
    unsigned long flags;

    /* Block a timer-based transmit from overlapping.  This could better be
     * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
     */
    local_irq_save(flags);

    if (stdma_islocked()) {
        local_irq_restore(flags);
        lp->stats.tx_errors++;
    }
    else {
        int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
        unsigned long buf = virt_to_phys(skb->data);
        int stat;

        stdma_lock(bionet_intr, NULL);
        local_irq_restore(flags);
        if( !STRAM_ADDR(buf+length-1) ) {
            memcpy(nic_packet->buffer, skb->data, length);
            buf = (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buffer;
        }

        if (bionet_debug >1) {
            u_char *data = nic_packet->buffer, *p;
            int i;

            printk( "%s: TX pkt type 0x%4x from ", dev->name,
                    ((u_short *)data)[6]);

            for( p = &data[6], i = 0; i < 6; i++ )
                printk("%02x%s", *p++,i != 5 ? ":" : "" );
            printk(" to ");

            for( p = data, i = 0; i < 6; i++ )
                printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );

            printk( "%s: ", dev->name );
            printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
                   " %02x%02x%02x%02x len %d\n",
                   data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
                   data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
                   data[28], data[29], data[30], data[31], data[32], data[33],
                   length );
        }
        dma_cache_maintenance(buf, length, 1);

        stat = hardware_send_packet(buf, length);
        ENABLE_IRQ();
        stdma_release();

        dev->trans_start = jiffies;
        dev->tbusy	 = 0;
        lp->stats.tx_packets++;
        lp->stats.tx_bytes+=length;
    }
    dev_kfree_skb(skb);

    return 0;
}
Ejemplo n.º 10
0
/**
 * Output AES call info, including some of args
 */
static void AES_OpcodeInfo(FILE *fp, Uint16 opcode)
{
	int code = opcode - 10;
	fprintf(fp, "AES call %3hd ", opcode);
	if (code >= 0 && code < ARRAYSIZE(AESName_10) && AESName_10[code])
	{
		bool first = true;
		int i, items;

		fprintf(fp, "%s(", AESName_10[code]);

		items = 0;
		/* there are so few of these that linear search is fine */
		for (i = 0; i < ARRAYSIZE(AESStrings); i++)
		{
			/* something that can be shown? */
			if (AESStrings[i].code == opcode)
			{
				items = AESStrings[i].count;
				break;
			}
		}
		/* addrin array size in longs enough for items? */
		if (items > 0 && items <= STMemory_ReadWord(AESControl+SIZE_WORD*3))
		{
			const char *str;
			fputs("addrin: ", fp);
			for (i = 0; i < items; i++)
			{
				if (first)
					first = false;
				else
					fputs(", ", fp);
				str = (const char *)STRAM_ADDR(STMemory_ReadLong(AESAddrin+SIZE_LONG*i));
				fprintf(fp, "\"%s\"", str);
			}
		}
		/* intin array size in words */
		items = STMemory_ReadWord(AESControl+SIZE_WORD*1);
		if (items > 0)
		{
			if (!first)
			{
				fputs(", ", fp);
				first = true;
			}
			fputs("intin: ", fp);
			for (i = 0; i < items; i++)
			{
				if (first)
					first = false;
				else
					fputs(",", fp);
				fprintf(fp, "0x%x", STMemory_ReadWord(AESIntin+SIZE_WORD*i));
			}
		}
		fputs(")\n", fp);
	}
	else
		fputs("???\n", fp);
	fflush(fp);
}