Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
V
virtual_game_machine
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
adrian.spycher
virtual_game_machine
Commits
d309cb2c
Commit
d309cb2c
authored
7 months ago
by
adrian.spycher
Browse files
Options
Downloads
Patches
Plain Diff
feat!: refactore code
parent
ba113a08
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
shared/hypercall_params.h
+14
-2
14 additions, 2 deletions
shared/hypercall_params.h
vmm/handler.c
+151
-0
151 additions, 0 deletions
vmm/handler.c
vmm/handler.h
+45
-0
45 additions, 0 deletions
vmm/handler.h
vmm/vmm_main.c
+9
-48
9 additions, 48 deletions
vmm/vmm_main.c
with
219 additions
and
50 deletions
shared/hypercall_params.h
+
14
−
2
View file @
d309cb2c
...
...
@@ -5,8 +5,14 @@
// --- DEFINE ---
#define HYPERCALL_SHARED_ADDR 0xC0000000
#define HYPERCALL_BUFF_SIZE 4096
#define HYPERCALL_PMIO_ADDR 0xABBA
#define HYPERCALL_SHARED_ADDR 0xC0000000
#define HYPERCALL_BUFF_SIZE 4096
#define HYPERCALL_CODE_CONSOLE 1
#define HYPERCALL_CODE_TIMER 2
#define HYPERCALL_CODE_GFX_INIT 3
// --- SHARED STRUCT ---
...
...
@@ -20,6 +26,12 @@ typedef struct {
uint32_t
us
;
// delay in micro-seconds
}
__attribute__
((
packed
))
hyper_timer_sleep_params_t
;
typedef
struct
{
uint32_t
width
;
// horizontal resolution in pixels
uint32_t
height
;
// vertical resolution in pixels
}
__attribute__
((
packed
))
hyper_init_gfx_params_t
;
// --- FUNCTION ---
// ...
...
...
This diff is collapsed.
Click to expand it.
vmm/handler.c
0 → 100644
+
151
−
0
View file @
d309cb2c
#include
"handler.h"
#include
<err.h>
#include
<stdio.h>
#include
<stdint.h>
#include
<unistd.h>
#include
"shared/hypercall_params.h"
// --- DEFINE ---
state_handler_t
const
STATE_HANDLERS
[]
=
{
[
KVM_EXIT_HLT
]
=
handle_halt
,
[
KVM_EXIT_IO
]
=
handle_pmio
,
[
KVM_EXIT_MMIO
]
=
handle_mmio
,
};
static
state_t
const
STATE_TIMER
[]
=
{
{
OP_WRITE_EQUAL
,
0x43
,
20
,
2
,
NULL
},
{
OP_WRITE_EQUAL
,
0x40
,
0
,
4
,
NULL
},
{
OP_WRITE_EQUAL
,
0
,
0
,
0
,
NULL
},
};
static
state_t
const
STATE_VGA
[]
=
{
{
OP_WRITE_EQUAL
,
0x3C2
,
0x67
,
1
,
NULL
},
{
OP_WRITE_EQUAL
,
0x3C4
,
0xF02
,
2
,
NULL
},
{
OP_WRITE_EQUAL
,
0x3CE
,
0x506
,
2
,
NULL
},
{
OP_WRITE_EQUAL
,
0x3DA
,
0x80
,
1
,
NULL
},
{
OP_WRITE_EQUAL
,
0x3C0
,
0x20
,
1
,
NULL
},
{
OP_WRITE_EQUAL
,
0x3C5
,
0x0F
,
1
,
NULL
},
{
OP_WRITE_EQUAL
,
0
,
0
,
0
,
NULL
},
};
// --- STATIC FUNCTION ---
static
uint32_t
retrieve_value
(
uint8_t
*
addr
,
uint8_t
size
)
{
uint32_t
value
;
switch
(
size
)
{
case
1
:
value
=
*
(
uint8_t
*
)
addr
;
break
;
case
2
:
value
=
*
(
uint16_t
*
)
addr
;
break
;
case
4
:
value
=
*
(
uint32_t
*
)
addr
;
break
;
default:
errx
(
1
,
"Unsupported size trying to retrieve value.
\n
"
);
break
;
}
return
value
;
}
// --- FUNCTION ---
// - VMM EXIT REASON HANDLER -
void
handle_halt
(
struct
kvm_run
*
run
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
)
{
// printf("KVM_EXIT_HLT\n");
}
void
handle_pmio
(
struct
kvm_run
*
run
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
)
{
if
(
run
->
io
.
direction
==
KVM_EXIT_IO_OUT
)
{
uint32_t
value
=
retrieve_value
((
uint8_t
*
)
run
+
run
->
io
.
data_offset
,
run
->
io
.
size
);
printf
(
"PMIO guest write:
\t
size=%d
\t
port=0x%x
\t
value=%d
\n
"
,
run
->
io
.
size
*
8
,
run
->
io
.
port
,
value
);
switch
(
run
->
io
.
port
)
{
case
HYPERCALL_PMIO_ADDR
:
handle_hypercall
(
value
,
shared_buf
,
mem
);
break
;
case
0x43
:
break
;
case
0x40
:
break
;
}
}
}
void
handle_mmio
(
struct
kvm_run
*
run
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
)
{
if
(
run
->
mmio
.
is_write
)
{
uint32_t
value
=
retrieve_value
((
uint8_t
*
)
run
->
mmio
.
data
,
run
->
mmio
.
len
);
printf
(
"MMIO guest write:
\t
addr=0x%llx
\t
len=%d
\t
value=%d
\n
"
,
run
->
mmio
.
phys_addr
,
run
->
mmio
.
len
*
8
,
value
);
}
}
// - HYPERCALL HANDLER -
void
handle_hypercall
(
uint32_t
code
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
)
{
switch
(
code
)
{
case
HYPERCALL_CODE_CONSOLE
:
handle_hypercall_console
(
shared_buf
,
mem
);
break
;
case
HYPERCALL_CODE_TIMER
:
handle_hypercall_timer
(
shared_buf
);
break
;
case
HYPERCALL_CODE_GFX_INIT
:
handle_hypercall_gfx_init
(
shared_buf
);
break
;
default:
// TODO:
break
;
}
}
void
handle_hypercall_console
(
uint8_t
*
shared_buf
,
uint8_t
*
mem
)
{
hyper_virtual_console_params_t
*
p_consol
=
(
hyper_virtual_console_params_t
*
)
shared_buf
;
printf
(
"hypercall : sending a message...
\n
"
);
printf
(
"%s
\n
"
,
p_consol
->
msg
+
mem
);
}
void
handle_hypercall_timer
(
uint8_t
*
shared_buf
)
{
hyper_timer_sleep_params_t
*
p_timer
=
(
hyper_timer_sleep_params_t
*
)
shared_buf
;
printf
(
"hypercall : setting up a %dus timer...
\n
"
,
p_timer
->
us
);
sleep
(
p_timer
->
us
/
1e6
);
}
void
handle_hypercall_gfx_init
(
uint8_t
*
shared_buf
)
{
hyper_init_gfx_params_t
*
p_init_gfx
=
(
hyper_init_gfx_params_t
*
)
shared_buf
;
printf
(
"hypercall : initializing gfx...
\n
"
);
// TODO:
}
This diff is collapsed.
Click to expand it.
vmm/handler.h
0 → 100644
+
45
−
0
View file @
d309cb2c
#define _STATES_H_
#ifdef _STATES_H_
#include
<stdint.h>
#include
<linux/kvm.h>
// --- DEFINE ---
typedef
enum
{
OP_WRITE_EQUAL
,
OP_READ_INJECT
,
OP_EMUL_END
,
}
operation_t
;
typedef
void
(
*
state_handler_t
)(
struct
kvm_run
*
run
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
);
typedef
struct
{
operation_t
op
;
// the operation to perform
uint32_t
addr
;
// the address written to/read from
uint32_t
value
;
// the expected written value or value to inject
uint8_t
size
;
// the size of the operation (8, 16 or 32 bits)
void
(
*
callback
)();
// custom function that would be executed at the end of the state
}
state_t
;
extern
state_handler_t
const
STATE_HANDLERS
[];
// --- FUNCITON ---
void
handle_halt
(
struct
kvm_run
*
run
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
);
void
handle_pmio
(
struct
kvm_run
*
run
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
);
void
handle_mmio
(
struct
kvm_run
*
run
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
);
void
handle_hypercall
(
uint32_t
code
,
uint8_t
*
shared_buf
,
uint8_t
*
mem
);
void
handle_hypercall_console
(
uint8_t
*
shared_buf
,
uint8_t
*
mem
);
void
handle_hypercall_timer
(
uint8_t
*
shared_buf
);
void
handle_hypercall_gfx_init
(
uint8_t
*
shared_buf
);
#endif // !_STATES_H_
This diff is collapsed.
Click to expand it.
vmm/vmm_main.c
+
9
−
48
View file @
d309cb2c
...
...
@@ -12,7 +12,7 @@
#include
<sys/stat.h>
#include
<sys/types.h>
#include
"
states
.h"
#include
"
handler
.h"
#include
"shared/hypercall_params.h"
// -- DEFINE --
...
...
@@ -96,8 +96,7 @@ int main(int argc, char* argv[])
if
(
bytes_read
<
0
)
err
(
1
,
"Error reading guestOS binary file"
);
// Check if all bytes were read
if
(
bytes_read
!=
st
.
st_size
)
err
(
1
,
"Error: Only %ld of %ld bytes read from file
\n
"
,
bytes_read
,
st
.
st_size
);
if
(
bytes_read
!=
st
.
st_size
)
err
(
1
,
"Error: Only %ld of %ld bytes read from file
\n
"
,
bytes_read
,
st
.
st_size
);
// Close the file descriptor
close
(
binfd
);
...
...
@@ -142,56 +141,18 @@ int main(int argc, char* argv[])
bool
done
=
false
;
while
(
!
done
)
{
if
(
ioctl
(
vcpufd
,
KVM_RUN
,
NULL
)
==
-
1
)
err
(
1
,
"KVM_RUN"
);
// handle VM exits (blocking call)
switch
(
run
->
exit_reason
)
{
case
KVM_EXIT_HLT
:
// "halt" CPU instruction
puts
(
"KVM_EXIT_HLT"
);
break
;
case
KVM_EXIT_IO
:
// Encountered a PMIO VMexit
if
(
run
->
io
.
direction
==
KVM_EXIT_IO_OUT
)
{
uint8_t
*
addr
=
(
uint8_t
*
)
run
+
run
->
io
.
data_offset
;
uint8_t
code
=
*
(
uint8_t
*
)
addr
;
switch
(
code
)
{
case
1
:
// console
hyper_virtual_console_params_t
*
p_consol
=
(
hyper_virtual_console_params_t
*
)
shared_buf
;
printf
(
"%s
\n
"
,
p_consol
->
msg
+
mem
);
break
;
case
2
:
// timer
hyper_timer_sleep_params_t
*
p_timer
=
(
hyper_timer_sleep_params_t
*
)
shared_buf
;
printf
(
"waiting %dus
\n
"
,
p_timer
->
us
);
sleep
(
p_timer
->
us
/
1e6
);
done
=
true
;
break
;
}
}
if
(
ioctl
(
vcpufd
,
KVM_RUN
,
NULL
)
==
-
1
)
err
(
1
,
"KVM_RUN"
);
break
;
state_handler_t
handler
=
STATE_HANDLERS
[
run
->
exit_reason
]
;
case
KVM_EXIT_MMIO
:
// Encountered a MMIO VMexit
if
(
handler
)
{
// !TODO!
break
;
handler
(
run
,
shared_buf
,
mem
);
}
else
{
// handle errors
case
KVM_EXIT_SHUTDOWN
:
case
KVM_EXIT_FAIL_ENTRY
:
case
KVM_EXIT_INTERNAL_ERROR
:
default
:
errx
(
1
,
"exit_reason = 0x%x"
,
run
->
exit_reason
);
done
=
true
;
break
;
errx
(
1
,
"exit_reason = 0x%x"
,
run
->
exit_reason
);
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment