Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #if !defined(__cplusplus)
- #include <stdbool.h>
- #endif
- #include <stddef.h>
- #include <stdint.h>
- #define CONFIG_TX_DESCR_NUM 16
- #define CONFIG_RX_DESCR_NUM 16
- #define CONFIG_ETH_BUFSIZE 2048
- #define CONFIG_DW_GMAC_DEFAULT_DMA_PBL 8
- #define DMA_PBL (CONFIG_DW_GMAC_DEFAULT_DMA_PBL<<8)
- #define TX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
- #define RX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
- #define MAC_MAX_FRAME_SZ 1600
- #define DESC_RXCTRL_RXCHAIN (1 << 24)
- #define DESC_RXCTRL_SIZE1MASK (0x7FF << 0)
- #define DESC_RXSTS_OWNBYDMA (1 << 31)
- #define STOREFORWARD (1 << 21)
- #define FLUSHTXFIFO (1 << 20)
- #define FIXEDBURST (1 << 16)
- #define PRIORXTX_41 (3 << 14)
- #define RXSTART (1 << 1)
- #define RXENABLE (1 << 2)
- #define FULLDUPLEX (1 << 11)
- #define LINKUP (1 << 8)
- // The UART registers base address.
- #define UART0_BASE 0x01C28000
- // The offsets for reach register for the UART.
- #define UART0_RBR (UART0_BASE + 0x00)
- #define UART0_THR (UART0_BASE + 0x00)
- #define UART0_IER (UART0_BASE + 0x04)
- #define UART0_FCR (UART0_BASE + 0x08)
- #define UART0_LSR (UART0_BASE + 0x14)
- #define UART0_USR (UART0_BASE + 0x7C)
- // The GMAC registers base address.
- #define GMAC_BASE 0x01C50000
- // The offsets for reach register for the GMAC.
- #define GMAC_CONTROL (GMAC_BASE + 0x00)
- #define GMAC_FRAME_FILTER (GMAC_BASE + 0x04)
- #define GMAC_GMII_ADDR (GMAC_BASE + 0x10)
- #define GDMA_RCV_LIST (GMAC_BASE + 0x100C)
- #define GDMA_BUS_MODE (GMAC_BASE + 0x1000)
- #define GDMA_OPERATION (GMAC_BASE + 0x1018)
- // The DRAM base address.
- #define DRAM_BASE 0x40000000
- struct dmamacdescr {
- volatile uint32_t txrx_status;
- volatile uint32_t dmamac_cntl;
- volatile void *dmamac_addr;
- struct dmamacdescr *dmamac_next;
- };
- // Set up some pointers to locations in DRAM for GMAC DMA
- volatile char *txbuf = (void*)(DRAM_BASE + 0x0);
- volatile char *rxbuf = (void*)(DRAM_BASE + 0x8000);
- struct dmamacdescr *tx_mac_descrtable = (void*)(DRAM_BASE + 0x10000);
- struct dmamacdescr *rx_mac_descrtable = (void*)(DRAM_BASE + 0x10100);
- uint32_t rx_idx = 0;
- uint32_t tx_idx = 0;
- static inline void mmio_write(uint32_t reg, uint32_t data)
- {
- *(volatile uint32_t *)reg = data;
- }
- static inline uint32_t mmio_read(uint32_t reg)
- {
- return *(volatile uint32_t *)reg;
- }
- /* Loop <delay> times in a way that the compiler won't optimize away. */
- static inline void delay(int32_t count)
- {
- asm volatile("__delay_%=: subs %[count], %[count], #1; bne __delay_%=\n"
- : : [count]"r"(count) : "cc");
- }
- size_t strlen(const char* str)
- {
- size_t ret = 0;
- while ( str[ret] != 0 )
- ret++;
- return ret;
- }
- void uart_init()
- {
- // Disable UART interrupts.
- mmio_write(UART0_IER, 0x00000000);
- // Configure UART (enable FIFO)
- mmio_write(UART0_FCR, 0x00000001);
- }
- unsigned char uart_tx_ready()
- {
- return mmio_read(UART0_USR) & (2);
- }
- unsigned char uart_rx_ready()
- {
- return mmio_read(UART0_LSR) & (1);
- }
- void uart_putc(unsigned char byte)
- {
- // Wait for UART transmit FIFO to be not full.
- while ( ! uart_tx_ready() );
- mmio_write(UART0_THR, byte);
- }
- unsigned char uart_getc()
- {
- // Wait for UART to have recieved something.
- while ( ! uart_rx_ready() );
- return mmio_read(UART0_RBR);
- }
- void uart_write(const unsigned char* buffer, size_t size)
- {
- for ( size_t i = 0; i < size; i++ )
- uart_putc(buffer[i]);
- }
- void uart_puts(const char* str)
- {
- uart_write((const unsigned char*) str, strlen(str));
- }
- void uart_puts_uint32(uint32_t number)
- {
- unsigned char chars[] = "0123456789ABCDEF";
- uart_putc(chars[(number >> 28) & 0xF]);
- uart_putc(chars[(number >> 24) & 0xF]);
- uart_putc(chars[(number >> 20) & 0xF]);
- uart_putc(chars[(number >> 16) & 0xF]);
- uart_putc(chars[(number >> 12) & 0xF]);
- uart_putc(chars[(number >> 8) & 0xF]);
- uart_putc(chars[(number >> 4) & 0xF]);
- uart_putc(chars[(number >> 0) & 0xF]);
- }
- volatile void *memset(volatile void *s, int c, size_t n)
- {
- volatile unsigned char* p=s;
- while(n--)
- *p++ = (unsigned char)c;
- return s;
- }
- void gmac_init()
- {
- // Reset GMAC DMA
- uart_puts("Resetting GMAC DMA... ");
- mmio_write(GDMA_BUS_MODE, (mmio_read(GDMA_BUS_MODE) | 1));
- while (mmio_read(GDMA_BUS_MODE) & 1) {}
- uart_puts("[DONE]\r\n");
- // Zero-fill buffers
- memset(rxbuf, 0, 1024*32);
- memset(txbuf, 0, 1024*32);
- // Set up RX buffer descriptors
- uart_puts("Configuring RX buffers... ");
- uint32_t idx;
- struct dmamacdescr *desc_p;
- for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
- desc_p = rx_mac_descrtable + idx;
- desc_p->dmamac_addr = &rxbuf[idx * CONFIG_ETH_BUFSIZE];
- desc_p->dmamac_next = rx_mac_descrtable + idx + 1;
- desc_p->dmamac_cntl =
- (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | \
- DESC_RXCTRL_RXCHAIN;
- desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
- }
- desc_p->dmamac_next = rx_mac_descrtable;
- // Configure GMAC DMA with RX buffer descriptors
- mmio_write(GDMA_RCV_LIST, (uint32_t)rx_mac_descrtable);
- uart_puts("[DONE]\r\n");
- mmio_write(GDMA_BUS_MODE, FIXEDBURST | PRIORXTX_41 | DMA_PBL);
- mmio_write(GDMA_OPERATION, mmio_read(GDMA_OPERATION) | FLUSHTXFIFO | STOREFORWARD);
- mmio_write(GDMA_OPERATION, mmio_read(GDMA_OPERATION) | RXSTART);
- mmio_write(GMAC_CONTROL, mmio_read(GMAC_CONTROL) | RXENABLE);
- mmio_write(GMAC_CONTROL, mmio_read(GMAC_CONTROL) | FULLDUPLEX | LINKUP);
- //priv->tx_currdescnum = 0;
- //int n;
- //for(n=0;n<=0x1054; n=n+4)
- //{
- // uart_puts_uint32(n);
- // uart_putc(' ');
- // uart_puts_uint32(mmio_read(GMAC_BASE + n));
- // uart_putc('\r');
- // uart_putc('\n');
- //}
- }
- #if defined(__cplusplus)
- extern "C" /* Use C linkage for kernel_main. */
- #endif
- void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
- {
- (void) r0;
- (void) r1;
- (void) atags;
- uart_init();
- uart_puts("Hello, kernel World!\r\n");
- gmac_init();
- uart_puts_uint32(mmio_read(GMAC_CONTROL));
- uart_puts("\r\n");
- struct dmamacdescr *desc_p;
- while ( true )
- {
- desc_p = rx_mac_descrtable + rx_idx;
- while(desc_p->txrx_status & DESC_RXSTS_OWNBYDMA);
- desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
- rx_idx++;
- if(rx_idx > 15) rx_idx = 0;
- uart_puts("Frame received!\r\n");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement