Esempio n. 1
0
/* called when an interrupt tells us to. */
static void NE2000_Do_Receive(struct Net_Device *device) {
    uchar_t currentBuffer;
    ulong_t baseAddr = device->baseAddr;
    ushort_t ringBufferPage;


    Out_Byte(baseAddr + NE2K_CR, NE2K_CR_PAGE1 + NE2K_CR_NODMA + NE2K_CR_STA);
    currentBuffer = In_Byte(baseAddr + NE2K1W_CURR);
    Out_Byte(baseAddr + NE2K_CR, NE2K_CR_PAGE0 + NE2K_CR_NODMA + NE2K_CR_STA);

    while (currentBuffer != In_Byte(baseAddr + NE2K0R_BNRY)) {
        ringBufferPage = In_Byte(baseAddr + NE2K0R_BNRY) << 8;

        /* Receive as a packet; enqueue for further processing */
        Net_Device_Receive(device, ringBufferPage);

        /* Read the current buffer register */
        Out_Byte(baseAddr + NE2K_CR,
                 NE2K_CR_PAGE1 + NE2K_CR_NODMA + NE2K_CR_STA);
        currentBuffer = In_Byte(baseAddr + NE2K1W_CURR);
        Out_Byte(baseAddr + NE2K_CR,
                 NE2K_CR_PAGE0 + NE2K_CR_NODMA + NE2K_CR_STA);

        //Print("Current buffer: %x\n", currentBuffer);
        //Print("Boundary pointer: %x\n", In_Byte(baseAddr + NE2K0R_BNRY));
    }
}
Esempio n. 2
0
void NE2000_Reset(struct Net_Device *device) {
    ulong_t baseAddr = device->baseAddr;

    KASSERT(!Interrupts_Enabled());

    Out_Byte(baseAddr + NE2K_RESET_PORT, In_Byte(NE2K_RESET_PORT));

    while (In_Byte(baseAddr + NE2K0R_ISR) & NE2K_ISR_RST) {
        Print("NIC has not reset yet\n");
    }
}
Esempio n. 3
0
void NE2000_Handle_Ring_Buffer_Overflow(struct Net_Device *device) {
    int txp, resend;
    ulong_t baseAddr = device->baseAddr;
    /* 1. Read and store the value of the TXP bit */
    txp = In_Byte(baseAddr + NE2K_CR) & NE2K_CR_TXP;

    /* 2. Issue the STOP command to the NIC */
    Out_Byte(baseAddr + NE2K_CR, 0x21);

    /* 3. Wait for at least 1.6 ms */
    IO_Delay();

    /* 4. Clear the NIC’s Remote Byte Count */
    Out_Byte(baseAddr + NE2K0W_RBCR0, 0x00);
    Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00);

    /* 5. Handle resend */
    if (!txp) {
        resend = 0;
    } else {
        int isr = In_Byte(baseAddr + NE2K0R_ISR);
        if ((isr & NE2K_ISR_PTX) || (isr & NE2K_ISR_TXE)) {
            resend = 0;
        } else {
            resend = 1;
        }
    }

    /* 6. Place the NIC into loopback mode */
    Out_Byte(baseAddr + NE2K0W_TCR, 0x02);

    /* 7. Issue START command to the NIC */
    Out_Byte(baseAddr + NE2K_CR, 0x22);

    /* 8. Remove one or more packets from the receive buffer ring */
    NE2000_Do_Receive(device);

    /* 9. Reset the overwrite warning (OVW) bit in the ISR */
    Out_Byte(baseAddr + NE2K0R_ISR, NE2K_ISR_OVW);

    /* 10. Take the NIC out of loopback */
    Out_Byte(baseAddr + NE2K0W_TCR, 0x00);

    /* 11. Restart the interrupted transmit if resend = 1 */
    if (resend) {
        Out_Byte(baseAddr + NE2K_CR, 0x26);
    }
}
Esempio n. 4
0
/*
 * Update the location of the hardware cursor.
 */
static void Update_Cursor(void) {
    /*
     * The cursor location is a character offset from the beginning
     * of page memory (I think).
     */
    uint_t characterPos = (s_cons.row * NUMCOLS) + s_cons.col;
    uchar_t origAddr;

    /*
     * Save original contents of CRT address register.
     * It is considered good programming practice to restore
     * it to its original value after modifying it.
     */
    origAddr = In_Byte(CRT_ADDR_REG);
    IO_Delay();

    /* Set the high cursor location byte */
    Out_Byte(CRT_ADDR_REG, CRT_CURSOR_LOC_HIGH_REG);
    IO_Delay();
    Out_Byte(CRT_DATA_REG, (characterPos >> 8) & 0xff);
    IO_Delay();

    /* Set the low cursor location byte */
    Out_Byte(CRT_ADDR_REG, CRT_CURSOR_LOC_LOW_REG);
    IO_Delay();
    Out_Byte(CRT_DATA_REG, characterPos & 0xff);
    IO_Delay();

    /* Restore contents of the CRT address register */
    Out_Byte(CRT_ADDR_REG, origAddr);
}
Esempio n. 5
0
int rtl8139_Receive()
{
	PrintBoth("Packet Received\n");
	int i;

	while( (In_Byte(RTL8139_CR) & RxBufEmpty) == 0){

		uint_t ring_offset = cur_rx % RX_BUF_LEN;

		uint_t rx_status = ((uint_t)rx_buf + ring_offset);

		PrintBoth("RX Status = %x\n", rx_status);

		uint_t rx_size = (uint_t)((*(uchar_t *)(rx_status + 3) << 8) | (*(uchar_t *)(rx_status + 2)));
		uint_t pkt_len = rx_size - 4;

		PrintBoth("Packet Size = %d\n", pkt_len);
	
		for (i = 0; i < pkt_len; i++){
			PrintBoth(" %x ", *((uchar_t *)(rx_status + i)));
		}
		PrintBoth("\n");

		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
		Out_Word(RTL8139_CAPR, (ushort_t)(cur_rx - 16));

		pkt_cntr++;

		PrintBoth("Packet counter at %d\n", pkt_cntr);
	}



	return 0;
}
Esempio n. 6
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));
}
Esempio n. 7
0
Keycode Get_Test_Input() {
    Keycode ret;
    ret = In_Byte(0x510);
    if (!ret)
        return KEY_UNKNOWN;

    return ret;
}
Esempio n. 8
0
void Init_IDE(void) {
    int errorCode;

    Print("Initializing IDE controller...\n");

    /* Reset the controller and drives */
    Out_Byte(IDE_DEVICE_CONTROL_REGISTER,
             IDE_DCR_NOINTERRUPT | IDE_DCR_RESET);
    Micro_Delay(100);
    Out_Byte(IDE_DEVICE_CONTROL_REGISTER, IDE_DCR_NOINTERRUPT);

/*
 * FIXME: This code doesn't work on Bochs 2.0.
 *    while ((In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_READY) == 0)
 *	;
 */

    /* This code does work on Bochs 2.0. */
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ;

    if(ideDebug)
        Print("About to run drive Diagnosis\n");

    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_DIAGNOSTIC);
    while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ;
    errorCode = In_Byte(IDE_ERROR_REGISTER);
    if(ideDebug > 1)
        Print("ide: ide error register = %x\n", errorCode);

    /* Probe and register drives */
    int i;
    for(i = 0; i < IDE_MAX_DRIVES; i++) {
        if(readDriveConfig(i) == 0)
            ++numDrives;
    }
    if(ideDebug)
        Print("Found %d IDE drives\n", numDrives);

    /* Start request thread */
    if(numDrives > 0)
        Start_Kernel_Thread(IDE_Request_Thread, 0, PRIORITY_NORMAL, true,
                            "{IDE}");
}
Esempio n. 9
0
/*
 * Wait for the MRQ bit to be set in the main status register.
 * This indicates that the controller is ready to accept data
 * or send data via the data register.
 */
static void Wait_For_MRQ(uchar_t readyValue)
{
    KASSERT(readyValue == FDC_STATUS_READY_READ || readyValue == FDC_STATUS_READY_WRITE);

    /* Wait for MRQ bit to be set in main status register */
    while ((In_Byte(FDC_STATUS_REG) & FDC_STATUS_READY_MASK) != readyValue)
	;

    /*Debug("Ready to accept command!\n"); */
}
Esempio n. 10
0
static void NE2000_Interrupt_Handler(struct Interrupt_State *state) {
    struct Net_Device *device;
    ulong_t baseAddr;
    unsigned char isrMask;
    int rc;

    Begin_IRQ(state);
    DEBUG_NE2K("Handling NE2000 interrupt\n");

    rc = Get_Net_Device_By_IRQ(state->intNum - FIRST_EXTERNAL_INT, &device);
    if (rc != 0) {
        Print("NE2000: Could not identify interrupt number %d\n",
              state->intNum);
        goto fail;
    }

    baseAddr = device->baseAddr;
    isrMask = In_Byte(NE2K0R_ISR + baseAddr);

    // DEBUG_NE2K("ISR Mask: %x\n" , isrMask);

    if (isrMask & NE2K_ISR_RXE) {
        //Print("RSR: %x\n", In_Byte(NE2K0R_RSR + baseAddr));
        ++device->rxPacketErrors;
    }

    if (isrMask & NE2K_ISR_TXE) {
        //Print("TSR: %x\n", In_Byte(NE2K0R_TSR + baseAddr));
        ++device->txPacketErrors;
    }

    if (isrMask & NE2K_ISR_OVW) {
        //Print("Ring Buffer Overflow Encountered!!\n");
        NE2000_Handle_Ring_Buffer_Overflow(device);
    }

    if (isrMask & NE2K_ISR_PRX) {
        DEBUG_NE2K("Receiving packet\n");
        NE2000_Do_Receive(device);
        ++device->rxPackets;
    }

    if (isrMask & NE2K_ISR_PTX) {
        //Print("Packet transmitted\n");
        DEBUG_NE2K("Transmitted.\n");
        //Print("TSR: %x\n", In_Byte(NE2K0R_TSR + baseAddr));
        ++device->txPackets;
    }

  fail:

    Out_Byte(baseAddr + NE2K0R_ISR, isrMask);

    End_IRQ(state);
}
Esempio n. 11
0
void Init_IDE()
{
    int errorCode;

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

    if (ideDebug) Print("About to run drive Diagnosis\n");

    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_DIAGNOSTIC);
    while (!(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_READY));
    errorCode = In_Byte(IDE_ERROR_REGISTER);

    readDriveConfig(0);
    if (errorCode & 0x80) {
        numDrives = 1;
    } else {
        numDrives = 2;
	readDriveConfig(1);
    }
}
Esempio n. 12
0
/*
 * Initialize the floppy controller.
 */
void Init_Floppy(void)
{
    uchar_t floppyByte;
    bool ready = false;
    bool good;

    Print("Initializing floppy controller...\n");

    /* Allocate memory for DMA transfers */
    s_transferBuf = (uchar_t*) Alloc_Page();

    /* Use CMOS to get floppy configuration */
    Out_Byte(CMOS_OUT, CMOS_FLOPPY_INDEX);
    floppyByte = In_Byte(CMOS_IN);
    Setup_Drive_Parameters(0, (floppyByte >> 4) & 0xF);
    Setup_Drive_Parameters(1, floppyByte & 0xF);

    /* Install floppy interrupt handler */
    Install_IRQ(FDC_IRQ, &Floppy_Interrupt_Handler);
    Enable_IRQ(FDC_IRQ);

    /* Reset and calibrate the controller. */
    Disable_Interrupts();
    good = Reset_Controller();
    Enable_Interrupts();
    if (!good) {
	Print("  Failed to reset controller!\n");
	goto done;
    }

    /* Reserve DMA channel 2. */
    if (!Reserve_DMA(FDC_DMA)) {
	Print("  Failed to reserve DMA channel\n");
	goto done;
    }

    /*
     * Driver is now ready for requests.
     * Start the request processing thread.
     */
    ready = true;
    Start_Kernel_Thread(Floppy_Request_Thread, 0, PRIORITY_NORMAL, true);

done:
    if (!ready)
	Print("  Floppy controller initialization FAILED\n");
}
Esempio n. 13
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;
}
Esempio n. 14
0
/*
 * Write a block at the logical block number indicated.
 */
static int IDE_Write(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)) {
        return IDE_ERROR_BAD_DRIVE;
    }

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

    if (Interrupts_Enabled()) {
        Disable_Interrupts();
        reEnable = 1;
    }

    /* 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 write 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));
    Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(driveNum) | head);

    Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_WRITE_SECTORS);


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

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

    if (ideDebug)
        Print("About to wait for Write \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 (reEnable)
        Enable_Interrupts();

    return IDE_ERROR_NO_ERROR;
}
Esempio n. 15
0
void NE2000_Transmit(struct Net_Device *device, void *buffer, ulong_t length) {

    ulong_t baseAddr = device->baseAddr;

    KASSERT(!Interrupts_Enabled());

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

    /* Make sure we aren't currently transmitting */
    if (In_Byte(baseAddr + NE2K_CR) & NE2K_CR_TXP) {
        Print("ERROR - Currently transmitting\n");
        return;
    }

    /* Reset the card */
    NE2000_Reset(device);

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

    /* Handle the read before write bug */
    Out_Byte(baseAddr + NE2K0W_RBCR0, 0x42);
    Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00);
    Out_Byte(baseAddr + NE2K0W_RSAR0, 0x42);
    Out_Byte(baseAddr + NE2K0W_RSAR1, 0x00);
    Out_Byte(baseAddr + NE2K_CR, NE2K_CR_DMA_RREAD + NE2K_CR_STA);
    Out_Byte(baseAddr + NE2K0R_ISR, NE2K_ISR_RDC);

    /* 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, 0x00);
    Out_Byte(baseAddr + NE2K0W_RSAR1, NE2K_TRANSMIT_PAGE);

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

    /* Write the data to the I/O port */
    for (i = 0; i < newLength; ++i) {
        Out_Word(baseAddr + NE2K_IO_PORT, newBuffer[i]);
    }

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


    /* Wait for transmit remote DMA */
    while ((In_Byte(baseAddr + NE2K0R_ISR) & NE2K_ISR_RDC) == 0) {
        Print("Waiting on remote DMA for transmit \n");
    }

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

    /* Now that Remote DMA is complete, set up the transmit */

    /* Store the transmit page in the transmit register */
    Out_Byte(baseAddr + NE2K0W_TPSR, NE2K_TRANSMIT_PAGE);

    /* Set transmit byte count */
    Out_Byte(baseAddr + NE2K0W_TBCR0, length & 0xFF);
    Out_Byte(baseAddr + NE2K0W_TBCR1, length >> 8);

    /* Issue transmit command */
    Out_Byte(baseAddr + NE2K_CR, NE2K_CR_NODMA | NE2K_CR_STA | NE2K_CR_TXP);

    device->txBytes += length;
}
Esempio n. 16
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;
}
Esempio n. 17
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;
}
Esempio n. 18
0
/*
 * Get a byte from the data register.
 */
static uchar_t Floppy_In(void)
{
    Wait_For_MRQ(FDC_STATUS_READY_READ);
    return In_Byte(FDC_DATA_REG);
}
Esempio n. 19
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;
}
Esempio n. 20
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");
}
Esempio n. 21
0
/*
 * Handler for keyboard interrupts.
 */
static void Keyboard_Interrupt_Handler(struct Interrupt_State* state)
{
    uchar_t status, scanCode;
    unsigned flag = 0;
    bool release = false, shift;
    Keycode keycode;

    Begin_IRQ(state);

    status = In_Byte(KB_CMD);
    IO_Delay();

    if ((status & KB_OUTPUT_FULL) != 0) {
	/* There is a byte available */
	scanCode = In_Byte(KB_DATA);
	IO_Delay();
/*
 *	Print("code=%x%s\n", scanCode, (scanCode&0x80) ? " [release]" : "");
 */

	if (scanCode & KB_KEY_RELEASE) {
	    release = true;
	    scanCode &= ~(KB_KEY_RELEASE);
	}

	if (scanCode >= SCAN_TABLE_SIZE) {
	    Print("Unknown scan code: %x\n", scanCode);
	    goto done;
	}

	/* Process the key */
	shift = ((s_shiftState & SHIFT_MASK) != 0);
	keycode = shift ? s_scanTableWithShift[scanCode] : s_scanTableNoShift[scanCode];

	/* Update shift, control and alt state */
	switch (keycode) {
	case KEY_LSHIFT:
	    flag = LEFT_SHIFT;
	    break;
	case KEY_RSHIFT:
	    flag = RIGHT_SHIFT;
	    break;
	case KEY_LCTRL:
	    flag = LEFT_CTRL;
	    break;
	case KEY_RCTRL:
	    flag = RIGHT_CTRL;
	    break;
	case KEY_LALT:
	    flag = LEFT_ALT;
	    break;
	case KEY_RALT:
	    flag = RIGHT_ALT;
	    break;
	default:
	    goto noflagchange;
	}

	if (release)
	    s_shiftState &= ~(flag);
	else
	    s_shiftState |= flag;
			
	/*
	 * Shift, control and alt keys don't have to be
	 * queued, flags will be set!
	 */
	goto done;

noflagchange:
	/* Format the new keycode */
	if (shift)
	    keycode |= KEY_SHIFT_FLAG;
	if ((s_shiftState & CTRL_MASK) != 0)
	    keycode |= KEY_CTRL_FLAG;
	if ((s_shiftState & ALT_MASK) != 0)
	    keycode |= KEY_ALT_FLAG;
	if (release)
	    keycode |= KEY_RELEASE_FLAG;
		
	/* Put the keycode in the buffer */
	Enqueue_Keycode(keycode);

	/* Wake up event consumers */
	Wake_Up(&s_waitQueue);

	/*
	 * Pick a new thread upon return from interrupt
	 * (hopefully the one waiting for the keyboard event)
	 */
	g_needReschedule = true;
    }

done:
    End_IRQ(state);
}
Esempio n. 22
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;

}