added front-end link code
authorAndrew Waterman <waterman@s143.Millennium.Berkeley.EDU>
Mon, 22 Mar 2010 02:07:50 +0000 (19:07 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:37 +0000 (17:35 -0700)
kern/arch/i686/Makefrag
kern/arch/i686/frontend.c [new file with mode: 0644]
kern/arch/i686/frontend.h

index 2d826a1..562f020 100644 (file)
@@ -33,5 +33,6 @@ KERN_ARCH_SRCFILES := $(KERN_ARCH_SRC_DIR)/entry.S \
                       $(KERN_ARCH_SRC_DIR)/ne2k.c \
                       $(KERN_ARCH_SRC_DIR)/nic_common.c \
                       $(KERN_ARCH_SRC_DIR)/init.c \
-                      $(KERN_ARCH_SRC_DIR)/env.c
+                      $(KERN_ARCH_SRC_DIR)/env.c \
+                      $(KERN_ARCH_SRC_DIR)/frontend.c
 
diff --git a/kern/arch/i686/frontend.c b/kern/arch/i686/frontend.c
new file mode 100644 (file)
index 0000000..f82ee4b
--- /dev/null
@@ -0,0 +1,67 @@
+#include <multiboot.h>
+#include <arch/frontend.h>
+#include <arch/nic_common.h>
+#include <kmalloc.h>
+
+int handle_appserver_packet(const char* p, size_t size)
+{
+       appserver_packet_t* packet = (appserver_packet_t*)p;
+
+       if(size < sizeof(packet->header))
+               goto fail;
+
+       uint8_t cmd = packet->header.cmd;
+       if(cmd != APPSERVER_CMD_LOAD && cmd != APPSERVER_CMD_STORE)
+               goto fail;
+
+       uintptr_t paddr = ntohl(packet->header.addr);
+       size_t copy_size = ntohl(packet->header.payload_size);
+       if(paddr % 4 || paddr >= maxaddrpa)
+               goto fail;
+       if(copy_size % 4 || copy_size > APPSERVER_MAX_PAYLOAD_SIZE)
+               goto fail;
+
+       size_t paysize = copy_size;
+       size_t response_paysize = 0;
+       if(cmd == APPSERVER_CMD_LOAD)
+       {
+               response_paysize = copy_size;
+               paysize = 0;
+       }
+       if(size != sizeof(packet->header) + paysize)
+               goto fail;
+
+       // construct response packet
+       size_t response_size = sizeof(packet->header)+response_paysize;
+       appserver_packet_t* response_packet = kmalloc(response_size,0);
+
+       memcpy(response_packet->header.dst_mac,packet->header.src_mac,6);
+       memcpy(response_packet->header.src_mac,packet->header.dst_mac,6);
+       response_packet->header.ethertype = packet->header.ethertype;
+       response_packet->header.cmd = APPSERVER_CMD_ACK;
+       response_packet->header.seqno = packet->header.seqno;
+       response_packet->header.payload_size = packet->header.payload_size;
+       response_packet->header.addr = packet->header.addr;
+       
+       // determine src/dest for copy
+       const uint32_t* copy_src = (const uint32_t*)packet->payload;
+       uint32_t* copy_dst = (uint32_t*)KADDR(paddr);
+       if(cmd == APPSERVER_CMD_LOAD)
+       {
+               copy_src = copy_dst;
+               copy_dst = (uint32_t*)response_packet->payload;
+       }
+
+       // manual word-by-word copy for word-atomicity
+       for(int i = 0; i < copy_size/sizeof(uint32_t); i++)
+               copy_dst[i] = copy_src[i];
+
+       // fire the response
+       if(send_frame((char*)response_packet,response_size) != response_size)
+               panic("couldn't send appserver packet!");
+
+       return 0;
+       
+fail:
+       panic("bad appserver packet!");
+}
index 6a7c37a..8f5814b 100644 (file)
@@ -6,6 +6,29 @@
 #ifndef ROS_ARCH_FRONTEND_H
 #define ROS_ARCH_FRONTEND_H
 
+#define APPSERVER_MAX_PAYLOAD_SIZE 1024
+
+#define APPSERVER_CMD_LOAD  0
+#define APPSERVER_CMD_STORE 1
+#define APPSERVER_CMD_ACK   2
+
 int handle_appserver_packet(const char *buf, size_t len);
 
+typedef struct
+{
+       uint8_t dst_mac[6];
+       uint8_t src_mac[6];
+       uint16_t ethertype;
+       uint8_t cmd;
+       uint8_t seqno;
+       uint32_t payload_size;
+       uint32_t addr;
+} appserver_packet_header_t;
+
+typedef struct
+{
+       appserver_packet_header_t header;
+       uint8_t payload[APPSERVER_MAX_PAYLOAD_SIZE];
+} appserver_packet_t;
+
 #endif