77
|
1 |
import ctypes
|
|
2 |
import qemu
|
|
3 |
import sys
|
|
4 |
#import SyborgModule
|
|
5 |
|
|
6 |
class syborg_graphicsdevice(qemu.devclass):
|
|
7 |
# Graphics device registers derived from VirtualVideoInterfaceConstants.h
|
|
8 |
VVI_R_ID = 0x0000
|
|
9 |
VVI_R_IRQ_ENABLE = 0x0004
|
|
10 |
VVI_R_IRQ_STATUS = 0x0008
|
|
11 |
VVI_R_COMMAND = 0x000c
|
|
12 |
VVI_R_PARAMETER_LOAD = 0x0010
|
|
13 |
VVI_R_ERROR = 0x0014
|
|
14 |
VVI_R_INPUT_BUFFER_TAIL = 0x0018
|
|
15 |
VVI_R_INPUT_BUFFER_HEAD = 0x001c
|
|
16 |
VVI_R_INPUT_BUFFER_READ_COUNT = 0x0020
|
|
17 |
VVI_R_INPUT_BUFFER_WRITE_COUNT = 0x0024
|
|
18 |
VVI_R_INPUT_BUFFER_MAX_TAIL = 0x0028
|
|
19 |
VVI_R_REQUEST_ID = 0x002c
|
|
20 |
VVI_R_SHARED_CMD_MEMORY_BASE = 0x0030
|
|
21 |
VVI_R_SHARED_FRAMEBUFFER_MEMORY_BASE = 0x0034
|
|
22 |
VVI_R_LASTREG = 0x0038 # not a register, address of last register
|
|
23 |
|
|
24 |
VVI_EXECUTE = 0
|
|
25 |
shared_cmd_memory_base = 0
|
|
26 |
shared_framebuffer_memory_base = 0
|
|
27 |
m_request_id_reg = 0
|
|
28 |
|
|
29 |
# Memory base id's from SyborgModule.h
|
|
30 |
# SYBORG_CMDMEMBASE = 0
|
|
31 |
# SYBORG_FRAMEBUFFERMEMBASE = 1
|
|
32 |
|
|
33 |
class DllLoadExeption( Exception ):
|
|
34 |
def __init__(self,value):
|
|
35 |
self.value = value
|
|
36 |
|
|
37 |
def __str__(self):
|
|
38 |
return repr(self.value)
|
|
39 |
|
|
40 |
class SyborgGraphicsWrapper():
|
|
41 |
def __init__(self):
|
|
42 |
try:
|
|
43 |
self.library = ctypes.CDLL("syborg-graphicswrapper.dll")
|
|
44 |
except:
|
|
45 |
raise syborg_graphicsdevice.DllLoadExeption(1)
|
|
46 |
self.obj = self.library.create_SyborgGraphicsWrapper()
|
|
47 |
|
|
48 |
def initialize_graphics_utils(self):
|
|
49 |
self.library.initialize_SyborgGraphicsWrapper( self.obj )
|
|
50 |
|
|
51 |
def create(self):
|
|
52 |
try:
|
|
53 |
self.graphicsutils = self.SyborgGraphicsWrapper()
|
|
54 |
except syborg_graphicsdevice.DllLoadExeption:
|
|
55 |
#print "syborg_graphicsdevice: Graphics dll load failed"
|
|
56 |
sys.exit("syborg_graphicsdevice: Graphics dll load failed")
|
|
57 |
|
|
58 |
|
|
59 |
self.graphicsutils.initialize_graphics_utils()
|
|
60 |
self.initialize_graphics_callback()
|
|
61 |
# deliver the graphics ram region
|
|
62 |
# self.gmembase = self.graphicsutils.library.get_membase()
|
|
63 |
|
|
64 |
self.irqenable = 0
|
|
65 |
self.irqstatus = 0
|
|
66 |
self.command = 0
|
|
67 |
self.parameterload = 0
|
|
68 |
|
|
69 |
def updateIrq(self,new_value):
|
|
70 |
self.set_irq_level(0, new_value)
|
|
71 |
|
|
72 |
def graphics_request_callback(self, request_id):
|
|
73 |
#print "graphics_request_callback: " , request_id
|
|
74 |
self.m_request_id_reg = request_id
|
|
75 |
self.updateIrq(1)
|
|
76 |
return 0
|
|
77 |
|
|
78 |
def initialize_graphics_callback(self):
|
|
79 |
self.CALLBACKFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
|
|
80 |
self.graphics_callback = self.CALLBACKFUNC(self.graphics_request_callback)
|
|
81 |
self.graphicsutils.library.set_GraphicsCallBack( self.graphicsutils.obj, self.graphics_callback )
|
|
82 |
|
|
83 |
def read_reg(self, offset):
|
|
84 |
offset >>= 2
|
|
85 |
if offset == self.VVI_R_ID:
|
|
86 |
return 0xDEADBEEF
|
|
87 |
elif offset == self.VVI_R_IRQ_ENABLE:
|
|
88 |
return self.irqenable
|
|
89 |
elif offset == self.VVI_R_IRQ_STATUS:
|
|
90 |
return self.irqstatus
|
|
91 |
elif offset == self.VVI_R_COMMAND:
|
|
92 |
return self.command
|
|
93 |
elif offset == self.VVI_R_PARAMETER_LOAD:
|
|
94 |
return self.parameterload
|
|
95 |
elif offset == self.VVI_R_ERROR:
|
|
96 |
self.lasterror = 0
|
|
97 |
return self.lasterror
|
|
98 |
elif offset == self.VVI_R_INPUT_BUFFER_TAIL:
|
|
99 |
return self.graphicsutils.library.get_InputBufferTail( self.graphicsutils.obj )
|
|
100 |
elif offset == self.VVI_R_INPUT_BUFFER_HEAD:
|
|
101 |
return self.graphicsutils.library.get_InputBufferHead( self.graphicsutils.obj )
|
|
102 |
elif offset == self.VVI_R_INPUT_BUFFER_READ_COUNT:
|
|
103 |
return self.graphicsutils.library.get_InputBufferReadCount( self.graphicsutils.obj )
|
|
104 |
elif offset == self.VVI_R_INPUT_BUFFER_WRITE_COUNT:
|
|
105 |
return self.graphicsutils.library.get_InputBufferWriteCount( self.graphicsutils.obj )
|
|
106 |
elif offset == self.VVI_R_INPUT_BUFFER_MAX_TAIL:
|
|
107 |
return self.graphicsutils.library.get_InputMaxTailIndex( self.graphicsutils.obj )
|
|
108 |
elif offset == self.VVI_R_REQUEST_ID:
|
|
109 |
return self.m_request_id_reg
|
|
110 |
elif offset == self.VVI_R_SHARED_CMD_MEMORY_BASE:
|
|
111 |
return self.shared_cmd_memory_base
|
|
112 |
elif offset == self.VVI_R_SHARED_FRAMEBUFFER_MEMORY_BASE:
|
|
113 |
return self.shared_framebuffer_memory_base
|
|
114 |
else:
|
|
115 |
reg_read_error = "syborg_graphicsdevice: Illegal register read at: ", offset
|
|
116 |
sys.exit( reg_read_error )
|
|
117 |
|
|
118 |
def write_reg(self, offset, value):
|
|
119 |
offset >>= 2
|
|
120 |
if offset == self.VVI_R_IRQ_STATUS:
|
|
121 |
self.updateIrq(0);
|
|
122 |
self.graphicsutils.library.signal_outputbuffer_semafore( self.graphicsutils.obj )
|
|
123 |
self.graphicsutils.library.execute_command( self.graphicsutils.obj );
|
|
124 |
elif offset == self.VVI_R_COMMAND:
|
|
125 |
if value == self.VVI_EXECUTE:
|
|
126 |
self.graphicsutils.library.execute_command( self.graphicsutils.obj );
|
|
127 |
else:
|
|
128 |
sys.exit("syborg_graphicsdevice: Unknown command issued!")
|
|
129 |
elif offset == self.VVI_R_INPUT_BUFFER_TAIL:
|
|
130 |
self.graphicsutils.library.set_InputBufferTail( self.graphicsutils.obj, value );
|
|
131 |
elif offset == self.VVI_R_INPUT_BUFFER_HEAD:
|
|
132 |
self.graphicsutils.library.set_InputBufferHead( self.graphicsutils.obj, value );
|
|
133 |
elif offset == self.VVI_R_INPUT_BUFFER_READ_COUNT:
|
|
134 |
self.graphicsutils.library.set_InputBufferReadCount( self.graphicsutils.obj, value );
|
|
135 |
elif offset == self.VVI_R_INPUT_BUFFER_WRITE_COUNT:
|
|
136 |
self.graphicsutils.library.set_InputBufferWriteCount( self.graphicsutils.obj, value );
|
|
137 |
elif offset == self.VVI_R_INPUT_BUFFER_MAX_TAIL:
|
|
138 |
self.graphicsutils.library.set_InputMaxTailIndex( self.graphicsutils.obj, value );
|
|
139 |
elif offset == self.VVI_R_SHARED_CMD_MEMORY_BASE:
|
|
140 |
gmemsize = self.graphicsutils.library.get_cmd_memsize()
|
|
141 |
self.cmd_memregion = qemu.memregion( value, gmemsize )
|
|
142 |
self.memregion_cmd_base = self.cmd_memregion.region_host_addr()
|
|
143 |
#SyborgModule.post_address( self.memregion_cmd_base, self.SYBORG_CMDMEMBASE )
|
|
144 |
elif offset == self.VVI_R_SHARED_FRAMEBUFFER_MEMORY_BASE:
|
|
145 |
gmemsize = self.graphicsutils.library.get_framebuffer_memsize()
|
|
146 |
self.framebuffer_memregion = qemu.memregion( value, gmemsize )
|
|
147 |
self.memregion_framebuffer_base = self.framebuffer_memregion.region_host_addr()
|
|
148 |
#SyborgModule.post_address( self.memregion_framebuffer_base, self.SYBORG_FRAMEBUFFERMEMBASE )
|
|
149 |
# Ready to finalise graphics initialization
|
|
150 |
if( self.graphicsutils.library.reset_SyborgGraphicsWrapper( self.graphicsutils.obj, self.memregion_framebuffer_base, self.memregion_cmd_base ) != 0 ):
|
|
151 |
sys.exit("syborg_graphicsdevice: Syborg graphicsutils library not initialized correctly!")
|
|
152 |
else:
|
|
153 |
reg_write_error = "syborg_graphicsdevice: Illegal register write to: ", offset
|
|
154 |
sys.exit( reg_write_error )
|
|
155 |
|
|
156 |
# Device class properties
|
|
157 |
regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)]
|
|
158 |
irqs = 1
|
|
159 |
name = "syborg,graphicsdevice"
|
|
160 |
properties = {}
|
|
161 |
|
|
162 |
qemu.register_device(syborg_graphicsdevice)
|