Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/misoc
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 891496976058
Choose a base ref
...
head repository: m-labs/misoc
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1ab89d6a623a
Choose a head ref
  • 10 commits
  • 4 files changed
  • 2 contributors

Commits on Apr 14, 2013

  1. dvisampler/chansync: use Record.raw_bits()

    Sebastien Bourdeauducq committed Apr 14, 2013
    Copy the full SHA
    0d21711 View commit details

Commits on Apr 16, 2013

  1. microudp.c: avoid redundant accesses into multi-level structures

    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013
    Copy the full SHA
    65b807b View commit details
  2. tftp.c: use symbolic constants for protocol opcodes

    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    36613c7 View commit details
  3. tftp.c (rx_callback): simplify expressions containing unnecessary casts

    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013
    Copy the full SHA
    e0e447f View commit details
  4. tftp.c: make "packet_data" unsigned and optimize strcpy+strlen

    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013
    Copy the full SHA
    effa71a View commit details
  5. tftp.h, tftp.c (tftp_get): make "buffer" void and use unsigned char i…

    …nternally
    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013
    Copy the full SHA
    cdb5519 View commit details
  6. tftp.c: use uintNN_t instead of "unsigned short", etc.

    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013
    Copy the full SHA
    aafb3ef View commit details
  7. tftp.c (format_request): pass opcode as argument

    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013
    Copy the full SHA
    944dd59 View commit details
  8. tftp.c: use symbolic constant for block size

    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013
    Copy the full SHA
    22f39b9 View commit details
  9. tftp.h, tftp.c: add tftp_put

    wpwrak authored and Sebastien Bourdeauducq committed Apr 16, 2013
    Copy the full SHA
    1ab89d6 View commit details
Showing with 156 additions and 52 deletions.
  1. +2 −2 milkymist/dvisampler/chansync.py
  2. +32 −28 software/bios/microudp.c
  3. +118 −21 software/bios/tftp.c
  4. +4 −1 software/bios/tftp.h
4 changes: 2 additions & 2 deletions milkymist/dvisampler/chansync.py
Original file line number Diff line number Diff line change
@@ -31,8 +31,8 @@ def __init__(self, nchan=3, depth=8):
self.add_submodule(fifo, "pix")
self.comb += [
fifo.we.eq(self.valid_i),
fifo.din.eq(Cat(*data_in.flatten())),
Cat(*data_out.flatten()).eq(fifo.dout)
fifo.din.eq(data_in.raw_bits()),
data_out.raw_bits().eq(fifo.dout)
]
is_control = Signal()
is_control_r = Signal()
60 changes: 32 additions & 28 deletions software/bios/microudp.c
Original file line number Diff line number Diff line change
@@ -128,39 +128,42 @@ static unsigned int cached_ip;

static void process_arp(void)
{
const struct arp_frame *rx_arp = &rxbuffer->frame.contents.arp;
struct arp_frame *tx_arp = &txbuffer->frame.contents.arp;

if(rxlen < 68) return;
if(rxbuffer->frame.contents.arp.hwtype != ARP_HWTYPE_ETHERNET) return;
if(rxbuffer->frame.contents.arp.proto != ARP_PROTO_IP) return;
if(rxbuffer->frame.contents.arp.hwsize != 6) return;
if(rxbuffer->frame.contents.arp.protosize != 4) return;
if(rxbuffer->frame.contents.arp.opcode == ARP_OPCODE_REPLY) {
if(rxbuffer->frame.contents.arp.sender_ip == cached_ip) {
if(rx_arp->hwtype != ARP_HWTYPE_ETHERNET) return;
if(rx_arp->proto != ARP_PROTO_IP) return;
if(rx_arp->hwsize != 6) return;
if(rx_arp->protosize != 4) return;
if(rx_arp->opcode == ARP_OPCODE_REPLY) {
if(rx_arp->sender_ip == cached_ip) {
int i;
for(i=0;i<6;i++)
cached_mac[i] = rxbuffer->frame.contents.arp.sender_mac[i];
cached_mac[i] = rx_arp->sender_mac[i];
}
return;
}
if(rxbuffer->frame.contents.arp.opcode == ARP_OPCODE_REQUEST) {
if(rxbuffer->frame.contents.arp.target_ip == my_ip) {
if(rx_arp->opcode == ARP_OPCODE_REQUEST) {
if(rx_arp->target_ip == my_ip) {
int i;

fill_eth_header(&txbuffer->frame.eth_header,
rxbuffer->frame.contents.arp.sender_mac,
rx_arp->sender_mac,
my_mac,
ETHERTYPE_ARP);
txlen = 68;
txbuffer->frame.contents.arp.hwtype = ARP_HWTYPE_ETHERNET;
txbuffer->frame.contents.arp.proto = ARP_PROTO_IP;
txbuffer->frame.contents.arp.hwsize = 6;
txbuffer->frame.contents.arp.protosize = 4;
txbuffer->frame.contents.arp.opcode = ARP_OPCODE_REPLY;
txbuffer->frame.contents.arp.sender_ip = my_ip;
tx_arp->hwtype = ARP_HWTYPE_ETHERNET;
tx_arp->proto = ARP_PROTO_IP;
tx_arp->hwsize = 6;
tx_arp->protosize = 4;
tx_arp->opcode = ARP_OPCODE_REPLY;
tx_arp->sender_ip = my_ip;
for(i=0;i<6;i++)
txbuffer->frame.contents.arp.sender_mac[i] = my_mac[i];
txbuffer->frame.contents.arp.target_ip = rxbuffer->frame.contents.arp.sender_ip;
tx_arp->sender_mac[i] = my_mac[i];
tx_arp->target_ip = rx_arp->sender_ip;
for(i=0;i<6;i++)
txbuffer->frame.contents.arp.target_mac[i] = rxbuffer->frame.contents.arp.sender_mac[i];
tx_arp->target_mac[i] = rx_arp->sender_mac[i];
send_packet();
}
return;
@@ -171,6 +174,7 @@ static const unsigned char broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

int microudp_arp_resolve(unsigned int ip)
{
struct arp_frame *arp = &txbuffer->frame.contents.arp;
int i;
int tries;
int timeout;
@@ -190,17 +194,17 @@ int microudp_arp_resolve(unsigned int ip)
my_mac,
ETHERTYPE_ARP);
txlen = 68;
txbuffer->frame.contents.arp.hwtype = ARP_HWTYPE_ETHERNET;
txbuffer->frame.contents.arp.proto = ARP_PROTO_IP;
txbuffer->frame.contents.arp.hwsize = 6;
txbuffer->frame.contents.arp.protosize = 4;
txbuffer->frame.contents.arp.opcode = ARP_OPCODE_REQUEST;
txbuffer->frame.contents.arp.sender_ip = my_ip;
arp->hwtype = ARP_HWTYPE_ETHERNET;
arp->proto = ARP_PROTO_IP;
arp->hwsize = 6;
arp->protosize = 4;
arp->opcode = ARP_OPCODE_REQUEST;
arp->sender_ip = my_ip;
for(i=0;i<6;i++)
txbuffer->frame.contents.arp.sender_mac[i] = my_mac[i];
txbuffer->frame.contents.arp.target_ip = ip;
arp->sender_mac[i] = my_mac[i];
arp->target_ip = ip;
for(i=0;i<6;i++)
txbuffer->frame.contents.arp.target_mac[i] = 0;
arp->target_mac[i] = 0;
send_packet();

/* Do we get a reply ? */
139 changes: 118 additions & 21 deletions software/bios/tftp.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdint.h>
#include <string.h>

#include "microudp.h"
@@ -6,12 +7,25 @@
#define PORT_OUT 69
#define PORT_IN 7642

static int format_request(char *buf, const char *filename)
enum {
TFTP_RRQ = 1, /* Read request */
TFTP_WRQ = 2, /* Write request */
TFTP_DATA = 3, /* Data */
TFTP_ACK = 4, /* Acknowledgment */
TFTP_ERROR = 5, /* Error */
};

#define BLOCK_SIZE 512 /* block size in bytes */


static int format_request(uint8_t *buf, uint16_t op, const char *filename)
{
*buf++ = 0x00; /* Opcode: Request */
*buf++ = 0x01;
strcpy(buf, filename);
buf += strlen(filename);
int len = strlen(filename);

*buf++ = op >> 8; /* Opcode */
*buf++ = op;
memcpy(buf, filename, len);
buf += len;
*buf++ = 0x00;
*buf++ = 'o';
*buf++ = 'c';
@@ -22,52 +36,70 @@ static int format_request(char *buf, const char *filename)
return 9+strlen(filename);
}

static int format_ack(char *buf, unsigned short block)
static int format_ack(uint8_t *buf, uint16_t block)
{
*buf++ = 0x00; /* Opcode: Ack */
*buf++ = 0x04;
*buf++ = TFTP_ACK;
*buf++ = (block & 0xff00) >> 8;
*buf++ = (block & 0x00ff);
return 4;
}

static char *packet_data;
static int format_data(uint8_t *buf, uint16_t block, const void *data, int len)
{
*buf++ = 0x00; /* Opcode: Data*/
*buf++ = TFTP_DATA;
*buf++ = (block & 0xff00) >> 8;
*buf++ = (block & 0x00ff);
memcpy(buf, data, len);
return len+4;
}

static uint8_t *packet_data;
static int total_length;
static int transfer_finished;
static char *dst_buffer;
static uint8_t *dst_buffer;
static int last_ack; /* signed, so we can use -1 */
static uint16_t data_port;

static void rx_callback(unsigned int src_ip, unsigned short src_port, unsigned short dst_port, void *_data, unsigned int length)
static void rx_callback(uint32_t src_ip, uint16_t src_port,
uint16_t dst_port, void *_data, unsigned int length)
{
unsigned char *data = (unsigned char *)_data;
unsigned short opcode;
unsigned short block;
uint8_t *data = _data;
uint16_t opcode;
uint16_t block;
int i;
int offset;

if(length < 4) return;
if(dst_port != PORT_IN) return;
opcode = ((unsigned short)(data[0]) << 8)|((unsigned short)(data[1]));
block = ((unsigned short)(data[2]) << 8)|((unsigned short)(data[3]));
opcode = data[0] << 8 | data[1];
block = data[2] << 8 | data[3];
if(opcode == TFTP_ACK) { /* Acknowledgement */
data_port = src_port;
last_ack = block;
return;
}
if(block < 1) return;
if(opcode == 3) { /* Data */
if(opcode == TFTP_DATA) { /* Data */
length -= 4;
offset = (block-1)*512;
offset = (block-1)*BLOCK_SIZE;
for(i=0;i<length;i++)
dst_buffer[offset+i] = data[i+4];
total_length += length;
if(length < 512)
if(length < BLOCK_SIZE)
transfer_finished = 1;

length = format_ack(packet_data, block);
microudp_send(PORT_IN, src_port, length);
}
if(opcode == 5) { /* Error */
if(opcode == TFTP_ERROR) { /* Error */
total_length = -1;
transfer_finished = 1;
}
}

int tftp_get(unsigned int ip, const char *filename, char *buffer)
int tftp_get(uint32_t ip, const char *filename, void *buffer)
{
int len;
int tries;
@@ -86,7 +118,7 @@ int tftp_get(unsigned int ip, const char *filename, char *buffer)
transfer_finished = 0;
tries = 5;
while(1) {
len = format_request(packet_data, filename);
len = format_request(packet_data, TFTP_RRQ, filename);
microudp_send(PORT_IN, PORT_OUT, len);
for(i=0;i<2000000;i++) {
microudp_service();
@@ -117,3 +149,68 @@ int tftp_get(unsigned int ip, const char *filename, char *buffer)

return total_length;
}

int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size)
{
int len, send;
int tries;
int i;
int block = 0, sent = 0;

if(!microudp_arp_resolve(ip))
return -1;

microudp_set_callback(rx_callback);

packet_data = microudp_get_tx_buffer();

total_length = 0;
transfer_finished = 0;
tries = 5;
while(1) {
len = format_request(packet_data, TFTP_WRQ, filename);
microudp_send(PORT_IN, PORT_OUT, len);
for(i=0;i<2000000;i++) {
last_ack = -1;
microudp_service();
if(last_ack == block)
goto send_data;
if(transfer_finished)
goto fail;
}
tries--;
if(tries == 0)
goto fail;
}

send_data:
do {
block++;
send = sent+BLOCK_SIZE > size ? size-sent : BLOCK_SIZE;
tries = 5;
while(1) {
len = format_data(packet_data, block, buffer, send);
microudp_send(PORT_IN, data_port, len);
for(i=0;i<12000000;i++) {
microudp_service();
if(transfer_finished)
goto fail;
if(last_ack == block)
goto next;
}
if (!--tries)
goto fail;
}
next:
sent += send;
buffer += send;
} while (send == BLOCK_SIZE);

microudp_set_callback(NULL);

return sent;

fail:
microudp_set_callback(NULL);
return -1;
}
5 changes: 4 additions & 1 deletion software/bios/tftp.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#ifndef __TFTP_H
#define __TFTP_H

int tftp_get(unsigned int ip, const char *filename, char *buffer);
#include <stdint.h>

int tftp_get(uint32_t ip, const char *filename, void *buffer);
int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size);

#endif /* __TFTP_H */