/*------------------------------------------------------------------------ * cominit -- initialize a com device (NS16{4/5}50) *------------------------------------------------------------------------ */ int cominit(struct devsw *pdev) { struct comsoft *pcom; void *csr = pdev->dvcsr; /* void comint(); */ /* not needed and conflicting PW */ pcom = &comtab[pdev->dvminor]; pcom->com_pdev = pdev; set_evec(pdev->dvivec, comint); #ifdef X86 outb(csr+LCR, LCR_DLAB); outb(csr+DLL, 12); /* 9600 baud */ outb(csr+DLM, 0); /* 9600 baud */ outb(csr+LCR, LCR_W8); /* 8N1 */ /* raise DTR and RTS & enable interrupts */ outb(csr+MCR, MCR_DTR | MCR_RTS | MCR_OUT2); #endif pcom->com_osema = screate(COMBUFSZ); #ifdef X86 outb(csr+IER, 0x0f); /* enable interrupts */ (void) inb(csr+IIR); #endif return OK; }
initevec() { int i; STATWORD ps; #ifdef __COM32__ puts_com32("initevec() begin"); #endif for (i=0; i<NID; ++i) set_evec(i, (int)defevec[i]); /* * "girmask" masks all (bus) interrupts with the default handler. * initially, all, then cleared as handlers are set via set_evec() */ girmask = 0xfffb; /* leave bit 2 enabled for IC cascade */ #ifdef __COM32__ puts_com32("initevec() set_evec() done\n"); #endif lidt(); #ifdef __COM32__ puts_com32("initevec() lidt() done\n"); #endif init8259(); #ifdef __COM32__ puts_com32("initevec() init8259() done\n"); #endif }
/*------------------------------------------------------------------------ * clkinit - initialize the clock and sleep queue at startup *------------------------------------------------------------------------ */ void clkinit(void) { uint16 intv; /* clock rate in KHz */ /* Set interrupt vector for clock to invoke clkint */ set_evec(IRQBASE, (uint32)clkint); /* clock rate is 1.190 Mhz; this is 10ms interrupt rate */ intv = 1190; sleepq = newqueue(); /* allocate a queue to hold the delta */ /* list of sleeping processes */ preempt = QUANTUM; /* initial time quantum */ /* Specify that seepq is initially empty */ slnonempty = FALSE; clktime = 0; /* start counting seconds */ /* set to: timer 0, 16-bit counter, rate generator mode, counter is binary */ outb(CLKCNTL, 0x34); /* must write LSB first, then MSB */ outb(CLOCK0, (char)intv); outb(CLOCK0, intv>>8); return; }
/** * @ingroup timer * * Initialize the clock and sleep queue. This function is called at startup. */ void clkinit(void) { sleepq = queinit(); /* initialize sleep queue */ clkticks = 0; #ifdef DETAIL kprintf("Time base %dHz, Clock ticks at %dHz\r\n", platform.clkfreq, CLKTICKS_PER_SEC); #endif /* TODO: Get rid of ugly x86 ifdef. */ #ifdef _XINU_PLATFORM_X86_ time_intr_freq = platform.clkfreq / CLKTICKS_PER_SEC; outb(CLOCKCTL, 0x34); /* LSB then MSB */ outb(CLOCKBASE, time_intr_freq); outb(CLOCKBASE, time_intr_freq >> 8); outb(CLOCKBASE, time_intr_freq >> 8); /* why??? */ set_evec(IRQBASE, (ulong)clockIRQ); #else /* register clock interrupt */ interruptVector[IRQ_TIMER] = clkhandler; enable_irq(IRQ_TIMER); clkupdate(platform.clkfreq / CLKTICKS_PER_SEC); #endif }
void initevec(void) { int i; /* bzero( idt, sizeof( struct idt ) * 256 ); */ memset( idt, 0, sizeof( struct idt ) * 256 ); for (i=0; i<NID; ++i) set_evec(i, (long)defevec[i]); lidt(); init8259(); set_exception=&set_evec; }
int initevec() { int i; for (i=0; i<NID; ++i) set_evec(i, (long)defevec[i]); /* * "girmask" masks all (bus) interrupts with the default handler. * initially, all, then cleared as handlers are set via set_evec() */ girmask = 0xfffb; /* leave bit 2 enabled for IC cascade */ lidt(); init8259(); return(OK); }
/*------------------------------------------------------------------------ * kbminit -- initialize the PC keyboard *------------------------------------------------------------------------ */ int kbminit(struct devsw *pdev) { set_evec(pdev->dvivec, (void (*)())kbmint); while (inb(KB_CSR) & KBS_NRDY); /* wait for input buffer empty */ outb(KB_CSR, 0x60); /* next write is a command */ while (inb(KB_CSR) & KBS_NRDY); outb(KB_DAT, 0x69); while (inb(KB_CSR) & KBS_NRDY); outb(KB_DAT, 0xff); /* reset */ while ((inb(KB_CSR) & KBS_HASDAT) == 0); pdev->dvioblk = 0; { unsigned char c = inb(KB_DAT); /* if (inb(KB_DAT) != 0xAA) panic("keyboard initialization error\n"); */ } }
/* *------------------------------------------------------------------------ * clkinit - initialize the clock and sleep queue (called at startup) *------------------------------------------------------------------------ */ int clkinit(void) { int clkint(); set_evec(IRQBASE, clkint); clkruns = 1; clockq = newqueue(); preempt = QUANTUM; /* initial time quantum */ compute_delay(); /* set to: timer 0, 16-bit counter, rate generator mode, counter is binary */ outb(CLKCNTL, 0x34); /* must write LSB first, then MSB */ outb(CLOCK0, (char)DIVIDER); outb(CLOCK0, DIVIDER>>8); return OK; }
/*------------------------------------------------------------------------ * mon_netinit - init nif[] *------------------------------------------------------------------------ */ int mon_netinit() { struct ethdev *ped = &mon_eth[0]; extern short girmask; extern int mon_clkint(); /* clock int. handler, for retx purpose */ blkcopy(mon_nif[0].ni_hwa.ha_addr, ped->ed_paddr, EP_ALEN); blkcopy(mon_nif[0].ni_hwb.ha_addr, ped->ed_bcast, EP_ALEN); mon_nif[0].ni_state = NIS_UP; girmask = 0xfffb; /* * 1. Set monitor's clock interrupt handler (for retx purpose). * (It sets the corresponding mask bit in "girmask" to 0.) * 2. Sets the Ethernet mask bit in "girmask" to 0. * 3. call enable() to enable clock & ethernet interrupts. */ set_evec(IRQBASE, (unsigned int) mon_clkint); girmask = (girmask & ~(1 << ped->ed_irq)); enable(); return(OK); }
/* *------------------------------------------------------------------------ * clkinit - initialize the clock and sleep queue (called at startup) *------------------------------------------------------------------------ */ void clkinit() { unsigned short intv; int clkint(); set_evec(IRQBASE, (u_long)clkint); /* clock rate is 1.190 Mhz; this is 10ms interrupt rate */ intv = 1190; clkruns = 1; clockq = newqueue(); preempt = QUANTUM; /* initial time quantum */ clmutex = screate(1); /* set to: timer 0, 16-bit counter, rate generator mode, counter is binary */ outb(CLKCNTL, 0x34); /* must write LSB first, then MSB */ outb(CLOCK0, (char)intv); outb(CLOCK0, intv>>8); outb(CLOCK0, intv>>8); }
/*------------------------------------------------------------------------ * i8255x_open - allocate resources and prepare hardware for transmit and * receive *------------------------------------------------------------------------ */ status i8255x_open( struct ether *ethptr ) { struct i82559_tx_desc* txRingptr; struct i82559_rx_desc* rxRingptr; int32 i; // uint32 bufptr; /* Initialize structure pointers */ ethptr->rxRingSize = I8255X_RX_RING_SIZE; ethptr->txRingSize = I8255X_TX_RING_SIZE; ethptr->isem = semcreate(0); ethptr->osem = semcreate(ethptr->txRingSize); /* * Rings must be aligned on a 4-byte boundary for I82559 * Only Simplified Frame descriptors can be used, as that is the only one supported. * */ ethptr->stats = getmem(I82559_DUMP_STATS_SIZE + 4); /*4 extra bytes assigned to make sure the address is dword alligned*/ ethptr->rxRing = (void *)getmem((ethptr->rxRingSize + 1) * ( I82559_RFDSIZE + ETH_BUF_SIZE ) ); ethptr->txRing = (void *)getmem((ethptr->txRingSize + 1) * ( I82559_TFDSIZE + ETH_BUF_SIZE )); if ( (SYSERR == (uint32)ethptr->rxRing) || (SYSERR == (uint32)ethptr->txRing) || SYSERR == (uint32) ethptr->stats ) { //kprintf("i8255x_open: fail to allocate tx/rx Bufs\n\r"); return SYSERR; } /*16-byte allignment. Not needed, but to be on safe side*/ ethptr->rxRing = (void *)(((uint32)ethptr->rxRing + 0xf) & ~0xf); ethptr->txRing = (void *)(((uint32)ethptr->txRing + 0xf) & ~0xf); ethptr->stats = (void *) (((uint32)ethptr->stats + 3) & ~0x3); /*D-word alligned*/ ethptr->rxBufs = NULL; ethptr->txBufs = NULL; //kprintf("The rings are tx : %u rx: %u \r\n", ethptr->txRing, ethptr->rxRing); /* Set buffer pointers and rings to zero */ memset(ethptr->rxRing, '\0', ( I82559_RFDSIZE + ETH_BUF_SIZE )* ethptr->rxRingSize); memset(ethptr->txRing, '\0', ( I82559_TFDSIZE + ETH_BUF_SIZE )* ethptr->txRingSize); txRingptr = (struct i82559_tx_desc *)ethptr->txRing; for(i=0; i < ethptr->txRingSize; ++i ){ txRingptr = (struct i82559_tx_desc *)((char *)(ethptr->txRing)+i*(I82559_TFDSIZE + ETH_BUF_SIZE)); /*NOTE: The following statment assumes that segmented addressing mode is used*/ /* Set the link to the next CB in the ring */ txRingptr->link_addr = ((i+1)%ethptr->txRingSize)*(I82559_TFDSIZE + ETH_BUF_SIZE); /* Set the entire status word to 0x0000 , FIXME, check if this is OK */ txRingptr->status = 0x0000; /** * Command Word Description(from Bit 16-31) : * Command = 100 (Transmit Command) * SF = 0 (Simplified Mode) * NC = 0 (CRC and address inserted by device) * 000 (Reserved and set to zeros) * CID = 00000 (Delay for CNA Interrupt, set to 0 for now, TODO more work required) * I = 1 (Generate interrupt after the execution of CB is complete) * S = 1 (Put CU to sleep after execution of CB and more .. Check manual) * EL = 1 (Indicates this CB is the last one in the CBL, is set to 1 for all CBs initially) * Command Word : 1110000000000100 / E004 */ //txRingptr->command = 0xA030; txRingptr->command = 0xE004; txRingptr->tbd_addr = 0xFFFFFFFF; /* Transmit threshold, represents the number of bytes in the * transmit FIFO for transmission to happen, is multiplied by * 8 to give the bytes, should be between 1 and 0E0h */ /* 16 bytes required in the trasnmit FIFO */ txRingptr->tx_treshold = 0x02; /* This is not used in the simplified structure, set it to 0, TBD number */ txRingptr->tbd_no = 0x00; /*These parameters should be changed when packet is ready to be transmitted * Also, EL bit should be unset*/ txRingptr->byte_count = 0; } /* RFA initialization */ rxRingptr = (struct i82559_rx_desc *)ethptr->rxRing; for(i=0; i < ethptr->rxRingSize; ++i){ rxRingptr = (struct i82559_rx_desc *)((char *)(ethptr->rxRing)+i*(I82559_RFDSIZE + ETH_BUF_SIZE)); /* Set the pointer to the next Receive frame.*/ rxRingptr->link_addr = ((i+1)%ethptr->rxRingSize)*(I82559_RFDSIZE + ETH_BUF_SIZE); //kprintf("Set link address to %u for [%d]\r\n", rxRingptr->link_addr, i); /* Set the entire status word to 0x0000 since this is set by the device later FIXME*/ rxRingptr->status = 0x0000; /* * Command Word Description( from Bit 16-31): * Command = 000 (command opcode for receive) * SF = 0 (for simplified mode) * H = 0 (decides if the RFD is a header RFD or not, is disregarded if load HDS was not run before * 000000000 (Reserved) * S = 0 ( Suspend the RU after receiving the frame) * EL = 0 (Indicates this is the last RFD in the RFA, set to 0 for all RFDs initially, except the last RFD) * Command Word : 1000000000000000 / 8000 */ rxRingptr->command = 0x0000; /*FIXME : Change these later */ /* Set the actual count to 0x0000 (this will set the EOF and F bits too) */ rxRingptr->ac_count = 0x0000; /* * Set the size to ETH_BUF_SIZE Later */ rxRingptr->size = ETH_BUF_SIZE; } /* * For the last RFD in the ring, we need to set the EL Bit and the S bit for the last block * this changes the command word to 0xC000 */ rxRingptr->command = 0x4000; /* Reset the NIC to bring it into a known state and initialize it */ if (OK != i8255x_reset(ethptr)) { //kprintf("i8255x_open: fail to reset I8255X device\n"); return SYSERR; } /* Configure the NIC */ if (OK != i8255x_configure(ethptr)) { //kprintf("i8255x_open: fail to configure I8255X device\n"); return SYSERR; } /* Enable interrupt */ set_evec(ethptr->dev->dvirq + IRQBASE, (uint32)ethDispatch); //kprintf("Calling the first IRQ Enable \r\n"); //kprintf("The interrupt mask is : %x\r\n", inw(ethptr->iobase +I8255X_SCB_COMMAND_LOW)); i8255x_irq_enable(ethptr); /* Start the receive unit */ i8255x_exec_ru(ethptr, (uint32) ethptr->rxHead*(I82559_RFDSIZE + ETH_BUF_SIZE)); //kprintf("All user processes have completed \r\n"); return OK; }
/*------------------------------------------------------------------------ * sysinit -- initialize all Xinu data structeres and devices *------------------------------------------------------------------------ */ LOCAL sysinit() { static long currsp; int i,j; struct pentry *pptr; struct sentry *sptr; struct mblock *mptr; SYSCALL pfintr(); numproc = 0; /* initialize system variables */ nextproc = NPROC-1; nextsem = NSEM-1; nextqueue = NPROC; /* q[0..NPROC-1] are processes */ /* initialize free memory list */ /* PC version has to pre-allocate 640K-1024K "hole" */ if (maxaddr+1 > HOLESTART) { memlist.mnext = mptr = (struct mblock *) roundmb(&end); mptr->mnext = (struct mblock *)HOLEEND; mptr->mlen = (int) truncew(((unsigned) HOLESTART - (unsigned)&end)); mptr->mlen -= 4; mptr = (struct mblock *) HOLEEND; mptr->mnext = 0; mptr->mlen = (int) truncew((unsigned)maxaddr - HOLEEND - NULLSTK); /* mptr->mlen = (int) truncew((unsigned)maxaddr - (4096 - 1024 ) * 4096 - HOLEEND - NULLSTK); */ } else { /* initialize free memory list */ memlist.mnext = mptr = (struct mblock *) roundmb(&end); mptr->mnext = 0; mptr->mlen = (int) truncew((unsigned)maxaddr - (int)&end - NULLSTK); } for (i=0 ; i<NPROC ; i++) /* initialize process table */ proctab[i].pstate = PRFREE; #ifdef MEMMARK _mkinit(); /* initialize memory marking */ #endif #ifdef RTCLOCK clkinit(); /* initialize r.t.clock */ #endif mon_init(); /* init monitor */ #ifdef NDEVS for (i=0 ; i<NDEVS ; i++ ) { init_dev(i); } #endif pptr = &proctab[NULLPROC]; /* initialize null process entry */ pptr->pstate = PRCURR; for (j=0; j<7; j++) pptr->pname[j] = "prnull"[j]; pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK; pptr->pbase = (WORD) maxaddr - 3; /* pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK - (4096 - 1024 )*4096; pptr->pbase = (WORD) maxaddr - 3 - (4096-1024)*4096; */ pptr->pesp = pptr->pbase-4; /* for stkchk; rewritten before used */ *( (int *)pptr->pbase ) = MAGIC; pptr->paddr = (WORD) nulluser; pptr->pargs = 0; pptr->pprio = 0; currpid = NULLPROC; for (i=0 ; i<NSEM ; i++) { /* initialize semaphores */ (sptr = &semaph[i])->sstate = SFREE; sptr->sqtail = 1 + (sptr->sqhead = newqueue()); } rdytail = 1 + (rdyhead=newqueue());/* initialize ready list */ //OS proj 3 modify //OS proj 3 modify init_bsm(); //initialize 16 Backing stores init_frm(); //initialize 1024 frames set_evec(14,pfintr); return(OK); }
/*------------------------------------------------------------------------ * ttyInit - initialize buffers and modes for a tty line *------------------------------------------------------------------------ */ devcall ttyInit( struct dentry *devptr /* entry in device switch table */ ) { struct ttycblk *typtr; /* pointer to ttytab entry */ struct uart_csreg *uptr; /* address of UART's CSRs */ typtr = &ttytab[ devptr->dvminor ]; /* Initialize values in the tty control block */ typtr->tyihead = typtr->tyitail = /* set up input queue */ &typtr->tyibuff[0]; /* as empty */ typtr->tyisem = semcreate(0); /* input semaphore */ typtr->tyohead = typtr->tyotail = /* set up output queue */ &typtr->tyobuff[0]; /* as empty */ typtr->tyosem = semcreate(TY_OBUFLEN); /* output semaphore */ typtr->tyehead = typtr->tyetail = /* set up echo queue */ &typtr->tyebuff[0]; /* as empty */ typtr->tyimode = TY_IMCOOKED; /* start in cooked mode */ typtr->tyiecho = TRUE; /* echo console input */ typtr->tyieback = TRUE; /* honor erasing bksp */ typtr->tyevis = TRUE; /* visual control chars */ typtr->tyecrlf = TRUE; /* echo CRLF for NEWLINE*/ typtr->tyicrlf = TRUE; /* map CR to NEWLINE */ typtr->tyierase = TRUE; /* do erasing backspace */ typtr->tyierasec = TY_BACKSP; /* erase char is ^H */ typtr->tyeof = TRUE; /* honor eof on input */ typtr->tyeofch = TY_EOFCH; /* end-of-file character*/ typtr->tyikill = TRUE; /* allow line kill */ typtr->tyikillc = TY_KILLCH; /* set line kill to ^U */ typtr->tyicursor = 0; /* start of input line */ typtr->tyoflow = TRUE; /* handle flow control */ typtr->tyoheld = FALSE; /* output not held */ typtr->tyostop = TY_STOPCH; /* stop char is ^S */ typtr->tyostart = TY_STRTCH; /* start char is ^Q */ typtr->tyocrlf = TRUE; /* send CRLF for NEWLINE*/ typtr->tyifullc = TY_FULLCH; /* send ^G when buffer */ /* is full */ /* Initialize the UART */ uptr = (struct uart_csreg *)devptr->dvcsr; /* Set baud rate */ outb((int)&uptr->lcr, UART_LCR_DLAB); outb((int)&uptr->dlm, 0x00); outb((int)&uptr->dll, 0x0c); outb((int)&uptr->lcr, UART_LCR_8N1); /* 8 bit char, No Parity*/ /* and 1 Stop bit */ outb((int)&uptr->fcr, 0x00); /* Disable FIFO for now */ /* OUT2 value is used to control the onboard interrupt tri-state*/ /* buffer. It should be set high to generate interrupts */ outb((int)&uptr->mcr, UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); /* Enbale user-def. OUT2*/ /* Register the interrupt dispatcher for the tty device */ set_evec( devptr->dvirq, (uint32)devptr->dvintr ); /* Enable interrupts on the device */ /* Enable UART FIFOs, clear and set interrupt trigger level */ outb((int)&uptr->fcr, UART_FCR_EFIFO | UART_FCR_RRESET | UART_FCR_TRESET | UART_FCR_TRIG2); ttyKickOut(typtr, uptr); (void)inb((int)&uptr->iir); (void)inb((int)&uptr->lsr); (void)inb((int)&uptr->msr); (void)inb((int)&uptr->buffer); return OK; }
int mon_3c905_ethinit () { struct dev_3c905* dev; struct netif* pni; struct ethdev* ped; unsigned short status; unsigned char* buf; int i; dev = &mon_dev_eth; dev->state = 0; /* read config information */ mon_pci_bios_read_config_dword(dev->pcidev, _3C905_PCI_IOBASE, &dev->iobase); mon_pci_bios_read_config_dword(dev->pcidev, _3C905_PCI_MEMBASE, &dev->membase); mon_pci_bios_read_config_byte (dev->pcidev, _3C905_PCI_IRQ, &dev->irq); /* the low bit is set to indicate I/O */ dev->iobase &= ~1; /* if mem address is below 1 MB */ dev->membase &= ~2; /* enable PCI bus master */ mon_pci_bios_read_config_word(dev->pcidev, PCI_COMMAND, &status); status |= PCI_BUSMASTER; mon_pci_bios_write_config_word(dev->pcidev, PCI_COMMAND, status); /* read the MAC address */ _3CSEL(dev, 2); *((unsigned short*) &dev->hwa[0]) = inw(dev->iobase + 0x00); *((unsigned short*) &dev->hwa[2]) = inw(dev->iobase + 0x02); *((unsigned short*) &dev->hwa[4]) = inw(dev->iobase + 0x04); /* enable this to "emulate" xinu109 *((unsigned short*) &dev->hwa[0]) = 0xAA00; *((unsigned short*) &dev->hwa[2]) = 0xA300; *((unsigned short*) &dev->hwa[4]) = 0x8A75; outw(dev->iobase + 0x00, *((unsigned short*) &dev->hwa[0])); outw(dev->iobase + 0x02, *((unsigned short*) &dev->hwa[2])); outw(dev->iobase + 0x04, *((unsigned short*) &dev->hwa[4])); */ #ifdef BOOT_MONITOR *((unsigned short*) &dev->hwa[0]) |= 0xFF01; #endif /* initialize TX/RX rings */ mon_eth_txring = (struct eth_pd*) (((unsigned long) txring + 0xF) & ~0xF); mon_eth_rxring = (struct eth_pd*) (((unsigned long) rxring + 0xF) & ~0xF); for (i = 0; i < _3C905_RXRING; i++) { mon_eth_rxring[i].next = &mon_eth_rxring[(i + 1) % _3C905_RXRING]; mon_eth_rxring[i].status = 0; buf = (unsigned char*) GETBUF(mon_Net.netpool); if (buf == (unsigned char *)SYSERR || buf == (unsigned char *)0) { kprintf("No buffer in ethinit()"); panic("could not allocate buffer for monitor"); } mon_eth_rxring[i].buffer = (void*) buf + sizeof(struct ehx); mon_eth_rxring[i].length = _3C905_FLG_LASTFRAG | EP_MAXLEN; } dev->rx_begin = 0; bzero(mon_eth_txring, sizeof(struct eth_pd) * _3C905_TXRING); dev->tx_begin = 0; dev->tx_end = _3C905_TXRING - 1; /* reset nic */ ethcmdwait(dev, _3C905_CMD_RXRESET, 0x7); ethcmdwait(dev, _3C905_CMD_TXRESET, 0x3); /* enable interrupts */ set_evec(dev->irq + IRQBASE, (unsigned) mon_ethint_hi); _3CCMD(dev, _3C905_CMD_SETINDICATION, _3C905_MSK_INTERRUPTS); _3CCMD(dev, _3C905_CMD_SETINTERRUPT, _3C905_MSK_INTERRUPTS); /* enable receiving and transmission */ _3CCMD(dev, _3C905_CMD_SETRXFILTER, _3C905_MSK_RXFILTER); ethcmdwait(dev, _3C905_CMD_UPSTALL, 0); outl(dev->iobase + _3C905_OFF_UPLISTPTR, (int) mon_eth_rxring); _3CCMD(dev, _3C905_CMD_UPUNSTALL, 0); _3CCMD(dev, _3C905_CMD_RXENABLE, 0); _3CCMD(dev, _3C905_CMD_TXENABLE, 0); /* set the OS structures */ dev->ifn = 0; pni = &mon_nif[0]; pni->ni_write = mon_3c905_ethwrite; ped = &mon_eth[0]; for (i = 0; i < EP_ALEN; i++) { ped->ed_paddr[i] = dev->hwa[i]; ped->ed_bcast[i] = ~0; } ped->ed_irq = dev->irq; return(OK); }
/*------------------------------------------------------------------------ * nulluser -- initialize system and become the null process (id==0) *------------------------------------------------------------------------ */ nulluser() /* babysit CPU when no one is home */ { int userpid; unsigned long temp; console_dev = SERIAL0; /* set console to COM0 */ initevec(); kprintf("system running up!\n"); sysinit(); enable(); /* enable interrupts */ sprintf(vers, "PC Xinu %s", VERSION); kprintf("\n\n%s\n", vers); if (reboot++ < 1) kprintf("\n"); else kprintf(" (reboot %d)\n", reboot); kprintf("%d bytes real mem\n", (unsigned long) maxaddr+1); #ifdef DETAIL kprintf(" %d", (unsigned long) 0); kprintf(" to %d\n", (unsigned long) (maxaddr) ); #endif kprintf("%d bytes Xinu code\n", (unsigned long) ((unsigned long) &end - (unsigned long) start)); #ifdef DETAIL kprintf(" %d", (unsigned long) start); kprintf(" to %d\n", (unsigned long) &end ); #endif #ifdef DETAIL kprintf("%d bytes user stack/heap space\n", (unsigned long) ((unsigned long) maxaddr - (unsigned long) &end)); kprintf(" %d", (unsigned long) &end); kprintf(" to %d\n", (unsigned long) maxaddr); #endif kprintf("clock %sabled\n", clkruns == 1?"en":"dis"); /* initialize_pagedirectory(); initialize_pagetable(); get_frame(1,FR_DIR,0); get_frame(1,FR_TBL,0); get_frame(1,FR_TBL,0); get_frame(1,FR_TBL,0); get_frame(1,FR_TBL,0); */ init_frm(); init_bsm(); temp = create_ps() ; write_cr3(0x400000); set_evec(14,pfintr); proctab[currpid].pdbr = temp; // pageq.next= &pageq; //Always points to head myheadq = NULL; //actual pointer used by page replacement policyi currq = NULL; pcurrq = NULL; /* create a process to execute the user's main program */ userpid = create(main,INITSTK,INITPRIO,INITNAME,INITARGS); enable_paging(); resume(userpid); while (TRUE) /* empty */; }
/*------------------------------------------------------------------------ * _82545EMInit - initialize Intel 82545EM Ethernet NIC *------------------------------------------------------------------------ */ status _82545EMInit( struct ether *ethptr ) { struct e1000_tx_desc* txRingPtr; struct e1000_rx_desc* rxRingPtr; uint16 command; int32 i; uint32 rar_low, rar_high, bufptr; /* Read PCI configuration information */ /* Read I/O base address */ pci_bios_read_config_dword(ethptr->pcidev, E1000_PCI_IOBASE, (uint32 *)ðptr->iobase); ethptr->iobase &= ~1; ethptr->iobase &= 0xffff; /* the low bit is set to indicate I/O */ /* Read interrupt line number */ pci_bios_read_config_byte (ethptr->pcidev, E1000_PCI_IRQ, (byte *)&(ethptr->dev->dvirq)); /* Enable PCI bus master, I/O port access */ pci_bios_read_config_word(ethptr->pcidev, E1000_PCI_COMMAND, &command); command |= E1000_PCI_CMD_MASK; pci_bios_write_config_word(ethptr->pcidev, E1000_PCI_COMMAND, command); /* Read the MAC address */ rar_low = e1000_io_readl(ethptr->iobase, E1000_RAL(0)); rar_high = e1000_io_readl(ethptr->iobase, E1000_RAH(0)); for (i = 0; i < ETH_ADDR_LEN; i++) ethptr->devAddress[i] = (byte)(rar_low >> (i*8)); for (i = 0; i < ETH_ADDR_LEN; i++) ethptr->devAddress[i + 4] = (byte)(rar_high >> (i*8)); kprintf("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n", 0xffðptr->devAddress[0], 0xffðptr->devAddress[1], 0xffðptr->devAddress[2], 0xffðptr->devAddress[3], 0xffðptr->devAddress[4], 0xffðptr->devAddress[5]); /* Initialize structure pointers */ ethptr->rxRingSize = E1000_RX_RING_SIZE; ethptr->txRingSize = E1000_TX_RING_SIZE; ethptr->isem = semcreate(0); ethptr->osem = semcreate(ethptr->txRingSize); /* Rings must be aligned on a 16-byte boundary */ ethptr->rxRing = (void *)getmem((ethptr->rxRingSize + 1) * E1000_RDSIZE); ethptr->txRing = (void *)getmem((ethptr->txRingSize + 1) * E1000_TDSIZE); ethptr->rxRing = (void *)(((uint32)ethptr->rxRing + 0xf) & ~0xf); ethptr->txRing = (void *)(((uint32)ethptr->txRing + 0xf) & ~0xf); /* Buffers are highly recommended to be allocated on cache-line */ /* size (64-byte for E8400) */ ethptr->rxBufs = (void *)getmem((ethptr->rxRingSize + 1) * ETH_BUF_SIZE); ethptr->txBufs = (void *)getmem((ethptr->txRingSize + 1) * ETH_BUF_SIZE); ethptr->rxBufs = (void *)(((uint32)ethptr->rxBufs + 0x3f) & ~0x3f); ethptr->txBufs = (void *)(((uint32)ethptr->txBufs + 0x3f) & ~0x3f); if ( (SYSERR == (uint32)ethptr->rxBufs) || (SYSERR == (uint32)ethptr->txBufs) ) { return SYSERR; } /* Set buffer pointers and rings to zero */ memset(ethptr->rxBufs, '\0', ethptr->rxRingSize * ETH_BUF_SIZE); memset(ethptr->txBufs, '\0', ethptr->txRingSize * ETH_BUF_SIZE); memset(ethptr->rxRing, '\0', E1000_RDSIZE * ethptr->rxRingSize); memset(ethptr->txRing, '\0', E1000_TDSIZE * ethptr->txRingSize); /* Insert the buffer into descriptor ring */ rxRingPtr = (struct e1000_rx_desc *)ethptr->rxRing; bufptr = (uint32)ethptr->rxBufs; for (i = 0; i < ethptr->rxRingSize; i++) { rxRingPtr->buffer_addr = (uint64)bufptr; rxRingPtr++; bufptr += ETH_BUF_SIZE; } txRingPtr = (struct e1000_tx_desc *)ethptr->txRing; bufptr = (uint32)ethptr->txBufs; for (i = 0; i < ethptr->txRingSize; i++) { txRingPtr->buffer_addr = (uint64)bufptr; txRingPtr++; bufptr += ETH_BUF_SIZE; } /* Reset packet buffer allocation to default */ e1000_io_writel(ethptr->iobase, E1000_PBA, E1000_PBA_48K); /* Reset the NIC to bring it into a known state and initialize it */ _82545EM_reset_hw(ethptr); /* Initialize the hardware */ if (_82545EM_init_hw(ethptr) != OK) return SYSERR; /* Configure the NIC */ e1000_io_writel(ethptr->iobase, E1000_AIT, 0); /* Configure the RX */ _82545EM_configure_rx(ethptr); /* Configure the TX */ _82545EM_configure_tx(ethptr); /* Register the interrupt and enable interrupt */ set_evec(ethptr->dev->dvirq + IRQBASE, (uint32)e1000Dispatch); e1000IrqEnable(ethptr); return OK; }