Ejemplo n.º 1
0
void  readDriveConfig(int drive)
{
    int i;
    short info[256];

    Out_Byte(IDE_DRIVE_HEAD_REGISTER, (drive == 0) ? IDE_DRIVE_0 : IDE_DRIVE_1);
    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_IDENTIFY_DRIVE);

    while (In_Byte(IDE_STATUS_REGISTER) != 0x58);

    for (i=0; i < 256; i++) {
        info[i] = In_Word(IDE_DATA_REGISTER);
    }

    drives[drive].num_Cylinders = info[IDE_INDENTIFY_NUM_CYLINDERS];
    drives[drive].num_Heads = info[IDE_INDENTIFY_NUM_HEADS];
    drives[drive].num_SectorsPerTrack = info[IDE_INDENTIFY_NUM_SECTORS_TRACK];
    drives[drive].num_BytesPerSector = info[IDE_INDENTIFY_NUM_BYTES_SECTOR];

    Print ("Found IDE: Drive %d\n", drive);
    Print ("    %d cylinders, %d heads, %d sectors/tack, %d bytes/sector\n", 
        drives[drive].num_Cylinders, drives[drive].num_Heads,
        drives[drive].num_SectorsPerTrack, drives[drive].num_BytesPerSector);
    Print ("    Disk has %d blocks\n", IDE_getNumBlocks(drive));
}
Ejemplo n.º 2
0
void NE2000_Get_Dev_Hdr(struct Net_Device *device,
                        struct Net_Device_Header *hdr, ulong_t pageOffset) {
    unsigned int i;
    ulong_t baseAddr = device->baseAddr;
    ulong_t size = sizeof(struct Net_Device_Header) >> 1;
    ushort_t *buffer = (ushort_t *) hdr;

    /* Set the Command Register */
    Out_Byte(baseAddr + NE2K_CR, 0x22);

    /* Load the packet size into the registers */
    Out_Byte(baseAddr + NE2K0W_RBCR0, sizeof(struct Net_Device_Header));
    Out_Byte(baseAddr + NE2K0W_RBCR1, 0);

    /* Load the page start  into the RSARX registers */
    Out_Byte(baseAddr + NE2K0W_RSAR0, 0x00);
    Out_Byte(baseAddr + NE2K0W_RSAR1, pageOffset);

    /* Start the remote write */
    Out_Byte(baseAddr + NE2K_CR, NE2K_CR_DMA_RREAD | NE2K_CR_STA);

    /* Read the data in through the I/O port */
    for (i = 0; i < size; ++i) {
        buffer[i] = In_Word(baseAddr + NE2K_IO_PORT);
    }

}
Ejemplo n.º 3
0
static void rtl8139_interrupt( struct Interrupt_State * state )
{
	Begin_IRQ(state);

	uint_t status = In_Word(RTL8139_ISR);

	PrintBoth("Interrupt Received: %x\n", status);

	if( status == PKT_RX )
		rtl8139_Receive();

	rtl8139_Clear_IRQ(status);
	End_IRQ(state);

}
Ejemplo n.º 4
0
/* actually reads the data out of the device */
void NE2000_Receive(struct Net_Device *device, void *buffer, ulong_t length,
                    ulong_t pageOffset) {
    ulong_t baseAddr = device->baseAddr;

    KASSERT(!Interrupts_Enabled());

    int i;
    int newLength = length >> 1;
    unsigned short *newBuffer = (unsigned short *)buffer;

    /* Set the Command Register */
    Out_Byte(baseAddr + NE2K_CR, 0x22);

    Out_Byte(baseAddr + NE2K0W_RCR, 0x0C);

    /* Load the packet size into the registers */
    Out_Byte(baseAddr + NE2K0W_RBCR0, length & 0xFF);
    Out_Byte(baseAddr + NE2K0W_RBCR1, length >> 8);

    /* Load the page start  into the RSARX registers */
    Out_Byte(baseAddr + NE2K0W_RSAR0, pageOffset & 0xFF);
    Out_Byte(baseAddr + NE2K0W_RSAR1, pageOffset >> 8);

    /* Start the remote write */
    Out_Byte(baseAddr + NE2K_CR, NE2K_CR_DMA_RREAD | NE2K_CR_STA);

    /* Read the data in through the I/O port */
    for (i = 0; i < newLength; ++i) {
        newBuffer[i] = In_Word(baseAddr + NE2K_IO_PORT);
    }

    /* Receive the last byte of data if we have an odd length */
    if (length & 0x1) {
        ((uchar_t *) buffer)[length - 1] = In_Byte(baseAddr + NE2K_IO_PORT);
    }

    /* Ack the remote DMA interrupt */
    Out_Byte(baseAddr + NE2K0R_ISR, NE2K_ISR_RDC);

    device->rxBytes += length;
}
Ejemplo n.º 5
0
/*
 * Read a block at the logical block number indicated.
 */
int IDE_Read(int driveNum, int blockNum, char *buffer)
{
    int i;
    int head;
    int sector;
    int cylinder;
    short *bufferW;

    if (driveNum < 0 || driveNum > (numDrives-1)) {
        return IDE_ERROR_BAD_DRIVE;
    }

    if (blockNum < 0 || blockNum >= IDE_getNumBlocks(driveNum)) {
        return IDE_ERROR_INVALID_BLOCK;
    }

    /* now compute the head, cylinder, and sector */
    sector = blockNum % drives[driveNum].num_SectorsPerTrack + 1;
    cylinder = blockNum / (drives[driveNum].num_Heads * 
     	drives[driveNum].num_SectorsPerTrack);
    head = (blockNum / drives[driveNum].num_SectorsPerTrack) % 
        drives[driveNum].num_Heads;

    if (ideDebug) {
	Print ("request to read block %d\n", blockNum);
	Print ("    head %d\n", head);
	Print ("    cylinder %d\n", cylinder);
	Print ("    sector %d\n", sector);
    }

    Out_Byte(IDE_SECTOR_COUNT_REGISTER, 1);
    Out_Byte(IDE_SECTOR_NUMBER_REGISTER, sector);
    Out_Byte(IDE_CYLINDER_LOW_REGISTER, LOW_BYTE(cylinder));
    Out_Byte(IDE_CYLINDER_HIGH_REGISTER, HIGH_BYTE(cylinder));
    if (driveNum == 0) {
	Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE_0 | head);
    } else if (driveNum == 1) {
	Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE_1 | head);
    }

    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_READ_SECTORS);

    if (ideDebug) Print("About to wait for Read \n");

    /* wait for the drive */
    while (!(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_READY));

    if (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_ERROR) {
	Print("ERROR: Got Read %d\n", In_Byte(IDE_STATUS_REGISTER));
	return IDE_ERROR_DRIVE_ERROR;
    }

    if (ideDebug) Print("got buffer \n");

    bufferW = (short *) buffer;
    for (i=0; i < 256; i++) {
        bufferW[i] = In_Word(IDE_DATA_REGISTER);
    }

    return IDE_ERROR_NO_ERROR;
}
Ejemplo n.º 6
0
void Init_8139()
{
	cur_tx = 0;
	cur_rx = 0;

	/* Reset the chip */
	Out_Byte(RTL8139_CR, CmdReset);

	//while( In_Byte(RTL8139_CR) != 0 )
		/*udelay(10)*/;

	/* Unlock Config[01234] and BMCR register writes */
	Out_Byte(RTL8139_9346CR, Cfg9346_Unlock);

	/* Enable Tx/Rx before setting transfer thresholds */
	Out_Byte(RTL8139_CR, CmdRxEnb | CmdTxEnb);

	/* Using 32K ring */
	Out_DWord(RTL8139_RCR, RxCfgRcv32K | RxNoWrap | (7 << RxCfgFIFOShift) | (7 << RxCfgDMAShift)
				 | AcceptBroadcast | AcceptMyPhys);

//	Out_DWord(RTL8139_TCR, RxCfgRcv32K | RxNoWrap | (7 << RxCfgFIFOShift) | (7 << RxCfgDMAShift));

	Out_DWord(RTL8139_TCR, TxIFG96 | (6 << TxDMAShift) | (8 << TxRetryShift));

	/* Lock Config[01234] and BMCR register writes */
	Out_Byte(RTL8139_9346CR, Cfg9346_Lock);

	/* init Rx ring buffer DMA address */
	rx_buf = Malloc(RX_BUF_LEN);
	Out_DWord(RTL8139_RBSTART, (uint_t)rx_buf);

	/* init Tx buffer DMA addresses (4 registers) */
	tx_buf = Malloc(TX_BUF_SIZE * 4);
	int i;
	for(i = 0; i < 4; i++)
		Out_DWord(RTL8139_TSAD0 + (i * 4), ((uint_t)tx_buf) + (i * TX_BUF_SIZE));

	/* missed packet counter */
	Out_DWord(RTL8139_MPC, 0);

	// rtl8139_set_rx_mode does some stuff here.
	Out_DWord(RTL8139_RCR, In_DWord(RTL8139_RCR) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
				AcceptAllPhys);

	for(i = 0; i < 8; i++)
		Out_Byte(RTL8139_MAR0 + i, 0xff);

	/* no early-rx interrupts */
	Out_Word(RTL8139_MULINT, In_Word(RTL8139_MULINT) & MultiIntrClear);

	/* make sure RxTx has started */
	if(!(In_Byte(RTL8139_CR) & CmdRxEnb) || !(In_Byte(RTL8139_CR) & CmdTxEnb))
		Out_Byte(RTL8139_CR, CmdRxEnb | CmdTxEnb);

	/* Enable all known interrupts by setting the interrupt mask. */
	Out_Word(RTL8139_IMR, rtl8139_intr_mask);

	Install_IRQ(RTL8139_IRQ, rtl8139_interrupt);
  	Enable_IRQ(RTL8139_IRQ);

	PrintBoth("8139 initialized\n");
}
Ejemplo n.º 7
0
static int readDriveConfig(int drive) {
    int i;
    int status;
    short info[256];
    char devname[BLOCKDEV_MAX_NAME_LEN];
    int rc;

    if (ideDebug > 1)
        Print("ide: about to read drive config for drive #%d\n", drive);

    Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(drive));
    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_IDENTIFY_DRIVE);
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY);

    status = In_Byte(IDE_STATUS_REGISTER);
    /*
     * simulate failure
     * status = 0x50;
     */
    if ((status & IDE_STATUS_DRIVE_DATA_REQUEST)) {
        Print("ide: probe found ATA drive\n");
        /* drive responded to ATA probe */
        for (i = 0; i < 256; i++) {
            info[i] = In_Word(IDE_DATA_REGISTER);
        }

        drives[drive].num_Cylinders = info[IDE_INDENTIFY_NUM_CYLINDERS];
        drives[drive].num_Heads = info[IDE_INDENTIFY_NUM_HEADS];
        drives[drive].num_SectorsPerTrack =
            info[IDE_INDENTIFY_NUM_SECTORS_TRACK];
        drives[drive].num_BytesPerSector =
            info[IDE_INDENTIFY_NUM_BYTES_SECTOR];
    } else {
        /* try for ATAPI */
        Out_Byte(IDE_FEATURE_REG, 0);   /* disable dma & overlap */

        Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(drive));
        Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_ATAPI_IDENT_DRIVE);
        while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY);
        status = In_Byte(IDE_STATUS_REGISTER);
        Print("status is %x\n", status);
        if ((status & IDE_STATUS_DRIVE_DATA_REQUEST)) {
            Print("ide: found atapi drive\n");
        } else {
            Print("ide: found no drive %d\n", drive);
        }
        return -1;
    }

    Print("    ide%d: cyl=%d, heads=%d, sectors=%d\n", drive,
          drives[drive].num_Cylinders, drives[drive].num_Heads,
          drives[drive].num_SectorsPerTrack);

    /* Register the drive as a block device */
    snprintf(devname, sizeof(devname), "ide%d", drive);
    rc = Register_Block_Device(devname, &s_ideDeviceOps, drive, 0,
                               &s_ideWaitQueue, &s_ideRequestQueue);
    if (rc != 0)
        Print("  Error: could not create block device for %s\n", devname);

    return 0;
}
Ejemplo n.º 8
0
/*
 * Read a block at the logical block number indicated.
 */
static int IDE_Read(int driveNum, int blockNum, char *buffer) {
    int i;
    int head;
    int sector;
    int cylinder;
    short *bufferW;
    int reEnable = 0;

    if(driveNum < 0 || driveNum > (numDrives - 1)) {
        if(ideDebug)
            Print("ide: invalid drive %d\n", driveNum);
        return IDE_ERROR_BAD_DRIVE;
    }

    if(blockNum < 0 || blockNum >= IDE_getNumBlocks(driveNum)) {
        if(ideDebug)
            Print("ide: invalid block %d\n", blockNum);
        return IDE_ERROR_INVALID_BLOCK;
    }

    /* now compute the head, cylinder, and sector */
    sector = blockNum % drives[driveNum].num_SectorsPerTrack + 1;
    cylinder = blockNum / (drives[driveNum].num_Heads *
                           drives[driveNum].num_SectorsPerTrack);
    head = (blockNum / drives[driveNum].num_SectorsPerTrack) %
        drives[driveNum].num_Heads;

    if(ideDebug >= 2) {
        Print("request to read block %d\n", blockNum);
        Print("    head %d, cylinder %d, sector %d\n", head, cylinder,
              sector);
        // Print ("    cylinder %d\n", cylinder);
        // Print ("    sector %d\n", sector);
    }
#ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK
    reEnable = Begin_Int_Atomic();
#endif

    Out_Byte(IDE_SECTOR_COUNT_REGISTER, 1);
    Out_Byte(IDE_SECTOR_NUMBER_REGISTER, sector);
    Out_Byte(IDE_CYLINDER_LOW_REGISTER, LOW_BYTE(cylinder));
    Out_Byte(IDE_CYLINDER_HIGH_REGISTER, HIGH_BYTE(cylinder));
    Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(driveNum) | head);

    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_READ_SECTORS);

    if(ideDebug > 2)
        Print("About to wait for Read \n");

    /* wait for the drive */
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ;
    if(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_ERROR) {
        Print("ERROR: Got Read %d\n", In_Byte(IDE_STATUS_REGISTER));
        return IDE_ERROR_DRIVE_ERROR;
    }

    if(ideDebug > 2)
        Print("got buffer \n");

    bufferW = (short *)buffer;
    for(i = 0; i < 256; i++) {
        bufferW[i] = In_Word(IDE_DATA_REGISTER);
    }
    if(ideDebug > 2)
        Print("read buffer \n");

#ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK
    End_Int_Atomic(reEnable);
#endif

    return IDE_ERROR_NO_ERROR;
}
Ejemplo n.º 9
0
int Init_NE2000(struct Net_Device *device) {

    unsigned char saProm[32];
    int i;
    ulong_t baseAddr = device->baseAddr;

    Print("Initializing ne2000 nic...\n");

    /* Read the PROM, taken from ne2k-pci.c in linux kernel */
    Out_Byte(baseAddr + NE2K_CR, 0x21);
    Out_Byte(baseAddr + NE2K0W_DCR, 0x49);
    Out_Byte(baseAddr + NE2K0W_RBCR0, 0x00);
    Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00);
    Out_Byte(baseAddr + NE2K0W_IMR, 0x00);
    Out_Byte(baseAddr + NE2K0R_ISR, 0xFF);
    Out_Byte(baseAddr + NE2K0W_RCR, 0x20);
    Out_Byte(baseAddr + NE2K0W_TCR, 0x02);
    Out_Byte(baseAddr + NE2K0W_RBCR0, 32);
    Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00);
    Out_Byte(baseAddr + NE2K0W_RSAR0, 0x00);
    Out_Byte(baseAddr + NE2K0W_RSAR1, 0x00);
    Out_Byte(baseAddr + NE2K_CR, NE2K_CR_STA + NE2K_CR_DMA_RREAD);

    for (i = 0; i < 32; ++i) {
        saProm[i] = (unsigned char)In_Word(baseAddr + NE2K_IO_PORT);
    }

    /* Ensure this is an ne2000. Ne2000 cards have the byte values
       0x57 in the 0x0e and 0x0f bytes in the station prom */
    if (saProm[0x0e] != 0x57 || saProm[0x0f] != 0x57) {
        return -1;
    }

    /* Print out the mac address */
    device->addrLength = 6;
    Print("Mac address: ");
    for (i = 0; i < 6; ++i) {
        device->devAddr[i] = saProm[i];
        Print("%02x", saProm[i]);
        if (i < 5)
            Print(":");
    }

    Print("\n");

    /* Install interrupt handler */
    Install_IRQ(device->irq, NE2000_Interrupt_Handler);

    /* Enable IRQ */
    Enable_IRQ(device->irq);

    /* Program Command Register for Page 0 */
    Out_Byte(baseAddr + NE2K_CR, 0x21);

    /* Initialize Data Configuration Register */
    Out_Byte(baseAddr + NE2K0W_DCR, 0x49);

    /* Clear remote byte count registers */
    Out_Byte(baseAddr + NE2K0W_RBCR0, 0x00);
    Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00);

    /* Initialize Receive Configuration Register */
    Out_Byte(baseAddr + NE2K0W_RCR, 0x0C);

    /* Place the NIC in LOOPBACK mode 1 or 2 */
    Out_Byte(baseAddr + NE2K0W_TCR, 0x02);

    /* Initialize Transmit page start register */
    Out_Byte(baseAddr + NE2K0W_TPSR, NE2K_TRANSMIT_PAGE);

    /* Clear Interrupt Status Register ISR by writing 0xFF to it */
    Out_Byte(baseAddr + NE2K0R_ISR, 0xFF);

    /* Initialize Interrupt Mask Register */
    Out_Byte(baseAddr + NE2K0W_IMR, 0x0F + NE2K_ISR_OVW);

    /* Initialize the Receive Buffer Ring (BNDRY, PSTART, PSTOP) */
    Out_Byte(baseAddr + NE2K0W_PSTART, NE2K_RB_START);
    Out_Byte(baseAddr + NE2K0W_BNRY, NE2K_RB_START);
    Out_Byte(baseAddr + NE2K0W_PSTOP, NE2K_RB_STOP);

    /* Go to Page 1 */
    Out_Byte(baseAddr + NE2K_CR, 0x61);

    /* Initialize Physical Address Registers */
    Out_Byte(baseAddr + NE2K1W_PAR0, saProm[0]);
    Out_Byte(baseAddr + NE2K1W_PAR1, saProm[1]);
    Out_Byte(baseAddr + NE2K1W_PAR2, saProm[2]);
    Out_Byte(baseAddr + NE2K1W_PAR3, saProm[3]);
    Out_Byte(baseAddr + NE2K1W_PAR4, saProm[4]);
    Out_Byte(baseAddr + NE2K1W_PAR5, saProm[5]);

    /* Initialize Multicast Address Registers */
    Out_Byte(baseAddr + NE2K1W_MAR0, 0xFF);
    Out_Byte(baseAddr + NE2K1W_MAR1, 0xFF);
    Out_Byte(baseAddr + NE2K1W_MAR2, 0xFF);
    Out_Byte(baseAddr + NE2K1W_MAR3, 0xFF);
    Out_Byte(baseAddr + NE2K1W_MAR4, 0xFF);
    Out_Byte(baseAddr + NE2K1W_MAR5, 0xFF);
    Out_Byte(baseAddr + NE2K1W_MAR6, 0xFF);
    Out_Byte(baseAddr + NE2K1W_MAR7, 0xFF);

    /* Write the CURRENT buffer address */
    Out_Byte(baseAddr + NE2K1W_CURR, NE2K_RB_START);
    Print("Current buffer Address: %x\n", In_Byte(baseAddr + NE2K1W_CURR));

    /* Go back to Page 0 and Start */
    Out_Byte(baseAddr + NE2K_CR, 0x22);

    /* Initialize the Transmit Configuration Register */
    Out_Byte(baseAddr + NE2K0W_TCR, 0x00);

    return 0;

}