/** * Source for init steps taken from the following forum. * http://forum.osdev.org/viewtopic.php?t=10247 */ void _ps2_mouse_init( void ){ // Setup initial values _init = 0; _x_move = 0; _y_move = 0; _left_button = 0; _right_button = 0; _middle_button = 0; // vars Uint resp = 0; // Hook in our interrupt vector, we do this first because there are some // weird interrupt timing issues. __install_isr( PS2_M_VEC, _ps2_mouse_isr ); // First, disable the mouse to avoid having it mess up initialization _ps2_mouse_clear(); __outb( PS2_STAT, 0xAD ); _ps2_mouse_clear(); __outb( PS2_STAT, 0xA7 ); // Clear the mouse's buffer __inb( 0x60 ); // enable the PS/2 auxillary device _ps2_mouse_clear(); __outb( PS2_STAT, 0xA8 ); // Enable the interrupts _ps2_mouse_clear(); __outb( PS2_STAT, 0x20 ); _ps2_mouse_ready(); resp = ( __inb(0x60) | 2 ); _ps2_mouse_clear(); __outb( PS2_STAT, 0x60 ); _ps2_mouse_clear(); __outb( 0x60, resp ); // Tell the mouse to use default settings _ps2_write_mouse( 0xF6 ); _ps2_read_mouse(); //Acknowledge /* // Override the Sample Rate to 200/s _ps2_write_mouse( PS2_M_SAMP ); _ps2_read_mouse(); c_puts( "ACK! Awaiting VALUE!\n" ); _ps2_mouse_clear(); __outb( PS2_STAT, 0xD4 ); while( (__inb(PS2_STAT) & 2) != 0 ) ; __outb( PS2_PORT, 200 ); //_ps2_read_mouse(); // next, override the resolution to 8count/mm _ps2_write_mouse( PS2_M_SRES ); _ps2_read_mouse(); c_puts( "ACK! Awaiting VALUE!\n" ); _ps2_mouse_clear(); __outb( PS2_STAT, 0xD4 ); while( (__inb(PS2_STAT) & 2) != 0 ) ; __outb( PS2_PORT, 0x03 ); */ // Enable the mouse to begin data packet transfers _ps2_write_mouse( 0xF4 ); _ps2_read_mouse(); //Acknowledge // Reset everything (settings) _ps2_mouse_clear(); __outb( PS2_STAT, PS2_M_RST ); // Done! c_puts( "Mouse driver successfully attached!\n" ); c_clearscreen(); _init = 1; // Draw mouse at center _x_pos = 0; _y_pos = 0; }
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_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; }
void _init( void ) { pcb_t *pcb; /* ** BOILERPLATE CODE - taken from basic framework ** ** Initialize interrupt stuff. */ __init_interrupts(); // IDT and PIC initialization // Ignore the 0x2A interrupt which happens when removing or inserting a // flash drive. __install_isr( 0x2A, _ignore_isr ); /* ** Console I/O system. */ c_io_init(); c_clearscreen(); #ifdef ISR_DEBUGGING_CODE c_setscroll( 0, 7, 99, 99 ); c_puts_at( 0, 6, "================================================================================" ); #endif /* ** 20123-SPECIFIC CODE STARTS HERE */ /* ** Initialize various OS modules ** ** Note: the clock, SIO, and syscall modules also install ** their ISRs. */ c_puts( "Module init: " ); _q_init(); // must be first _pcb_init(); _stack_init(); _sio_init(); _sys_init(); _sched_init(); _clock_init(); _pci_init(); _disk_init(); _net_init(); c_puts( "\n" ); c_puts("Launching the shell. Please be patient\n"); __delay(1000); c_clearscreen(); /* ** Create the initial system ESP ** ** This will be the address of the next-to-last ** longword in the system stack. */ _system_esp = ((uint32_t *) ( (&_system_stack) + 1)) - 2; /* ** Create the initial process ** ** Code mostly stolen from _sys_fork(); if that routine ** changes, SO MUST THIS!!! */ // allocate a PCB and stack pcb = _create_process( NULL ); if( pcb == NULL ) { _kpanic( "_init", "init() creation failed", FAILURE ); } // initialize the stack with the standard context pcb->context = _create_stack( pcb->stack ); if( pcb->context == NULL ) { _kpanic( "_init", "init() stack setup failed", FAILURE ); } // define the entry point for init() pcb->context->eip = (uint32_t) init; // set up various PCB fields pcb->pid = pcb->ppid = PID_INIT; // next PID is initially 1 pcb->prio = PRIO_HIGH; pcb->children = 1000; // remember this PCB for use in reparenting orphan processes _init_pcb = pcb; // make it the first process _schedule( pcb ); _dispatch(); /* ** Turn on the SIO receiver (the transmitter will be turned ** on/off as characters are being sent) */ _sio_enable( SIO_RX ); /* ** END OF 20123-SPECIFIC CODE ** ** Finally, report that we're all done. */ c_puts( "System initialization complete.\n" ); }
void _init( void ) { Pcb *pcb; // // BOILERPLATE CODE - taken from basic framework // // Initialize interrupt stuff. // __init_interrupts(); // IDT and PIC initialization // // I/O system. // c_io_init(); c_clearscreen(); c_setscroll( 0, 7, 99, 99 ); c_puts_at( 0, 6, "================================================================================" ); c_puts( "Init: " ); // // 20073-SPECIFIC CODE STARTS HERE // // // Initialize various OS modules // _init_queues(); // must be first _init_memory(); _init_processes(); _init_stacks(); _init_sio(); _init_clock(); _init_syscalls(); c_puts( "\n" ); // // Create the initial process // // Code mostly stolen from _sys_fork() and _sys_exec(); // if either of those routines change, SO MUST THIS!!! // // // First, get a PCB and a stack // pcb = _get_pcb(); if( pcb == 0 ) { _kpanic( "_init - can't allocate first pcb" ); } pcb->stack = _get_stack(); if( pcb->stack == 0 ) { _kpanic( "_init - can't allocate first stack" ); } // // Next, set up various PCB fields // pcb->pid = g_next_pid++; pcb->prio = PRI_NORMAL; // // Set up the initial process context. // // See _sys_exec() for an explanation of how this works. // pcb->context = _setup_stack( pcb->stack, (unsigned int) first_main ); // Initialize memory segment. Equals that of the kernel's in the GDT. pcb->seg.mem.offset = 0x0; pcb->seg.mem.length = 0xFFFFFFFF; // Initialize LDT entries for this PCB // This is a "kernel" process, so we will just copy over the // descriptors from the GDT and stick them into this process' LDT. __copy_gdt_entry( &(pcb->seg.ldt.cseg), (GDT_INDEX(GDT_CODE)) ); __copy_gdt_entry( &(pcb->seg.ldt.dseg), (GDT_INDEX(GDT_DATA)) ); // Allocate a slot in the GDT for the LDT descriptor, // and initialize this PCB's LDT register variable. pcb->seg.ldtr = SEL_SETINDEX(_gdt_alloc()) | SEL_GDT | SEL_RPL(0); // Initialize the LDT descriptor located in the GDT __gdt_set_entry( SEL_GETINDEX(pcb->seg.ldtr), (u32_t)&(pcb->seg.ldt), sizeof(ldt_t), ACC_PRES | ACC_DPL(0) | ACC_SYS | SYS_LDT ); // // Give it to the scheduler. // _schedule( pcb ); // // Do it all again for the idle process. // pcb = _get_pcb(); if( pcb == 0 ) { _kpanic( "_init - can't allocate idle pcb" ); } pcb->stack = _get_stack(); if( pcb->stack == 0 ) { _kpanic( "_init - can't allocate idle stack" ); } pcb->pid = g_next_pid++; pcb->prio = PRI_MINIMUM; pcb->context = _setup_stack( pcb->stack, (unsigned int) idle_main ); pcb->seg.mem.offset = 0x0; pcb->seg.mem.length = 0xFFFFFFFF; __copy_gdt_entry( &(pcb->seg.ldt.cseg), (GDT_INDEX(GDT_CODE)) ); __copy_gdt_entry( &(pcb->seg.ldt.dseg), (GDT_INDEX(GDT_DATA)) ); pcb->seg.ldtr = SEL_SETINDEX(_gdt_alloc()) | SEL_GDT | SEL_RPL(0); __gdt_set_entry( SEL_GETINDEX(pcb->seg.ldtr), (u32_t)&(pcb->seg.ldt), sizeof(ldt_t), ACC_PRES | ACC_DPL(0) | ACC_SYS | SYS_LDT ); _schedule( pcb ); // // Dispatch the initial current process // _dispatch(); // // END OF 20073-SPECIFIC CODE // // Finally, report that we're all done. // c_puts( "System initialization complete.\n" ); }