Пример #1
0
void pci_scan_slot(pci_func_t f, int type, int bus, int slot) {
	uint32_t dev = pci_box_device(bus, slot, 0);
	if (pci_read_field(dev, PCI_VENDOR_ID, 2) == PCI_NONE) {
		return;
	}
	pci_scan_func(f, type, bus, slot, 0);
	if (!pci_read_field(dev, PCI_HEADER_TYPE, 1)) {
		return;
	}
	for (int func = 1; func < 8; func++) {
		uint32_t dev = pci_box_device(bus, slot, func);
		if (pci_read_field(dev, PCI_VENDOR_ID, 2) != PCI_NONE) {
			pci_scan_func(f, type, bus, slot, func);
		}
	}
}
Пример #2
0
void pci_scan(pci_func_t f, int type) {
	pci_scan_bus(f, type, 0);

	if (!pci_read_field(0, PCI_HEADER_TYPE, 1)) {
		return;
	}

	for (int func = 1; func < 8; ++func) {
		uint32_t dev = pci_box_device(0, 0, func);
		if (pci_read_field(dev, PCI_VENDOR_ID, 2) != PCI_NONE) {
			pci_scan_bus(f, type, func);
		} else {
			break;
		}
	}
}
Пример #3
0
static void find_usb_device(uint32_t device, uint16_t vendorid, uint16_t deviceid, void * extra) {
	if (pci_find_type(device) == 0xc03) {
		int prog_if = (int)pci_read_field(device, PCI_PROG_IF, 1);
		if (prog_if == 0) {
			*((uint32_t *)extra)= device;
		}
	}
}
Пример #4
0
void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func) {
	uint32_t dev = pci_box_device(bus, slot, func);
	if (type == -1 || type == pci_find_type(dev)) {
		pci_scan_hit(f, dev);
	}
	if (pci_find_type(dev) == PCI_TYPE_BRIDGE) {
		pci_scan_bus(f, type, pci_read_field(dev, PCI_SECONDARY_BUS, 1));
	}
}
Пример #5
0
static void bochas_scan_pci(u32 device,u16 v,u16 d,void *extra)
{
    printf("vendor : %x device : %x\n",v,d);
    if((v == 0x1234 && d == 0x1111) || 
       (v == 0x80EE && d == 0xBEEF)) {
        uintptr_t t = pci_read_field(device, PCI_BAR0,4);
        if(t > 0)
            *((u8 **)extra) = (u8 *)(t & 0xFFFFFFF0);
    }
}
Пример #6
0
int bochs_init(void) {

	outw(VBE_DISPI_IOPORT_INDEX, 0);
	
	int n = inw(VBE_DISPI_IOPORT_DATA);
	if(!(CHECK_BGA(n)))
		return E_ERR;


	__lfbptr = 0;

	void pci_func(uint32_t device, uint16_t vendor_id, uint16_t device_id, void* arg) {
		
		if(likely(!(
			(vendor_id == 0x1234) &&
			(device_id == 0x1111)
		))) return;
		
		__lfbptr = (uintptr_t) pci_read_field(device, PCI_BAR0, 4);
	}

	int i;
	for(i = 0; i < 65536 && !__lfbptr; i++)
		pci_scan(&pci_func, i, NULL);

	if(!__lfbptr)
		return E_ERR;


	#define ALIGN(x)										\
		(((x) + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1))
	
	if(__lfbptr) {
		uintptr_t frame = ALIGN(__lfbptr) - PAGE_SIZE;
		uintptr_t end = ALIGN(frame + BGA_VIDEORAM_SIZE);

		for(; frame < end; frame += PAGE_SIZE)
			map_page(frame, frame, 1);
	} else
		return E_ERR;
	


	fbdev->name = "Bochs VBE Extensions";
	fbdev->setvideomode = bga_setvideomode;
	return E_OK;
#else
int bga_init(void) {
	return E_ERR;
#endif
}
Пример #7
0
Файл: rtl.c Проект: Saruta/ToyOS
int init_rtl(void) {
	if (rtl_device_pci) {
		debug_print(NOTICE, "Located an RTL 8139: 0x%x\n", rtl_device_pci);

		uint16_t command_reg = pci_read_field(rtl_device_pci, PCI_COMMAND, 4);
		debug_print(NOTICE, "COMMAND register before: 0x%4x\n", command_reg);
		if (command_reg & (1 << 2)) {
			debug_print(NOTICE, "Bus mastering already enabled.\n");
		} else {
			command_reg |= (1 << 2); /* bit 2 */
			debug_print(NOTICE, "COMMAND register after:  0x%4x\n", command_reg);
			pci_write_field(rtl_device_pci, PCI_COMMAND, 4, command_reg);
			command_reg = pci_read_field(rtl_device_pci, PCI_COMMAND, 4);
			debug_print(NOTICE, "COMMAND register after:  0x%4x\n", command_reg);
		}

		rtl_irq = pci_read_field(rtl_device_pci, PCI_INTERRUPT_LINE, 1);
		debug_print(NOTICE, "Interrupt Line: %x\n", rtl_irq);
		irq_install_handler(rtl_irq, rtl_irq_handler);

		uint32_t rtl_bar0 = pci_read_field(rtl_device_pci, PCI_BAR0, 4);
		uint32_t rtl_bar1 = pci_read_field(rtl_device_pci, PCI_BAR1, 4);

		debug_print(NOTICE, "BAR0: 0x%8x\n", rtl_bar0);
		debug_print(NOTICE, "BAR1: 0x%8x\n", rtl_bar1);

		rtl_iobase = 0x00000000;

		if (rtl_bar0 & 0x00000001) {
			rtl_iobase = rtl_bar0 & 0xFFFFFFFC;
		} else {
			debug_print(NOTICE, "This doesn't seem right! RTL8139 should be using an I/O BAR; this looks like a memory bar.");
		}

		debug_print(NOTICE, "RTL iobase: 0x%x\n", rtl_iobase);

		rx_wait = list_create();

		debug_print(NOTICE, "Determining mac address...\n");
		for (int i = 0; i < 6; ++i) {
			mac[i] = inports(rtl_iobase + RTL_PORT_MAC + i);
		}

		debug_print(NOTICE, "%2x:%2x:%2x:%2x:%2x:%2x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

		debug_print(NOTICE, "Enabling RTL8139.\n");
		outportb(rtl_iobase + RTL_PORT_CONFIG, 0x0);

		debug_print(NOTICE, "Resetting RTL8139.\n");
		outportb(rtl_iobase + RTL_PORT_CMD, 0x10);
		while ((inportb(rtl_iobase + 0x37) & 0x10) != 0) { }

		debug_print(NOTICE, "Done resetting RTL8139.\n");

		for (int i = 0; i < 5; ++i) {
			rtl_tx_buffer[i] = (void*)kvmalloc_p(0x1000, &rtl_tx_phys[i]);
			for (int j = 0; j < 60; ++j) {
				rtl_tx_buffer[i][j] = 0xF0;
			}
		}

		rtl_rx_buffer = (uint8_t *)kvmalloc_p(0x3000, &rtl_rx_phys);
		memset(rtl_rx_buffer, 0x00, 0x3000);

		debug_print(NOTICE, "Buffers:\n");
		debug_print(NOTICE, "   rx 0x%x [phys 0x%x and 0x%x and 0x%x]\n", rtl_rx_buffer, rtl_rx_phys, map_to_physical((uintptr_t)rtl_rx_buffer + 0x1000), map_to_physical((uintptr_t)rtl_rx_buffer + 0x2000));

		for (int i = 0; i < 5; ++i) {
			debug_print(NOTICE, "   tx 0x%x [phys 0x%x]\n", rtl_tx_buffer[i], rtl_tx_phys[i]);
		}

		debug_print(NOTICE, "Initializing receive buffer.\n");
		outportl(rtl_iobase + RTL_PORT_RBSTART, rtl_rx_phys);

		debug_print(NOTICE, "Enabling IRQs.\n");
		outports(rtl_iobase + RTL_PORT_IMR,
			0x8000 | /* PCI error */
			0x4000 | /* PCS timeout */
			0x40   | /* Rx FIFO over */
			0x20   | /* Rx underrun */
			0x10   | /* Rx overflow */
			0x08   | /* Tx error */
			0x04   | /* Tx okay */
			0x02   | /* Rx error */
			0x01     /* Rx okay */
		); /* TOK, ROK */

		debug_print(NOTICE, "Configuring transmit\n");
		outportl(rtl_iobase + RTL_PORT_TCR,
			0
		);

		debug_print(NOTICE, "Configuring receive buffer.\n");
		outportl(rtl_iobase + RTL_PORT_RCR,
			(0)       | /* 8K receive */
			0x08      | /* broadcast */
			0x01        /* all physical */
		);

		debug_print(NOTICE, "Enabling receive and transmit.\n");
		outportb(rtl_iobase + RTL_PORT_CMD, 0x08 | 0x04);

		debug_print(NOTICE, "Resetting rx stats\n");
		outportl(rtl_iobase + RTL_PORT_RXMISS, 0);

		net_queue = list_create();

#if 1
		{
			debug_print(NOTICE, "Sending DHCP discover\n");
			size_t packet_size = write_dhcp_packet(rtl_tx_buffer[next_tx]);

			outportl(rtl_iobase + RTL_PORT_TXBUF + 4 * next_tx, rtl_tx_phys[next_tx]);
			outportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * next_tx, packet_size);

			next_tx++;
			if (next_tx == 4) {
				next_tx = 0;
			}
		}

		{
			struct ethernet_packet * eth = (struct ethernet_packet *)rtl_dequeue();
			uint16_t eth_type = ntohs(eth->type);

			debug_print(NOTICE, "Ethernet II, Src: (%2x:%2x:%2x:%2x:%2x:%2x), Dst: (%2x:%2x:%2x:%2x:%2x:%2x) [type=%4x)\n",
					eth->source[0], eth->source[1], eth->source[2],
					eth->source[3], eth->source[4], eth->source[5],
					eth->destination[0], eth->destination[1], eth->destination[2],
					eth->destination[3], eth->destination[4], eth->destination[5],
					eth_type);


			struct ipv4_packet * ipv4 = (struct ipv4_packet *)eth->payload;
			uint32_t src_addr = ntohl(ipv4->source);
			uint32_t dst_addr = ntohl(ipv4->destination);
			uint16_t length   = ntohs(ipv4->length);

			char src_ip[16];
			char dst_ip[16];

			ip_ntoa(src_addr, src_ip);
			ip_ntoa(dst_addr, dst_ip);

			debug_print(NOTICE, "IP packet [%s → %s] length=%d bytes\n",
					src_ip, dst_ip, length);

			struct udp_packet * udp = (struct udp_packet *)ipv4->payload;;
			uint16_t src_port = ntohs(udp->source_port);
			uint16_t dst_port = ntohs(udp->destination_port);
			uint16_t udp_len  = ntohs(udp->length);

			debug_print(NOTICE, "UDP [%d → %d] length=%d bytes\n",
					src_port, dst_port, udp_len);

			struct dhcp_packet * dhcp = (struct dhcp_packet *)udp->payload;
			uint32_t yiaddr = ntohl(dhcp->yiaddr);

			char yiaddr_ip[16];
			ip_ntoa(yiaddr, yiaddr_ip);
			debug_print(NOTICE,  "DHCP Offer: %s\n", yiaddr_ip);

			free(eth);
		}

#endif

		debug_print(NOTICE, "Card is configured, going to start worker thread now.\n");

		debug_print(NOTICE, "Initializing netif functions\n");

		init_netif_funcs(rtl_get_mac, rtl_get_packet, rtl_send_packet);
		create_kernel_tasklet(net_handler, "[eth]", NULL);

		debug_print(NOTICE, "Back from starting the worker thread.\n");
	} else {
		return -1;
	}
	return 0;
}
Пример #8
0
int init(void) {
    
    void find_pci(uint32_t device, uint16_t venid, uint16_t devid, void* data) {
        if((venid == 0x1022) && (devid == 0x2000))
            *((uint32_t*) data) = device;
    }

    int pci = 0;
    pci_scan(&find_pci, -1, &pci);
    if(!pci) {
        kprintf(ERROR "pcnet: pci device not found!\n");
        return -1;
    }

    struct pcnet* dev = (struct pcnet*) kmalloc(sizeof(struct pcnet), GFP_KERNEL);
    struct ethif* eth = (struct ethif*) kmalloc(sizeof(struct ethif), GFP_KERNEL);

    memset(dev, 0, sizeof(struct pcnet));
    memset(eth, 0, sizeof(struct ethif));


    eth->internals = (void*) dev;
    dev->pci = pci;



    spinlock_init(&dev->lock);

    dev->buf = (uintptr_t) kvalloc(0x10000, GFP_KERNEL);
    dev->bufp = (uintptr_t) V2P((void*) dev->buf);

    uint16_t cmd = pci_read_field(dev->pci, PCI_COMMAND, 4);
    if(!(cmd & (1 << 2))) 
        pci_write_field(dev->pci, PCI_COMMAND, 4, cmd | (1 << 2));


    dev->irq = pci_read_field(dev->pci, PCI_INTERRUPT_LINE, 1);
    dev->io = pci_read_field(dev->pci, PCI_BAR0, 4) & 0xFFFFFFF0;
    dev->mem = pci_read_field(dev->pci, PCI_BAR1, 4) & 0xFFFFFFF0;

    
    kprintf(LOG "pcnet: irq: %d, io: %p, mem: %p\n", dev->irq, dev->io, dev->mem);

    int i;
    for(i = 0; i < 6; i++)
        eth->address[i] = inb(dev->io + i);

    

    pcnet_irqno = dev->irq;   /* FIXME: fix current_irq */

    irq_enable(dev->irq, pcnet_irq);
    irq_set_data(dev->irq, dev);


    eth->low_level_init = pcnet_init;
    eth->low_level_startoutput = pcnet_startoutput;
    eth->low_level_output = pcnet_output;
    eth->low_level_endoutput = pcnet_endoutput;
    eth->low_level_startinput = pcnet_startinput;
    eth->low_level_input = pcnet_input;
    eth->low_level_endinput = pcnet_endinput;
    eth->low_level_input_nomem = pcnet_input_nomem;


    IP4_ADDR(&eth->ip, 10, 0, 2, 15);
    IP4_ADDR(&eth->nm, 255, 255, 255, 0);
    IP4_ADDR(&eth->gw, 10, 0, 2, 2);

    struct netif* netif = (struct netif*) kmalloc(sizeof(struct netif), GFP_KERNEL);
    dev->netif = netif;

    if(!netif_add(netif, &eth->ip, &eth->nm, &eth->gw, eth, ethif_init, ethernet_input)) {
        kprintf(ERROR "pcnet: netif_add() failed\n");

        kfree(dev);
        kfree(eth);
        kfree(netif);
        return -1;
    }

    netif_set_default(netif);
    netif_set_up(netif);

    return 0;
}
Пример #9
0
int init_rtl(void) {
	if (rtl_device_pci) {
		debug_print(NOTICE, "Located an RTL 8139: 0x%x\n", rtl_device_pci);

		uint16_t command_reg = pci_read_field(rtl_device_pci, PCI_COMMAND, 4);
		debug_print(NOTICE, "COMMAND register before: 0x%4x\n", command_reg);
		if (command_reg & (1 << 2)) {
			debug_print(NOTICE, "Bus mastering already enabled.\n");
		} else {
			command_reg |= (1 << 2); /* bit 2 */
			debug_print(NOTICE, "COMMAND register after:  0x%4x\n", command_reg);
			pci_write_field(rtl_device_pci, PCI_COMMAND, 4, command_reg);
			command_reg = pci_read_field(rtl_device_pci, PCI_COMMAND, 4);
			debug_print(NOTICE, "COMMAND register after:  0x%4x\n", command_reg);
		}

		rtl_irq = pci_get_interrupt(rtl_device_pci);
		debug_print(NOTICE, "Interrupt Line: %x\n", rtl_irq);
		irq_install_handler(rtl_irq, rtl_irq_handler, "rtl8139");

		uint32_t rtl_bar0 = pci_read_field(rtl_device_pci, PCI_BAR0, 4);
		uint32_t rtl_bar1 = pci_read_field(rtl_device_pci, PCI_BAR1, 4);

		debug_print(NOTICE, "BAR0: 0x%8x\n", rtl_bar0);
		debug_print(NOTICE, "BAR1: 0x%8x\n", rtl_bar1);

		rtl_iobase = 0x00000000;

		if (rtl_bar0 & 0x00000001) {
			rtl_iobase = rtl_bar0 & 0xFFFFFFFC;
		} else {
			debug_print(NOTICE, "This doesn't seem right! RTL8139 should be using an I/O BAR; this looks like a memory bar.");
		}

		debug_print(NOTICE, "RTL iobase: 0x%x\n", rtl_iobase);

		rx_wait = list_create();

		debug_print(NOTICE, "Determining mac address...\n");
		for (int i = 0; i < 6; ++i) {
			mac[i] = inports(rtl_iobase + RTL_PORT_MAC + i);
		}

		debug_print(NOTICE, "%2x:%2x:%2x:%2x:%2x:%2x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

		debug_print(NOTICE, "Enabling RTL8139.\n");
		outportb(rtl_iobase + RTL_PORT_CONFIG, 0x0);

		debug_print(NOTICE, "Resetting RTL8139.\n");
		outportb(rtl_iobase + RTL_PORT_CMD, 0x10);
		while ((inportb(rtl_iobase + 0x37) & 0x10) != 0) { }

		debug_print(NOTICE, "Done resetting RTL8139.\n");

		for (int i = 0; i < 5; ++i) {
			rtl_tx_buffer[i] = (void*)kvmalloc_p(0x1000, &rtl_tx_phys[i]);
			for (int j = 0; j < 60; ++j) {
				rtl_tx_buffer[i][j] = 0xF0;
			}
		}

		rtl_rx_buffer = (uint8_t *)kvmalloc_p(0x3000, &rtl_rx_phys);
		memset(rtl_rx_buffer, 0x00, 0x3000);

		debug_print(NOTICE, "Buffers:\n");
		debug_print(NOTICE, "   rx 0x%x [phys 0x%x and 0x%x and 0x%x]\n", rtl_rx_buffer, rtl_rx_phys, map_to_physical((uintptr_t)rtl_rx_buffer + 0x1000), map_to_physical((uintptr_t)rtl_rx_buffer + 0x2000));

		for (int i = 0; i < 5; ++i) {
			debug_print(NOTICE, "   tx 0x%x [phys 0x%x]\n", rtl_tx_buffer[i], rtl_tx_phys[i]);
		}

		debug_print(NOTICE, "Initializing receive buffer.\n");
		outportl(rtl_iobase + RTL_PORT_RBSTART, rtl_rx_phys);

		debug_print(NOTICE, "Enabling IRQs.\n");
		outports(rtl_iobase + RTL_PORT_IMR,
			0x8000 | /* PCI error */
			0x4000 | /* PCS timeout */
			0x40   | /* Rx FIFO over */
			0x20   | /* Rx underrun */
			0x10   | /* Rx overflow */
			0x08   | /* Tx error */
			0x04   | /* Tx okay */
			0x02   | /* Rx error */
			0x01     /* Rx okay */
		); /* TOK, ROK */

		debug_print(NOTICE, "Configuring transmit\n");
		outportl(rtl_iobase + RTL_PORT_TCR,
			0
		);

		debug_print(NOTICE, "Configuring receive buffer.\n");
		outportl(rtl_iobase + RTL_PORT_RCR,
			(0)       | /* 8K receive */
			0x08      | /* broadcast */
			0x01        /* all physical */
		);

		debug_print(NOTICE, "Enabling receive and transmit.\n");
		outportb(rtl_iobase + RTL_PORT_CMD, 0x08 | 0x04);

		debug_print(NOTICE, "Resetting rx stats\n");
		outportl(rtl_iobase + RTL_PORT_RXMISS, 0);

		net_queue = list_create();

		debug_print(NOTICE, "Initializing netif functions\n");
		init_netif_funcs(rtl_get_mac, rtl_get_packet, rtl_send_packet, "RTL8139");

		debug_print(NOTICE, "Back from starting the worker thread.\n");
	} else {
		return -1;
	}
	return 0;
}
Пример #10
0
void pci_scan_hit(pci_func_t f, uint32_t dev) {
	int dev_vend = (int)pci_read_field(dev, PCI_VENDOR_ID, 2);
	int dev_dvid = (int)pci_read_field(dev, PCI_DEVICE_ID, 2);

	f(dev, dev_vend, dev_dvid);
}
Пример #11
0
uint16_t pci_find_type(uint32_t dev) {
	return (pci_read_field(dev, PCI_CLASS, 1) << 8) | pci_read_field(dev, PCI_SUBCLASS, 1);
}