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