2020-07-09 11:28:57 -05:00
# include "mailboxes.h"
2019-06-27 17:00:23 -05:00
# include "kmalloc.h"
# include <string.h>
# include <stdint.h>
# include <mailboxes.h>
2019-08-04 13:14:35 -05:00
# include "serial.h"
2019-09-22 08:38:31 -05:00
# include "paging.h"
# include "pmem.h"
2019-08-25 13:52:31 -05:00
# include "../tasking.h"
2019-06-24 13:24:39 -05:00
2019-06-29 09:04:34 -05:00
Mailbox * mailboxes = ( Mailbox * ) 0xF6400000 ;
2019-07-20 11:03:27 -05:00
uint32_t next_box = 1 ;
2019-06-27 17:00:23 -05:00
2019-09-01 13:52:32 -05:00
uint32_t kernel_mailbox_new ( uint16_t size , char * name ) {
2019-06-27 17:00:23 -05:00
if ( next_box = = 262144 ) {
2019-08-04 13:14:35 -05:00
serial_printf ( " Attempted to create a mailbox, but failed \n " ) ;
2019-06-27 17:00:23 -05:00
return 0xFFFFFFFF ;
}
mailboxes [ next_box ] . rd = 0 ;
mailboxes [ next_box ] . wr = 0 ;
mailboxes [ next_box ] . size = size ;
mailboxes [ next_box ] . msg_store = kmalloc ( sizeof ( Message ) * size ) ;
2019-09-01 13:52:32 -05:00
if ( strlen ( name ) > 19 ) {
name [ 20 ] = ' \0 ' ;
}
strcpy ( mailboxes [ next_box ] . name , name ) ;
serial_printf ( " PID %d created mailbox %s \n " , getPID ( ) , mailboxes [ next_box ] . name ) ;
2019-06-27 17:00:23 -05:00
next_box + + ;
return next_box - 1 ;
}
void kernel_mailbox_free ( uint32_t box ) {
kfree ( mailboxes [ box ] . msg_store ) ;
2019-06-24 13:24:39 -05:00
}
2019-06-27 17:00:23 -05:00
void kernel_mailbox_send_msg ( Message * user_msg ) {
2019-08-28 20:24:53 -05:00
if ( user_msg - > to = = 0 ) {
2019-09-01 13:52:32 -05:00
serial_printf ( " Box %s attempted to send to box 0! \n " , mailboxes [ user_msg - > from ] . name ) ;
2019-08-28 20:24:53 -05:00
return ;
}
2019-06-27 17:00:23 -05:00
Mailbox mailbox = mailboxes [ user_msg - > to ] ;
2019-09-22 08:38:31 -05:00
uint32_t num_pages = ( user_msg - > size / 4096 ) + 1 ;
2019-10-20 09:44:33 -05:00
serial_printf ( " Storing data in pmem \n " ) ;
2019-09-22 08:38:31 -05:00
void * phys_addr = pmem_alloc ( num_pages ) ;
void * virt_addr = find_free_pages ( num_pages ) ;
map_pages ( virt_addr , phys_addr , num_pages , 0 , 1 ) ;
2019-10-20 09:44:33 -05:00
serial_printf ( " Mapped into vmem \n " ) ;
2019-09-22 08:38:31 -05:00
memcpy ( virt_addr , user_msg - > msg , user_msg - > size ) ;
unmap_pages ( virt_addr , num_pages ) ;
2019-10-20 09:44:33 -05:00
serial_printf ( " Stored data in pmem \n " ) ;
2019-09-22 08:38:31 -05:00
mailbox . msg_store [ mailbox . wr ] . msg = phys_addr ;
2019-06-27 17:00:23 -05:00
mailbox . msg_store [ mailbox . wr ] . from = user_msg - > from ;
mailbox . msg_store [ mailbox . wr ] . to = user_msg - > to ;
mailbox . msg_store [ mailbox . wr ] . size = user_msg - > size ;
mailbox . wr + + ;
if ( mailbox . wr = = mailbox . size ) {
mailbox . wr = 0 ;
2019-06-24 13:24:39 -05:00
}
2019-06-27 17:00:23 -05:00
if ( mailbox . wr = = mailbox . rd ) {
mailbox . wr - - ;
if ( mailbox . wr = = ( 2 ^ 32 ) - 1 ) {
mailbox . wr = mailbox . size - 1 ;
2019-06-24 13:24:39 -05:00
}
}
2019-08-25 13:52:31 -05:00
mailboxes [ user_msg - > to ] = mailbox ;
2019-09-01 13:52:32 -05:00
serial_printf ( " Message sent from box %s to box %s \n " , mailboxes [ user_msg - > from ] . name , mailboxes [ user_msg - > to ] . name ) ;
2019-06-24 13:24:39 -05:00
}
2019-06-27 17:00:23 -05:00
void kernel_mailbox_get_msg ( uint32_t box , Message * recv_msg , uint32_t buffer_sz ) {
Mailbox mailbox = mailboxes [ box ] ;
2019-09-01 14:14:25 -05:00
if ( mailbox . msg_store [ mailbox . rd ] . from = = 0 ) {
2019-08-31 16:46:21 -05:00
recv_msg - > size = 0 ;
recv_msg - > from = 0 ;
2019-09-01 13:52:32 -05:00
serial_printf ( " Box %s attempted to get a message, but there were none. \n " , mailboxes [ box ] . name ) ;
2019-08-31 16:46:21 -05:00
mailboxes [ box ] = mailbox ;
return ;
2019-06-24 13:24:39 -05:00
}
2019-06-27 17:00:23 -05:00
recv_msg - > from = mailbox . msg_store [ mailbox . rd ] . from ;
recv_msg - > to = mailbox . msg_store [ mailbox . rd ] . to ;
recv_msg - > size = mailbox . msg_store [ mailbox . rd ] . size ;
2019-09-01 13:01:37 -05:00
if ( buffer_sz < mailbox . msg_store [ mailbox . rd ] . size ) {
2019-06-27 17:00:23 -05:00
recv_msg - > size = mailbox . msg_store [ mailbox . rd ] . size ;
recv_msg - > from = 0 ;
2019-09-01 13:52:32 -05:00
serial_printf ( " Box %s attempted to get the message from box %s, but the buffer was too small. \n " , mailboxes [ box ] . name , mailboxes [ mailbox . msg_store [ mailbox . rd ] . from ] . name ) ;
2019-09-22 08:38:31 -05:00
serial_printf ( " Expected message at most %d big, but got message sized %d. \n " , buffer_sz , mailbox . msg_store [ mailbox . rd ] . size ) ;
2019-08-25 13:52:31 -05:00
mailboxes [ box ] = mailbox ;
2019-06-27 17:00:23 -05:00
return ;
}
2019-10-20 09:44:33 -05:00
if ( buffer_sz > mailbox . msg_store [ mailbox . rd ] . size ) {
serial_printf ( " Warning: buffer sized for message %d big, but got message sized %d. \n " , buffer_sz , mailbox . msg_store [ mailbox . rd ] . size ) ;
}
2019-09-22 08:38:31 -05:00
Message msg = mailbox . msg_store [ mailbox . rd ] ;
uint32_t num_pages = ( msg . size / 4096 ) + 1 ;
void * virt_addr = find_free_pages ( num_pages ) ;
map_pages ( virt_addr , msg . msg , num_pages , 0 , 1 ) ;
memcpy ( recv_msg - > msg , virt_addr , mailbox . msg_store [ mailbox . rd ] . size ) ;
2020-07-09 11:28:57 -05:00
// unmap_pages(virt_addr,num_pages);
// pmem_free(((uint32_t)msg.msg)>>12,num_pages);
2019-09-22 08:38:31 -05:00
// kfree(mailbox.msg_store[mailbox.rd].msg);
2019-09-01 14:14:25 -05:00
mailbox . msg_store [ mailbox . rd ] . from = 0 ;
2019-08-31 18:43:27 -05:00
uint32_t orig_rd = mailbox . rd ;
2019-06-27 17:00:23 -05:00
mailbox . rd + + ;
if ( mailbox . rd = = mailbox . size ) {
mailbox . rd = 0 ;
2019-06-24 13:24:39 -05:00
}
2019-08-31 18:43:27 -05:00
if ( mailbox . rd > mailbox . wr & & ! ( orig_rd > mailbox . wr ) ) {
2019-08-31 16:46:21 -05:00
mailbox . rd = mailbox . wr ;
2019-06-24 13:24:39 -05:00
}
2019-09-01 13:52:32 -05:00
serial_printf ( " Box %s got a message from box %s. \n " , mailboxes [ box ] . name , mailboxes [ recv_msg - > from ] . name ) ;
2019-08-25 13:52:31 -05:00
mailboxes [ box ] = mailbox ;
2019-06-24 13:24:39 -05:00
}
2019-09-05 09:39:13 -05:00
uint32_t kernel_mailbox_find_by_name ( char * name ) {
for ( uint32_t i = 1 ; i < next_box ; i + + ) {
if ( strcmp ( mailboxes [ i ] . name , name ) = = 0 ) {
return i ;
}
}
return 0 ;
}