|
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) |