khypervisor
v1
|
00001 #include <context.h> 00002 #include <vdev.h> 00003 #include <hvmm_trace.h> 00004 00005 #include <log/print.h> 00006 00007 #define MAX_VDEV 5 00008 00009 static vdev_info_t vdev_list[MAX_VDEV]; 00010 00011 void vdev_init(void) 00012 { 00013 int i = 0; 00014 for (i = 0; i < MAX_VDEV; i++) { 00015 vdev_list[i].name = 0; 00016 vdev_list[i].base = 0; 00017 vdev_list[i].size = 0; 00018 vdev_list[i].handler = 0x0; 00019 } 00020 } 00021 00022 hvmm_status_t vdev_reg_device(vdev_info_t *new_vdev) 00023 { 00024 hvmm_status_t result = HVMM_STATUS_BUSY; 00025 int i = 0; 00026 00027 HVMM_TRACE_ENTER(); 00028 for (i = 0; i < MAX_VDEV; i++) { 00029 if (vdev_list[i].handler == 0x0 ) { 00030 vdev_list[i].name = new_vdev->name; 00031 vdev_list[i].base = new_vdev->base; 00032 vdev_list[i].size = new_vdev->size; 00033 vdev_list[i].handler = new_vdev->handler; 00034 printh("vdev:Registered vdev '%s' at index %d\n", vdev_list[i].name, i); 00035 00036 result = HVMM_STATUS_SUCCESS; 00037 break; 00038 } 00039 } 00040 00041 if ( result != HVMM_STATUS_SUCCESS ) { 00042 printh("vdev:Failed registering vdev '%s', max %d full \n", new_vdev->name, MAX_VDEV); 00043 } 00044 00045 HVMM_TRACE_EXIT(); 00046 return result; 00047 } 00048 00049 hvmm_status_t vdev_emulate(uint32_t fipa, uint32_t wnr, vdev_access_size_t access_size, uint32_t srt, struct arch_regs *regs) 00050 { 00051 hvmm_status_t result = HVMM_STATUS_NOT_FOUND; 00052 int i = 0; 00053 uint32_t offset; 00054 uint8_t isize = 4; 00055 00056 HVMM_TRACE_ENTER(); 00057 if ( regs->cpsr & 0x20 ) { 00058 /* Thumb */ 00059 isize = 2; 00060 } 00061 00062 for (i = 0; i < MAX_VDEV; i++){ 00063 if ( vdev_list[i].base == 0 ) break; 00064 00065 offset = fipa - vdev_list[i].base; 00066 if ( fipa >= vdev_list[i].base && offset < vdev_list[i].size && vdev_list[i].handler != 0) { 00067 /* fipa is in the rage: base ~ base + size */ 00068 printh("vdev: found %s for fipa %x srt:%x gpr[srt]:%x write:%d vmid:%d\n", vdev_list[i].name, fipa, srt, regs->gpr[srt], wnr, context_current_vmid() ); 00069 result = vdev_list[i].handler(wnr, offset, &(regs->gpr[srt]), access_size); 00070 if ( wnr == 0 ) { 00071 printh("vdev: result:%x\n", regs->gpr[srt] ); 00072 } 00073 00074 /* Update PC regardless handling result */ 00075 regs->pc += isize; 00076 break; 00077 } else { 00078 printh("vdev: fipa %x base %x not matched\n", fipa, vdev_list[i].base ); 00079 } 00080 } 00081 HVMM_TRACE_EXIT(); 00082 00083 return result; 00084 }