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