int32_t sys_execve(context_t *c, uint32_t *args) { c_printf("unimplemented call execve\n"); errno = ENOMEM; c->eax = -1; }
int32_t sys_isatty(context_t *c, uint32_t *args) { c_printf("isatty(%d)\n", args[0]); c->eax = 1; }
int32_t sys_fork(context_t *c, uint32_t *args) { c_printf("unimplemented call fork\n"); errno = EAGAIN; c->eax = -1; }
int32_t sys_kill(context_t *c, uint32_t *args) { c_printf("unimplemented call kill\n"); errno = EINVAL; c->eax = -1; }
int32_t sys_link(context_t *c, uint32_t *args) { c_printf("unimplemented call link\n"); errno = EMLINK; c->eax = -1; }
int32_t sys_unlink(context_t *c, uint32_t *args) { c_printf("unimplemented call unlink\n"); errno = ENOENT; c->eax = -1; }
void _ps2_nonack( Uint resp ){ c_printf( "Did not recieve ACK (0xFF) from MOUSE, instead got: '0x%x'.\n", resp ); __panic( "YOU SHALL NOT CYCLE!!!\n" ); }
void _ps2_debug( const char * comp, Uint resp ){ c_printf("DEBUG: %s, RCVD: '0x%x'\n", comp, resp); }
void _vmem_ref_inc_count( Uint32 address, Uint8 is4Mb ) { //loop over all entries Uint32 addr; Uint32 temp; Uint32 mb; Uint32 value; int i; for( i =0; i < REF_SIZE; i++ ) { //skip if empty if( ref[i] == 0 ) { continue; } #ifdef _VMEM_REF_DEBUG c_printf("Found non-empty index %d %x \n", i, ref[i] ); #endif temp = ref[i]; addr = temp & REF_ADDRESS; mb = temp & REF_4MB; //if the address and the correct size is found then if( addr == address && mb == is4Mb ) { //get the reference count value = temp & REF_COUNT; if( value == REF_COUNT ) { __panic("Vmem Ref page shared to many times"); } //increase the reference count by 1 value = value + REF_COUNT_ADD; //reassemble and put it back in the index ref[i] = addr | value | REF_VALID | mb; return; } } //if the address is not found make a new entry for it for( i =0; i < REF_SIZE; i++ ) { //skip if there is already an entry if( ref[i] != 0 ) { continue; } //calulate values and store ref[i] = ( address & REF_ADDRESS) | (is4Mb & REF_4MB) | REF_COUNT_ADD | REF_VALID; #ifdef _VMEM_REF_DEBUG c_printf("Make new entry for addr %x %x\n", address, ref[i] ); #endif return; } __panic( "Vmem Ref out of places for shared pages"); }
int main( void ) { c_puts( "Clearing screen\n"); c_clearscreen(); _interrupt_init(); _pci_alloc_device_list(&pciDevices); status_t status = _pci_scan(pciDevices); if(status != E_SUCCESS){ c_printf("PCI bus scan failed with error 0x%x\n", status); while(1); } c_printf("Detected %d PCI devices\n", pciDevices->size); //bcm_driver_init(pciDevices); status = i8255x_driver_init(pciDevices); c_io_init(); //HACK: To avoid updating c_io for the moment if(status != E_SUCCESS){ c_printf("ERROR: Failed to initialize network card!\n"); } else{ c_printf("SUCCESS: Network card initialized\n"); } pci_device_t* dev = pciDevices->first; struct ethframe frame; frame.header.proto = htons(0xcafe); int j=0; for(; j<ETH_ALEN; j++){ frame.header.dest[j] = 0xff; frame.header.source[j] = j; } while(dev!=NULL){ char scan = c_getchar(); switch(scan){ case 0x34: //Left arrow if(dev->prev == NULL){ dev=pciDevices->last; } else{ dev = dev->prev; } c_clearscreen(); c_moveto(0,1); _pci_print_config(dev); break; case 0x36: //Right arrow if(dev->next == NULL){ dev = pciDevices->first; } else{ dev = dev->next; } c_clearscreen(); c_moveto(0,1); _pci_print_config(dev); break; case 0x0A: //Enter key //Mask device's interrupt //_pci_mask_inta(dev); c_clearscreen(); //_pci_read_config(dev->address, &dev->config); c_moveto(0, 24); c_printf("> "); readline((char*)frame.data); c_moveto(0,24); c_printf("> Sending... "); c_moveto(0,24); i8255x_driver_transmit((uint8_t*)&frame, sizeof(struct ethframe), 0); c_moveto(0,1); c_moveto(0,24); c_printf("> "); //_pci_print_config(dev); //c_printf("MASKED"); break; default: c_printf_at(78, 0, "%x", (int)scan); break; } //__delay(2); } return( 0 ); }
status_t i8255x_driver_setup_irq(void){ status_t status; int i = 0; for(; i < MAX_IRQ_FIND_TRIES; i++){ c_printf("INFO: i8255x_driver_setup_irq - Try %d\n", i); //Initialize IRQ related variables _i8255x_device.irq_vector = -1; _i8255x_device.wrong_irq = false; asm("cli"); //Turn off maskable interrupts _i8255x_device.csr_bar->status |= INTEL_ETH_SCB_STATUS_ACK_MASK; //Trigger software interrupt _i8255x_device.csr_bar->command |= INTEL_ETH_SCB_CMD_TRIGGER_SI; status = _interrupt_wait(1000, &i8255x_driver_isr); if(status != E_SUCCESS){ c_printf("ERROR: i8255x_driver_setup_irq - Wait was inconclusive\n"); //i=0; __delay_ms(1000); continue; } //c_printf("Initial Status: 0x%x\n", _i8255x_device.csr_bar->status); //Setup our ISR status = _interrupt_add_isr(&i8255x_driver_isr, _i8255x_device.irq_vector); if(status != E_SUCCESS){ c_printf("ERROR: i8255x_driver_setup_irq - Failed to add ISR with status=0x%x\n", status); __panic("CRITICAL"); } //Make sure we didn't get the wrong IRQ //We don't expect an interrupt since we didn't trigger one __delay_ms(100); status = _interrupt_wait_for_irq(1000, _i8255x_device.irq_vector); if(_i8255x_device.wrong_irq != false || status != E_TIMEOUT){ //Remove installed ISR status = _interrupt_del_isr(&i8255x_driver_isr, _i8255x_device.irq_vector); if(status != E_SUCCESS){ __panic("ERROR: i8255x_driver_setup_irq - Failed to remove ISR\n"); } continue; } //Test out our ISR _i8255x_device.csr_bar->command |= INTEL_ETH_SCB_CMD_TRIGGER_SI; __delay_ms(10); //c_printf("Final Status: 0x%x\n", _i8255x_device.csr_bar->status); if(_i8255x_device.csr_bar->status == 0x0){ return E_SUCCESS; } } if(i == 3){ //Try using the default IRQ _i8255x_device.irq_vector = I8255X_DEFAULT_IRQ; status = _interrupt_add_isr(&i8255x_driver_isr, I8255X_DEFAULT_IRQ); if(status != E_SUCCESS){ c_printf("ERROR: i8255x_driver_setup_irq - Failed to add ISR with status=0x%x\n", status); __panic("CRITICAL"); } //Test out our ISR _i8255x_device.csr_bar->command |= INTEL_ETH_SCB_CMD_TRIGGER_SI; __delay_ms(10); //c_printf("Final Status: 0x%x\n", _i8255x_device.csr_bar->status); if(_i8255x_device.csr_bar->status == 0x0){ c_printf("INFO: i8255x_driver_setup_irq - Using default IRQ\n"); return E_SUCCESS; } _interrupt_del_isr(&i8255x_driver_isr, I8255X_DEFAULT_IRQ); return E_TOO_MANY_TRIES; } return status; }
void i8255x_driver_isr(int vector, int code){ //c_printf("_i8255x_driver_isr - Status: 0x%x\n", _i8255x_device.csr_bar->status); if(_i8255x_device.csr_bar->status == 0){ c_printf("ERROR: _i8255x_driver_isr - WRONG IRQ, expected %x got %x!\n", _i8255x_device.irq_vector, vector); _i8255x_device.wrong_irq = true; //__panic("ERROR: _i8255x_driver_isr - WRONG IRQ!\n"); } else{ boolean_t handled = false; if((_i8255x_device.csr_bar->status & INTEL_ETH_SCB_STATUS_SWI) != 0){ //Software Interrupt c_printf("INFO: _i8255x_driver_isr - SWI\n"); if(_i8255x_device.irq_vector == -1){ _i8255x_device.irq_vector = vector; } handled=true; } if((_i8255x_device.csr_bar->status & INTEL_ETH_SCB_STATUS_CX) != 0){ //Command Unit Execution finished //c_printf("INFO: _i8255x_driver_isr - CX\n"); _i8255x_device.cu_transition = true; handled=true; } if((_i8255x_device.csr_bar->status & INTEL_ETH_SCB_STATUS_FR) != 0){ //Recieve unit finished recieving frame //c_printf("INFO: _i8255x_driver_isr - FR\n"); //TODO: Wake up sleeping process thats waiting for packet info intel_rx_buffer_t* rx_buf = _i8255x_device.rx_buffer_ptr; if(rx_buf->header.status == 0x00){ c_printf("INFO: _i8255x_driver_isr - FR Nothing to do\n"); } while(rx_buf->header.status != 0x00){ //Did we get back to the start? if(rx_buf->header.link_addr == (uint32_t)_i8255x_device.rx_buffer_ptr){ break; } _i8255x_device.rx_count++; //DELIVER FRAME HERE struct ethframe* frame = (ethframe_t*) &rx_buf->frame[0]; if(frame->header.proto == htons(0xcafe)){ c_printf("MSG: %s\n", frame->data); } /*c_printf("PACKET - status=0x%x EOF=%d F=%d actual_count=0x%x rx_count=%d\n", rx_buf->header.status, ((rx_buf->actual_count>>15) & 1), ((rx_buf->actual_count>>14) & 1), ((~(1<<15) & ~(1<<14)) & rx_buf->actual_count), _i8255x_device.rx_count); */ //Print ethernet header int i=0; for(; i<ETH_HLEN; i++){ //c_printf("%x ", rx_buf->frame[i]); } //c_printf("\n"); if((rx_buf->header.command & ACTION_HDR_CMD_EL) != 0x0){ //RU stopped here i8255x_init_rxb(rx_buf); rx_buf = (intel_rx_buffer_t*) rx_buf->header.link_addr; break; } i8255x_init_rxb(rx_buf); rx_buf = (intel_rx_buffer_t*) rx_buf->header.link_addr; } _i8255x_device.rx_buffer_ptr = rx_buf; //__delay_ms(5000); handled=true; } if((_i8255x_device.csr_bar->status & INTEL_ETH_SCB_STATUS_CNA) != 0){ //CU not Active //c_printf("INFO: _i8255x_driver_isr - CNA\n"); _i8255x_device.cu_transition = true; handled=true; } if((_i8255x_device.csr_bar->status & INTEL_ETH_SCB_STATUS_RNR) != 0){ //Receive unit Not Ready //c_printf("INFO: _i8255x_driver_isr - RNR\n"); _i8255x_device.ru_transition = true; handled=true; _i8255x_device.rx_buffer_base = (intel_rx_buffer_t*) _i8255x_device.rx_buffer_base->header.link_addr; i8255x_write_ru_cmd(SCB_CMD_RUC_START, (uint32_t)_i8255x_device.rx_buffer_base); } if((_i8255x_device.csr_bar->status & INTEL_ETH_SCB_STATUS_MDI) != 0){ //MDI Write complete c_printf("INFO: _i8255x_driver_isr - MDI\n"); handled=true; } if((_i8255x_device.csr_bar->status & INTEL_ETH_SCB_STATUS_FCP) != 0){ //Flow Control Pause c_printf("INFO: _i8255x_driver_isr - FCP\n"); handled=true; //TODO: Punish last sending process } if(handled != true){ c_printf("ERROR: _i8255x_driver_isr - Unexpected status 0x%x\n", _i8255x_device.csr_bar->status); } //Acknowledge all interrupts _i8255x_device.csr_bar->status |= INTEL_ETH_SCB_STATUS_ACK_MASK; //c_printf("_i8255x_driver_isr - Command: 0x%x\n", _i8255x_device.csr_bar->command); //c_printf("_i8255x_driver_isr - Status: 0x%x\n", _i8255x_device.csr_bar->status); } }
status_t i8255x_driver_init(pci_device_list_t* list){ status_t status = _pci_get_device(list, &_i8255x_device.pci, PCI_VENDOR_ID_INTEL, INTEL8255x_DEVICE_ID); if(status == E_BAD_PARAM){ c_printf("ERROR: i8255x_driver_init failed with E_BAD_PARAM!\n"); return status; } else if(status == E_NOT_FOUND){ c_printf("ERROR: i8255x_driver_init failed with E_NOT_FOUND!\n"); return status; } else if(_i8255x_device.pci== NULL){ c_printf("ERROR: i8255x_driver_init got a null device pointer!\n"); return E_NOT_FOUND; } _i8255x_device.csr_bar = (intel_csr_t*) _pci_base_addr(_i8255x_device.pci->config.headers.type0.bar[0]); _pci_print_config(_i8255x_device.pci); status = i8255x_driver_setup_irq(); if(status != E_SUCCESS){ //Failed to detect IRQ c_printf("ERROR: i8255x_driver_init - Failed to auto determine IRQ\n"); return E_NOT_FOUND; } c_printf("IRQ: 0x%x\n", _i8255x_device.irq_vector); c_printf("Command: 0x%x\n", _i8255x_device.csr_bar->command); c_printf("Status: 0x%x\n", _i8255x_device.csr_bar->status); //Setup CU and RU base i8255x_write_cu_cmd(SCB_CMD_CUC_LD_CU_BASE, 0x00000000); i8255x_write_ru_cmd(SCB_CMD_RUC_LD_RU_BASE, 0x00000000); //Setup dump comand intel_action_dump_t dump; dump.header.command = CU_ACTION_DUMP | ACTION_HDR_CMD_EL | ACTION_HDR_CMD_I; dump.header.status = 0x0000; dump.header.link_addr = 0x00000000; dump.offset = (uint32_t) dump.buffer; //Start command processing i8255x_write_cu_cmd(SCB_CMD_CUC_START, (uint32_t)&dump); int timeout = 15000; while(timeout > 0){ if(_i8255x_device.cu_transition == true){ c_printf("\nCU Transitioned\n"); break; } timeout -= 500; __delay_ms(500); } int j=0; if(timeout > 0){ if((dump.header.status & ACTION_HDR_STATUS_C) != 0){ c_printf("\nCommand completed\n"); if((dump.header.status & ACTION_HDR_STATUS_OK) != 0){ for(j=0; j<6; j++){ _i8255x_device.mac_addr[j] = dump.buffer[39+j]; } } else{ c_printf("ERROR: Failed to dump data!\n"); return E_ERROR; } } else{ c_printf("ERROR: Dump command failed to complete!\n"); return E_ERROR; } } else{ c_printf("ERROR: Waited too long for command to complete!\n"); return E_TIMEOUT; } i8255x_setup_rfa(); c_printf("Command: 0x%x\n", _i8255x_device.csr_bar->command); c_printf("Status: 0x%x\n", _i8255x_device.csr_bar->status); __delay_ms(150); c_clearscreen(); c_printf("MAC Address = "); for(j=0; j<6; j++){ if(j==5){ c_printf("%x\n", _i8255x_device.mac_addr[j]); continue; } c_printf("%x:", _i8255x_device.mac_addr[j]); } c_printf("Receiving frames now... \n"); i8255x_write_ru_cmd(SCB_CMD_RUC_START, (uint32_t)_i8255x_device.rx_buffer_base); uint32_t buffer_size = sizeof(intel_tx_buffer_t)+(ETH_DATA_LEN+ETH_HLEN); _i8255x_device.tx_buffer_base = kalloc_aligned(buffer_size, Align_DWord); //Allocate Recieve frame area(RFA) //Initialize RFA and all Receive Frame Descriptors(RFDs) //Tell Device about RFA return E_SUCCESS; }
static void _clock_isr( int vector, int code ) { (void)(vector); (void)(code); pcb_t *pcb; // spin the pinwheel ++_pinwheel; if( _pinwheel == (CLOCK_FREQUENCY / 10) ) { _pinwheel = 0; ++_pindex; c_putchar_at( 79, 0, "|/-\\"[ _pindex & 3 ] ); } // increment the system time ++_system_time; /* ** wake up any sleeper whose time has come ** ** we give awakened processes preference over the ** current process (when it is scheduled again) */ while( !_queue_empty(_sleeping) && (uint32_t) _queue_kpeek(_sleeping) <= _system_time ) { // time to wake up! remove it from the queue pcb = (pcb_t *) _queue_remove( _sleeping ); if( pcb == NULL ) { #ifdef DEBUG _kpanic( "_clock_isr", "NULL from sleep queue remove" ); #else c_puts( "*** _clock_isr: NULL from sleep queue\n" ); break; #endif } // and schedule it for dispatch _schedule( pcb ); } // check the current process to see if it needs to be scheduled // sanity check! _current->quantum -= 1; if( _current->quantum < 1 ) { _schedule( _current ); _dispatch(); } #ifdef DUMP_QUEUES // Approximately every 10 seconds, dump the queues, and // print the contents of the SIO buffers. if( (_system_time % SECONDS_TO_TICKS(10)) == 0 ) { c_printf( "Queue contents @%08x\n", _system_time ); _queue_dump( "ready[0]", _ready[0] ); _queue_dump( "ready[1]", _ready[1] ); _queue_dump( "ready[2]", _ready[2] ); _queue_dump( "ready[3]", _ready[3] ); _queue_dump( "sleep", _sleeping ); _sio_dump(); } #endif // tell the PIC we're done __outb( PIC_MASTER_CMD_PORT, PIC_EOI ); }
void _vmem_init_bitmap( Uint32 addr ) { //make sure we start the bitmap where we think we should if ( addr != PAGE_TABLE_SIZE ) { __panic( "vmem: bitmap start is not where expected" ); } //maps the next 4 MBs _vmem_page_dir[1] = (Uint32) PAGE_TABLE_SIZE | PAGE_DIR_PRESENT | PAGE_DIR_WRITE | PAGE_DIR_SIZE; //initilize all bits to be set 1 in the bitmap (aka the address is free) int i; for( i = 0; i < (PAGE_TABLE_SIZE/32); i++ ) { _vmem_bitmap_start[i] = 0xFFFFFFFF; } //set the first 8MB are in use _vmem_set_4MB_address( 0x00 ); _vmem_set_4MB_address( PAGE_TABLE_SIZE ); #ifdef _VMEM_DEBUG c_printf("Bitmap ending init addr: %x \n", _vmem_bitmap_start ); c_printf(" %x : ", PAGE_TABLE_SIZE); c_printf(" %x : ", PAGE_SIZE); c_printf( "Ending of bitmap table is %x \n", addr); c_printf("0: %x \n", _vmem_page_dir[0] ); c_printf("1: %x \n", _vmem_page_dir[1] ); c_printf( "Bitmap entry 0 is %x \n", _vmem_bitmap_start[0]); c_printf( "Bitmap entry 0 is %x \n", _vmem_read_bit( _vmem_bitmap_start, 0, 0)); c_printf( "Bitmap entry 1 is %x \n", _vmem_read_bit( _vmem_bitmap_start, 0, 1)); c_printf( "Bitmap entry 2 is %x \n", _vmem_read_bit( _vmem_bitmap_start, 0, 2)); c_printf( "Bitmap entry n is %x \n", _vmem_read_bit( _vmem_bitmap_start, 63, 32)); c_printf( "Bitmap entry n is %x \n", _vmem_read_bit( _vmem_bitmap_start, 64, 0)); #endif }