Esempio n. 1
0
File: process.c Progetto: nwg/nanos
process_t *process_alloc(void *text, int argc, char **argv) {
    process_t *process = (process_t*)kalloc(sizeof(process_t));
    memset(process, 0, sizeof(process_t));

    process->text = kalloc_aligned(USER_TEXT_SIZE, 4096);
    memcpy(process->text, text, USER_TEXT_SIZE);
    process->stack_k = kalloc(K_STACK_SIZE);
    process->stack_u = kalloc_aligned(U_STACK_SIZE, 4096);
    process->pages = process_page_table_alloc((uintptr_t)process->stack_u, (uintptr_t)process->text);
    process->num_pages = 0;
    process->argc = argc;
    process->runstate = PROCESS_RUNNABLE;
    process->current = false;
    process->next_switch_is_kernel = false;
    process->num_waitable = 0;

    process->brk = USER_HEAP;

    process->files = kalloc(sizeof(file_t) * PROCESS_MAX_FILES);
    process->files[0] = g_termbuf->file;
    process->files[1] = g_term->file;
    process->files[2] = g_term->file;
    process->files[3] = g_devio->file;

    process->child_statuses = ll_alloc_a(kalloc);

    stackptr_t u = STACK(process->stack_u, U_STACK_SIZE);
    u = push_argv((void*)USER_STACK_VMA, process->stack_u, u, argc, argv);
    process->argv = (char**)u;

    process->pid = next_pid++;

    stackptr_t k = STACK(process->stack_k, K_STACK_SIZE);
    process->state = (system_state_t*)push_system_state(k, process->stack_u, process->argc, process->argv);
    process->kstate = NULL;

    return process;
}
status_t i8255x_setup_rfa(void){
	int i = 0;
	status_t status = E_SUCCESS;
	intel_rx_buffer_t* first_buf = NULL;
	intel_rx_buffer_t* prev_buf = NULL;

	do{
		intel_rx_buffer_t* rx_buf = kalloc_aligned(sizeof(intel_rx_buffer_t), Align_DWord);

		memset(rx_buf, 0x00, sizeof(intel_rx_buffer_t));

		rx_buf->size = ETH_DATA_LEN;

		if(prev_buf != NULL){
			prev_buf->header.link_addr = (uint32_t)rx_buf;
		}

		if(first_buf == NULL){
			first_buf = rx_buf;
		}

		prev_buf = rx_buf;
		i++;
	}
	while(i<I8255X_RX_BUFFER_COUNT && status == E_SUCCESS);

	prev_buf->header.link_addr = (uint32_t) first_buf;
	prev_buf->header.command = ACTION_HDR_CMD_EL | ACTION_HDR_CMD_S;

	_i8255x_device.rx_buffer_base = first_buf;
	_i8255x_device.rx_buffer_ptr = first_buf;
	_i8255x_device.rx_buffer_end = prev_buf;

	c_printf("i8255x_setup_rfa - Allocated %d RFDs totalling %d bytes\n", i, I8255X_RX_BUFFER_SIZE);

	return 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;
}