/* * Calibrate the delay loop. * This will initialize s_spinCountPerTick, which indicates * how many iterations of the loop are executed per timer tick. */ static void Calibrate_Delay(void) { Disable_Interrupts(); /* Install temporarily interrupt handler */ Install_IRQ(TIMER_IRQ, &Timer_Calibrate); Enable_IRQ(TIMER_IRQ); Enable_Interrupts(); /* Wait a few ticks */ while (g_numTicks < CALIBRATE_NUM_TICKS) ; /* * Execute the spin loop. * The temporary interrupt handler will overwrite the * loop counter when the next tick occurs. */ Spin(INT_MAX); Disable_Interrupts(); /* * Mask out the timer IRQ again, * since we will be installing a real timer interrupt handler. */ Disable_IRQ(TIMER_IRQ); Enable_Interrupts(); }
/* * 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"); }
void Init_Timer(void) { /* * TODO: reprogram the timer to set the frequency. * In bochs, it defaults to 18Hz, which is actually pretty * reasonable. */ Print("Initializing timer...\n"); /* configure for default clock */ Out_Byte(0x43, 0x36); Out_Byte(0x40, 0x00); Out_Byte(0x40, 0x00); /* Calibrate for delay loop */ Calibrate_Delay(); Print("Delay loop: %d iterations per tick\n", s_spinCountPerTick); /* Install an interrupt handler for the timer IRQ */ Install_IRQ(TIMER_IRQ, &Timer_Interrupt_Handler); Enable_IRQ(TIMER_IRQ); }
void Init_Timer_Interrupt(void) { // Enable_IRQ(TIMER_IRQ); Enable_IRQ(32); }
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"); }
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; }