os-workshop

same materials and sample source for RV32 OS projects
git clone http://frotz.net/git/os-workshop.git
Log | Files | Refs

ex05-ethernet.c (2272B)


      1 // Copyright 2022, Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0
      3 
      4 #include <hw/riscv.h>
      5 #include <hw/context.h>
      6 #include <hw/debug.h>
      7 #include <hw/intrinsics.h>
      8 
      9 #include <hw/platform.h>
     10 #include <hw/litex.h>
     11 
     12 #include <net/ipv6.h>
     13 
     14 #include <string.h>
     15 
     16 #define eth_rd(a) io_rd32(ETHMAC_BASE + LX_ETHMAC_ ## a)
     17 #define eth_wr(a,v) io_wr32(ETHMAC_BASE + LX_ETHMAC_ ## a, v)
     18 
     19 void interrupt_handler(void) { xputc('@'); }
     20 
     21 void pkt_rx_udp(void *data, unsigned len, unsigned port, int mcast) {
     22 	xprintf("UDP %u: %p(%u) %s\n", port, data, len, mcast ? "M" : "");
     23 	net_tx_udp_reply(data, "multipass", 10, port);
     24 }
     25 
     26 uint8_t rxbuf[1536] = { 0, };
     27 
     28 void eth_rx(uint8_t *rxb, unsigned rxlen) {
     29 	if (rxlen > 1534) return;
     30 	memcpy(rxbuf + 2, rxb, rxlen);
     31 	net_rx_eth(rxbuf, rxlen + 2);
     32 }
     33 
     34 static unsigned txslot;
     35 
     36 void eth_tx(void *txb, unsigned txlen) {
     37 	if (txlen > 1534) return;
     38 
     39 	while (eth_rd(RD_READY) != 1) ;
     40 
     41 	memcpy((void*)(ETHMAC_SRAM_BASE + ETHMAC_SLOT_SIZE * (ETHMAC_RX_SLOTS + txslot)), txb, txlen);
     42 
     43 	eth_wr(RD_SLOT, txslot);
     44 	eth_wr(RD_LEN, txlen);
     45 	eth_wr(RD_START, 1);
     46 
     47 	txslot ^= 1;
     48 }
     49 
     50 void eth_init(void) {
     51 	eth_wr(WR_EV_ENABLE, 0);
     52 	eth_wr(RD_EV_ENABLE, 0);
     53 
     54 	eth_wr(WR_EV_PENDING, 1);
     55 	eth_wr(RD_EV_PENDING, 1);
     56 
     57 	txslot = 0;
     58 	eth_wr(RD_SLOT, txslot);
     59 
     60 	eth_wr(WR_EV_ENABLE, 1);
     61 	eth_wr(RD_EV_ENABLE, 1);
     62 }
     63 
     64 void start(void) {
     65 	xprintf("Example 05 - Ethernet\n\n");
     66 
     67 	// set trap vector to trap_entry() in trap-entry-single.S
     68 	// it will call exception_handler() or interrupt_handler()
     69 	csr_write(CSR_STVEC, (uintptr_t) trap_entry);
     70 
     71 	// enable timer0 irq
     72 	//csr_set(CSR_S_INTC_ENABLE, TIMER0_IRQb);
     73 
     74 	// enable external interrupts
     75 	//csr_set(CSR_SIE, INTb_SVC_EXTERN);
     76 
     77 	// enable interrupts 
     78 	//irq_enable();
     79 
     80 	uint8_t mac[6] = { 0x42,0x42,0x10,0x20,0x30,0x40 };
     81 	net_init(mac);
     82 	eth_init();
     83 
     84 	while (1) {
     85 		if (eth_rd(WR_EV_PENDING) & 1) {
     86 			uint32_t slot = eth_rd(WR_SLOT);
     87 			uint8_t *rxb = (void*) (ETHMAC_SRAM_BASE + ETHMAC_SLOT_SIZE * slot);
     88 			eth_rx(rxb, eth_rd(WR_LEN));
     89 			eth_wr(WR_EV_PENDING, 1);
     90 		}
     91 	}
     92 }
     93 
     94 // if an exception occurs, dump register state and halt
     95 void exception_handler(eframe_t *ef) {
     96 	xprintf("\n** SUPERVISOR EXCEPTION **\n");
     97 	xprint_s_exception(ef);
     98 	xprintf("\nHALT\n");
     99 	for (;;) ;
    100 }
    101