added front-end link code
[akaros.git] / kern / arch / i686 / frontend.c
1 #include <multiboot.h>
2 #include <arch/frontend.h>
3 #include <arch/nic_common.h>
4 #include <kmalloc.h>
5
6 int handle_appserver_packet(const char* p, size_t size)
7 {
8         appserver_packet_t* packet = (appserver_packet_t*)p;
9
10         if(size < sizeof(packet->header))
11                 goto fail;
12
13         uint8_t cmd = packet->header.cmd;
14         if(cmd != APPSERVER_CMD_LOAD && cmd != APPSERVER_CMD_STORE)
15                 goto fail;
16
17         uintptr_t paddr = ntohl(packet->header.addr);
18         size_t copy_size = ntohl(packet->header.payload_size);
19         if(paddr % 4 || paddr >= maxaddrpa)
20                 goto fail;
21         if(copy_size % 4 || copy_size > APPSERVER_MAX_PAYLOAD_SIZE)
22                 goto fail;
23
24         size_t paysize = copy_size;
25         size_t response_paysize = 0;
26         if(cmd == APPSERVER_CMD_LOAD)
27         {
28                 response_paysize = copy_size;
29                 paysize = 0;
30         }
31         if(size != sizeof(packet->header) + paysize)
32                 goto fail;
33
34         // construct response packet
35         size_t response_size = sizeof(packet->header)+response_paysize;
36         appserver_packet_t* response_packet = kmalloc(response_size,0);
37
38         memcpy(response_packet->header.dst_mac,packet->header.src_mac,6);
39         memcpy(response_packet->header.src_mac,packet->header.dst_mac,6);
40         response_packet->header.ethertype = packet->header.ethertype;
41         response_packet->header.cmd = APPSERVER_CMD_ACK;
42         response_packet->header.seqno = packet->header.seqno;
43         response_packet->header.payload_size = packet->header.payload_size;
44         response_packet->header.addr = packet->header.addr;
45         
46         // determine src/dest for copy
47         const uint32_t* copy_src = (const uint32_t*)packet->payload;
48         uint32_t* copy_dst = (uint32_t*)KADDR(paddr);
49         if(cmd == APPSERVER_CMD_LOAD)
50         {
51                 copy_src = copy_dst;
52                 copy_dst = (uint32_t*)response_packet->payload;
53         }
54
55         // manual word-by-word copy for word-atomicity
56         for(int i = 0; i < copy_size/sizeof(uint32_t); i++)
57                 copy_dst[i] = copy_src[i];
58
59         // fire the response
60         if(send_frame((char*)response_packet,response_size) != response_size)
61                 panic("couldn't send appserver packet!");
62
63         return 0;
64         
65 fail:
66         panic("bad appserver packet!");
67 }