99 */
1010
1111#include "inc/bao.h"
12+ #include "inc/types.h"
1213#include <remio.h>
1314#include <cpu.h>
1415#include <vm.h>
@@ -285,6 +286,110 @@ static size_t remio_get_request_event_count(struct remio_device* device)
285286 return list_size (& device -> request_event_list );
286287}
287288
289+ /**
290+ * @brief Finds the Remote I/O device based on the Remote I/O device ID
291+ * @param id Remote I/O device ID
292+ * @return Returns the Remote I/O device or NULL if the device was not found
293+ */
294+ static struct remio_device * remio_find_dev_by_id (remio_id_t id )
295+ {
296+ struct remio_device * device = NULL ;
297+ list_foreach (remio_device_list , struct remio_device , io_device ) {
298+ if (id == io_device -> id ) {
299+ device = io_device ;
300+ break ;
301+ }
302+ }
303+ return device ;
304+ }
305+
306+ /**
307+ * @brief Finds the Remote I/O device associated with a VM based on the Remote I/O device ID
308+ * @param vm Pointer to the VM structure
309+ * @param id Remote I/O device ID
310+ * @return Returns the Remote I/O device or NULL if the device was not found
311+ */
312+ static struct remio_device * remio_find_vm_dev_by_id (struct vm * vm , unsigned long id )
313+ {
314+ struct remio_dev * dev = NULL ;
315+ struct remio_device * device = NULL ;
316+
317+ /** Find the Remote I/O device VM configuration based on the Remote I/O device ID */
318+ for (size_t i = 0 ; i < vm -> remio_dev_num ; i ++ ) {
319+ dev = & vm -> remio_devs [i ];
320+ if (dev -> id == id ) {
321+ break ;
322+ }
323+ }
324+
325+ if (dev == NULL ) {
326+ return NULL ;
327+ }
328+
329+ /** Find the Remote I/O device based on the Remote I/O device ID */
330+ device = remio_find_dev_by_id (id );
331+ if (device == NULL ) {
332+ return NULL ;
333+ }
334+
335+ /** Check if the Remote I/O device is associated with the VM */
336+ if (dev -> type == REMIO_DEV_BACKEND && vm -> id == device -> config .backend .vm_id ) {
337+ return device ;
338+ } else if (dev -> type == REMIO_DEV_FRONTEND && vm -> id == device -> config .frontend .vm_id ) {
339+ return device ;
340+ } else {
341+ return NULL ;
342+ }
343+
344+ return NULL ;
345+ }
346+
347+ /**
348+ * @brief Finds the Remote I/O device associated with a VM based on the MMIO access address
349+ * @param vm Pointer to the VM structure
350+ * @param addr MMIO access address
351+ * @return Returns the Remote I/O device or NULL if the device was not found
352+ */
353+ static struct remio_device * remio_find_vm_dev_by_addr (struct vm * vm , unsigned long addr )
354+ {
355+ struct remio_dev * dev = NULL ;
356+
357+ for (size_t i = 0 ; i < vm -> remio_dev_num ; i ++ ) {
358+ dev = & vm -> remio_devs [i ];
359+ if (in_range (addr , dev -> va , dev -> size )) {
360+ break ;
361+ }
362+ }
363+
364+ if (dev == NULL ) {
365+ return NULL ;
366+ }
367+
368+ return remio_find_vm_dev_by_id (vm , dev -> id );
369+ }
370+
371+ /**
372+ * @brief Sends a Remote I/O CPU message to the target CPU
373+ * @param event Message event (REMIO_CPU_MSG_*)
374+ * @param target_cpu Target CPU ID
375+ * @param id Remote I/O device ID
376+ * @param cpu_id CPU ID of the frontend VM that issued the I/O request
377+ * @param vcpu_id vCPU ID of the frontend VM that issued the I/O request
378+ * @param interrupt Interrupt ID
379+ */
380+ static void remio_cpu_send_msg (enum REMIO_CPU_MSG_EVENT event , unsigned long target_cpu ,
381+ unsigned long id , unsigned long cpu_id , unsigned long long vcpu_id , unsigned long interrupt )
382+ {
383+ union remio_cpu_msg_data data = {
384+ .id = (uint8_t )id ,
385+ .cpu_id = (uint8_t )cpu_id ,
386+ .vcpu_id = (uint8_t )vcpu_id ,
387+ .interrupt = (uint8_t )interrupt ,
388+ };
389+ struct cpu_msg msg = { (uint32_t )REMIO_CPUMSG_ID , event , data .raw };
390+ cpu_send_msg (target_cpu , & msg );
391+ }
392+
288393void remio_init (void )
289394{
290395 size_t frontend_cnt = 0 , backend_cnt = 0 ;
@@ -343,18 +448,15 @@ void remio_init(void)
343448 struct vm_config * vm_config = & config .vmlist [vm_id ];
344449 for (size_t i = 0 ; i < vm_config -> platform .remio_dev_num ; i ++ ) {
345450 struct remio_dev * dev = & vm_config -> platform .remio_devs [i ];
346- list_foreach (remio_device_list , struct remio_device , device ) {
347- if (dev -> id == device -> id ) {
348- if (dev -> type == REMIO_DEV_BACKEND ) {
349- device -> config .backend .vm_id = vm_id ;
350- device -> config .backend .interrupt = dev -> interrupt ;
351- device -> config .backend .cpu_id = (cpuid_t )- 1 ;
352- } else {
353- device -> config .frontend .vm_id = vm_id ;
354- device -> config .frontend .interrupt = dev -> interrupt ;
355- device -> config .frontend .cpu_id = (cpuid_t )- 1 ;
356- }
357- }
451+ struct remio_device * device = remio_find_dev_by_id (dev -> id );
452+ if (dev -> type == REMIO_DEV_BACKEND ) {
453+ device -> config .backend .vm_id = vm_id ;
454+ device -> config .backend .interrupt = dev -> interrupt ;
455+ device -> config .backend .cpu_id = (cpuid_t )- 1 ;
456+ } else {
457+ device -> config .frontend .vm_id = vm_id ;
458+ device -> config .frontend .interrupt = dev -> interrupt ;
459+ device -> config .frontend .cpu_id = (cpuid_t )- 1 ;
358460 }
359461 }
360462 }
@@ -378,93 +480,6 @@ void remio_assign_vm_cpus(struct vm* vm)
378480 }
379481}
380482
381- /**
382- * @brief Finds the Remote I/O device associated with a VM based on the Remote I/O device ID
383- * @param vm Pointer to the VM structure
384- * @param id Remote I/O device ID
385- * @return Returns the Remote I/O device or NULL if the device was not found
386- */
387- static struct remio_device * remio_find_vm_dev_by_id (struct vm * vm , unsigned long id )
388- {
389- struct remio_dev * dev = NULL ;
390- struct remio_device * device = NULL ;
391-
392- /** Find the Remote I/O device VM configuration based on the Remote I/O device ID */
393- for (size_t i = 0 ; i < vm -> remio_dev_num ; i ++ ) {
394- dev = & vm -> remio_devs [i ];
395- if (dev -> id == id ) {
396- break ;
397- }
398- }
399-
400- if (dev == NULL ) {
401- return NULL ;
402- }
403-
404- /** Find the Remote I/O device based on the Remote I/O device ID */
405- list_foreach (remio_device_list , struct remio_device , io_device ) {
406- if (id == io_device -> id ) {
407- if (dev -> type == REMIO_DEV_BACKEND && vm -> id == io_device -> config .backend .vm_id ) {
408- device = io_device ;
409- break ;
410- } else if (dev -> type == REMIO_DEV_FRONTEND &&
411- vm -> id == io_device -> config .frontend .vm_id ) {
412- device = io_device ;
413- break ;
414- } else {
415- return NULL ;
416- }
417- }
418- }
419- return device ;
420- }
421-
422- /**
423- * @brief Finds the Remote I/O device associated with a VM based on the MMIO access address
424- * @param vm Pointer to the VM structure
425- * @param addr MMIO access address
426- * @return Returns the Remote I/O device or NULL if the device was not found
427- */
428- static struct remio_device * remio_find_vm_dev_by_addr (struct vm * vm , unsigned long addr )
429- {
430- struct remio_dev * dev = NULL ;
431-
432- for (size_t i = 0 ; i < vm -> remio_dev_num ; i ++ ) {
433- dev = & vm -> remio_devs [i ];
434- if (in_range (addr , dev -> va , dev -> size )) {
435- break ;
436- }
437- }
438-
439- if (dev == NULL ) {
440- return NULL ;
441- }
442-
443- return remio_find_vm_dev_by_id (vm , dev -> id );
444- }
445-
446- /**
447- * @brief Sends a Remote I/O CPU message to the target CPU
448- * @param event Message event (REMIO_CPU_MSG_*)
449- * @param target_cpu Target CPU ID
450- * @param id Remote I/O device ID
451- * @param cpu_id CPU ID of the frontend VM that issued the I/O request
452- * @param vcpu_id vCPU ID of the frontend VM that issued the I/O request
453- * @param interrupt Interrupt ID
454- */
455- static void remio_cpu_send_msg (enum REMIO_CPU_MSG_EVENT event , unsigned long target_cpu ,
456- unsigned long id , unsigned long cpu_id , unsigned long long vcpu_id , unsigned long interrupt )
457- {
458- union remio_cpu_msg_data data = {
459- .id = (uint8_t )id ,
460- .cpu_id = (uint8_t )cpu_id ,
461- .vcpu_id = (uint8_t )vcpu_id ,
462- .interrupt = (uint8_t )interrupt ,
463- };
464- struct cpu_msg msg = { (uint32_t )REMIO_CPUMSG_ID , event , data .raw };
465- cpu_send_msg (target_cpu , & msg );
466- }
467-
468483/**
469484 * @brief Handles the Remote I/O ask operation
470485 * @param addr Should always be zero (convention)
0 commit comments