1 | #!/usr/bin/env python |
---|
2 | |
---|
3 | ####################################################################################### |
---|
4 | # file : giet_mapping.py |
---|
5 | # date : april 2014 |
---|
6 | # author : Alain Greiner |
---|
7 | ####################################################################################### |
---|
8 | # This file contains the classes required to define a generic mapping in python |
---|
9 | # for the GIET_VM. |
---|
10 | # - A 'Mapping' contains + various structural constants, |
---|
11 | # + a 'Cluster' set, (hardware architecture) |
---|
12 | # + a 'Vseg' set, (kernel virtual segments mapping) |
---|
13 | # + a 'Vspace' set (several user applications). |
---|
14 | # - A 'Cluster' contains + coordinates (x,y), |
---|
15 | # + a 'Pseg' set, (all physical segments in cluster) |
---|
16 | # + a 'Proc' set, (processors in cluster) |
---|
17 | # + a 'Peripheral' set (peripherals in cluster) |
---|
18 | # - A 'Vspace' contains + a 'Vseg' set, (user virtual segments mapping) |
---|
19 | # + a 'Task' set (user tasks mapping) |
---|
20 | #################################################################################### |
---|
21 | |
---|
22 | ######################### |
---|
23 | class Mapping( object ): |
---|
24 | ######################### |
---|
25 | def __init__( self, |
---|
26 | name, # mapping name |
---|
27 | x_size, # number of clusters in a row |
---|
28 | y_size, # number of clusters in a column |
---|
29 | nb_procs, # max number of processors per cluster |
---|
30 | x_width = 4, # number of bits encoding x coordinate |
---|
31 | y_width = 4, # number of bits encoding y coordinate |
---|
32 | paddr_width = 32, # number of bits for physical address |
---|
33 | coherence = False, # hardware cache coherence |
---|
34 | irq_per_proc = 1, # number or IRQ lines from XCU to processor |
---|
35 | use_ram_disk = False, # architecture contains ram_disk when true |
---|
36 | x_io = 0, # cluster_io x coordinate |
---|
37 | y_io = 0 ): # cluster_io y coordinate |
---|
38 | |
---|
39 | self.name = name |
---|
40 | self.paddr_width = paddr_width |
---|
41 | self.coherence = coherence |
---|
42 | self.x_size = x_size |
---|
43 | self.y_size = y_size |
---|
44 | self.x_width = x_width |
---|
45 | self.y_width = y_width |
---|
46 | self.irq_per_proc = irq_per_proc |
---|
47 | self.nb_procs = nb_procs |
---|
48 | self.use_ram_disk = use_ram_disk |
---|
49 | self.x_io = x_io |
---|
50 | self.y_io = y_io |
---|
51 | |
---|
52 | self.total_procs = 0 |
---|
53 | self.total_globs = 0 |
---|
54 | |
---|
55 | # clusters array |
---|
56 | self.clusters = [] |
---|
57 | for x in xrange (1<<x_width): |
---|
58 | for y in xrange (1<<y_width): |
---|
59 | self.clusters.append( Cluster(x,y) ) |
---|
60 | |
---|
61 | # globals array |
---|
62 | self.globs = [] |
---|
63 | |
---|
64 | # vspace array |
---|
65 | self.vspaces = [] |
---|
66 | |
---|
67 | return |
---|
68 | |
---|
69 | ########################## |
---|
70 | def addPseg( self, pseg ): |
---|
71 | cluster_xy = pseg.base >> (self.paddr_width - self.x_width - self.y_width) |
---|
72 | x = cluster_xy >> (self.y_width); |
---|
73 | y = cluster_xy & ((1 << self.y_width) - 1) |
---|
74 | if (x >= self.x_size) or (y >= self.y_size): |
---|
75 | print '(x,y) coordinates too large for pdeg %s' % str(pseg) |
---|
76 | self.clusters[cluster_xy].psegs.append( pseg ) |
---|
77 | return |
---|
78 | |
---|
79 | ###################################### |
---|
80 | def addPeripheral( self, peripheral ): |
---|
81 | cluster_xy = peripheral.pseg.base >> (self.paddr_width - self.x_width - self.y_width) |
---|
82 | x = cluster_xy >> (self.y_width); |
---|
83 | y = cluster_xy & ((1 << self.y_width) - 1) |
---|
84 | if (x >= self.x_size) or (y >= self.y_size): |
---|
85 | print '(x,y) coordinates too large for pdeg %s' % str(pseg) |
---|
86 | self.clusters[cluster_xy].peripherals.append( peripheral ) |
---|
87 | return |
---|
88 | |
---|
89 | ########################### |
---|
90 | def addProc ( self, proc ): |
---|
91 | cluster_xy = (proc.x << self.y_width) + proc.y |
---|
92 | self.clusters[cluster_xy].procs.append( proc ) |
---|
93 | self.total_procs += 1 |
---|
94 | if (proc.x >= self.x_size) or (proc.y >= self.y_size): |
---|
95 | print '(x,y) coordinates too large for node %s' % str(proc) |
---|
96 | return |
---|
97 | |
---|
98 | ############################ |
---|
99 | def addGlobal( self, vseg ): |
---|
100 | self.globs.append( vseg ) |
---|
101 | return |
---|
102 | |
---|
103 | ############################## |
---|
104 | def addVspace( self, vspace ): |
---|
105 | self.vspaces.append( vspace ) |
---|
106 | return |
---|
107 | |
---|
108 | #################### |
---|
109 | def __str__( self ): # xml generation for mapping |
---|
110 | s = '<?xml version="1.0"?>\n\n' |
---|
111 | s += '<mapping_info signature = "0xDACE2014"\n' |
---|
112 | s += ' name = "%s"\n' % (self.name) |
---|
113 | s += ' x_size = "%d"\n' % (self.x_size) |
---|
114 | s += ' y_size = "%d"\n' % (self.y_size) |
---|
115 | s += ' x_width = "%d"\n' % (self.x_width) |
---|
116 | s += ' y_width = "%d"\n' % (self.y_width) |
---|
117 | s += ' irq_per_proc = "%d"\n' % (self.irq_per_proc) |
---|
118 | s += ' use_ram_disk = "%d"\n' % (self.use_ram_disk) |
---|
119 | s += ' x_io = "%d"\n' % (self.x_io) |
---|
120 | s += ' y_io = "%d" >\n' % (self.y_io) |
---|
121 | s += ' <clusterset>\n' |
---|
122 | for x in xrange ( self.x_size ): |
---|
123 | for y in xrange ( self.y_size ): |
---|
124 | cluster_xy = (x << self.y_width) + y |
---|
125 | s += str( self.clusters[cluster_xy] ) |
---|
126 | s += ' </clusterset>\n' |
---|
127 | s += ' <globalset>\n' |
---|
128 | for vseg in self.globs: |
---|
129 | s += str ( vseg ) |
---|
130 | s += ' </globalset>\n' |
---|
131 | s += ' <vspaceset>\n' |
---|
132 | for vspace in self.vspaces: |
---|
133 | s += str( vspace ) |
---|
134 | s += ' </vspaceset>\n' |
---|
135 | s += '</mapping_info>\n' |
---|
136 | return s |
---|
137 | |
---|
138 | ####################### |
---|
139 | class Vspace( object ): |
---|
140 | ####################### |
---|
141 | def __init__( self, name, startname ): |
---|
142 | self.name = name # application name |
---|
143 | self.startname = startname # name of vobj containing the start_vector |
---|
144 | self.vsegs = [] |
---|
145 | self.tasks = [] |
---|
146 | return |
---|
147 | ########################## |
---|
148 | def addTask( self, task ): |
---|
149 | self.tasks.append( task ) |
---|
150 | return |
---|
151 | |
---|
152 | ########################## |
---|
153 | def addVseg( self, vseg ): |
---|
154 | self.vsegs.append( vseg ) |
---|
155 | return |
---|
156 | |
---|
157 | #################### |
---|
158 | def __str__( self ): # xml for one vspace |
---|
159 | s = ' <vspace name="%s" startname="%s" >\n' % ( self.name, self.startname ) |
---|
160 | for vseg in self.vsegs: |
---|
161 | s += str( vseg ) |
---|
162 | for task in self.tasks: |
---|
163 | s += str( task ) |
---|
164 | s += ' </vspace>\n' |
---|
165 | return s |
---|
166 | |
---|
167 | ##################### |
---|
168 | class Task( object ): |
---|
169 | ##################### |
---|
170 | def __init__( self, name, trdid, x, y, p, stackname, heapname, startid, \ |
---|
171 | usetty = False, usenic = False, usehba = False ): |
---|
172 | self.name = name # thread name |
---|
173 | self.trdid = trdid # thread index (unique in vspace) |
---|
174 | self.x = x # processor x coordinate |
---|
175 | self.y = y # processor y coordinate |
---|
176 | self.p = p # processor local index |
---|
177 | self.stackname = stackname # name of vobj containing the stack |
---|
178 | self.heapname = heapname # name of vobj containing the heap |
---|
179 | self.startid = startid # index in start_vector |
---|
180 | self.usetty = usetty # request a private TTY channel |
---|
181 | self.usenic = usenic # request a private NIC channel |
---|
182 | self.usehba = usehba # request a private HBA channel |
---|
183 | return |
---|
184 | |
---|
185 | #################### |
---|
186 | def __str__( self ): # xml for one task |
---|
187 | s = ' <task name="%s" trdid="%d" x="%d" y="%d" p="%d" stackname="%s" heapname="%s" startid="%d"' \ |
---|
188 | % (self.name, self.trdid, self.x, self.y, self.p, self.stackname, self.heapname, self.startid) |
---|
189 | if self.usetty != 0: |
---|
190 | s += ' usetty="1"' |
---|
191 | if self.usenic != 0: |
---|
192 | s += ' usenic="1"' |
---|
193 | if self.usehba != 0: |
---|
194 | s += ' usehba="1"' |
---|
195 | s += ' />\n' |
---|
196 | return s |
---|
197 | |
---|
198 | ###################### |
---|
199 | class Vseg( object ): |
---|
200 | ###################### |
---|
201 | def __init__( self, name, vbase, mode, x, y, psegname, ident = False ): |
---|
202 | assert mode in ['CXWU','CXW_','CX_U','CX__', |
---|
203 | 'C_WU','C_W_','C__U','C___', |
---|
204 | '_XWU','_XW_','_X_U','_X__', |
---|
205 | '__WU','__W_','___U','____'] |
---|
206 | self.name = name |
---|
207 | self.vbase = vbase |
---|
208 | self.mode = mode |
---|
209 | self.x = x |
---|
210 | self.y = y |
---|
211 | self.psegname = psegname |
---|
212 | self. ident = ident |
---|
213 | self.vobjs = [] |
---|
214 | return |
---|
215 | |
---|
216 | ##################### |
---|
217 | def add ( self, vo ): |
---|
218 | self.vobjs.append( vo ) |
---|
219 | return |
---|
220 | |
---|
221 | #################### |
---|
222 | def __str__( self ): # xml for one vseg |
---|
223 | s = ' <vseg name="%s" vbase="0x%x" mode="%s" x="%d" y="%d" psegname="%s"' \ |
---|
224 | % ( self.name, self.vbase, self.mode, self.x, self.y, self.psegname ) |
---|
225 | if self.ident != 0: |
---|
226 | s += ' ident="1"' |
---|
227 | s += ' >\n' |
---|
228 | for vobj in self.vobjs: |
---|
229 | s += str( vobj ) |
---|
230 | s += ' </vseg>\n' |
---|
231 | return s |
---|
232 | |
---|
233 | ###################### |
---|
234 | class Vobj( object ): |
---|
235 | ###################### |
---|
236 | def __init__( self, name, length, vtype, binpath = None, align = 0, init = 0 ): |
---|
237 | assert vtype in ['ELF','BLOB','PTAB','PERI','MWMR','LOCK', \ |
---|
238 | 'BUFFER','BARRIER','CONST','MEMSPACE','SCHED'] |
---|
239 | self.name = name |
---|
240 | self.vtype = vtype |
---|
241 | self.length = length |
---|
242 | self.binpath = binpath |
---|
243 | self.align = align |
---|
244 | self.init = init |
---|
245 | return |
---|
246 | |
---|
247 | #################### |
---|
248 | def __str__( self ): # xml for a vobj |
---|
249 | s = ' <vobj name="%s" type="%s" length="0x%x"' \ |
---|
250 | % ( self.name, self.vtype, self.length ) |
---|
251 | if (self.binpath != None): |
---|
252 | s += ' binpath="%s"' % (self.binpath) |
---|
253 | if (self.align != 0): |
---|
254 | s += ' align="%d"' % (self.align) |
---|
255 | if (self.init != 0): |
---|
256 | s += ' init="%d"' % (self.init) |
---|
257 | s += ' />\n' |
---|
258 | return s |
---|
259 | |
---|
260 | ######################### |
---|
261 | class Cluster ( object ): |
---|
262 | ######################### |
---|
263 | def __init__( self, x, y ): |
---|
264 | self.x = x |
---|
265 | self.y = y |
---|
266 | self.psegs = [] |
---|
267 | self.peripherals = [] |
---|
268 | self.procs = [] |
---|
269 | return |
---|
270 | |
---|
271 | #################### |
---|
272 | def __str__( self ): # xml for a cluster |
---|
273 | s = ' <cluster x="%d" y="%d" >\n' % (self.x, self.y) |
---|
274 | for pseg in self.psegs: |
---|
275 | s += str( pseg ) # psegs type RAM |
---|
276 | for peri in self.peripherals: |
---|
277 | s += str(peri.pseg) # psegs type PERI |
---|
278 | for proc in self.procs: |
---|
279 | s += str( proc ) # processors |
---|
280 | for peri in self.peripherals: |
---|
281 | s += str( peri ) # peripherals |
---|
282 | s += ' </cluster>\n' |
---|
283 | return s |
---|
284 | |
---|
285 | ########################### |
---|
286 | class Processor ( object ): |
---|
287 | ########################### |
---|
288 | def __init__( self, x, y, lpid ): |
---|
289 | self.x = x |
---|
290 | self.y = y |
---|
291 | self.lpid = lpid |
---|
292 | return |
---|
293 | |
---|
294 | #################### |
---|
295 | def __str__( self ): # xml for a processor |
---|
296 | return ' <proc index="%d" />\n' % (self.lpid) |
---|
297 | |
---|
298 | ###################### |
---|
299 | class Pseg ( object ): |
---|
300 | ###################### |
---|
301 | def __init__( self, name, base, size, segtype ): |
---|
302 | self.name = name |
---|
303 | self.base = base |
---|
304 | self.size = size |
---|
305 | self.segtype = segtype |
---|
306 | assert segtype in ['RAM','PERI'] |
---|
307 | return |
---|
308 | |
---|
309 | #################### |
---|
310 | def __str__( self ): # xml for a pseg |
---|
311 | return ' <pseg name="%s" type="%s" base="0x%x" length="0x%x" />\n' \ |
---|
312 | % (self.name, self.segtype, self.base, self.size) |
---|
313 | |
---|
314 | ############################ |
---|
315 | class Peripheral ( object ): |
---|
316 | ############################ |
---|
317 | def __init__( self, name, base, size, ptype, subtype, channels = 1): |
---|
318 | self.channels = channels |
---|
319 | self.ptype = ptype |
---|
320 | self.subtype = subtype |
---|
321 | self.pseg = Pseg( name, base, size, 'PERI' ) |
---|
322 | return |
---|
323 | |
---|
324 | #################### |
---|
325 | def __str__( self ): # xml for a peripheral |
---|
326 | s = ' <periph type="%s" subtype="%s" psegname="%s" channels="%d" >\n' \ |
---|
327 | % ( self.ptype, self.subtype, self.pseg.name, self.channels ) |
---|
328 | if ( self.ptype == 'PIC' ): |
---|
329 | for i in self.irqs: |
---|
330 | s += str( i ) # picIrq |
---|
331 | if ( (self.ptype == 'XCU') or (self.ptype == 'ICU') ): |
---|
332 | for i in self.irqs: |
---|
333 | s += str( i ) # xcuIrq |
---|
334 | s += ' </periph>\n' |
---|
335 | return s |
---|
336 | |
---|
337 | ######################## |
---|
338 | class Tty( Peripheral ): |
---|
339 | ######################## |
---|
340 | def __init__( self, name, base, size, channels ): |
---|
341 | Peripheral.__init__( self, name, base, size, 'TTY', 'NONE', channels ) |
---|
342 | return |
---|
343 | |
---|
344 | ######################## |
---|
345 | class Dma( Peripheral ): |
---|
346 | ######################## |
---|
347 | def __init__( self, name, base, size, channels ): |
---|
348 | Peripheral.__init__( self, name, base, size, 'DMA', 'NONE', channels ) |
---|
349 | return |
---|
350 | |
---|
351 | ######################## |
---|
352 | class Bdv( Peripheral ): |
---|
353 | ######################## |
---|
354 | def __init__( self, name, base, size ): |
---|
355 | Peripheral.__init__( self, name, base, size, 'IOC', 'BDV' ) |
---|
356 | return |
---|
357 | |
---|
358 | ######################## |
---|
359 | class Spi( Peripheral ): |
---|
360 | ######################## |
---|
361 | def __init__( self, name, base, size ): |
---|
362 | Peripheral.__init__( self, name, base, size, 'IOC', 'SPI' ) |
---|
363 | return |
---|
364 | |
---|
365 | ######################## |
---|
366 | class Hba( Peripheral ): |
---|
367 | ######################## |
---|
368 | def __init__( self, name, base, size, channels ): |
---|
369 | Peripheral.__init__( self, name, base, size, 'IOC', 'HBA', channels ) |
---|
370 | return |
---|
371 | |
---|
372 | ######################## |
---|
373 | class Nic( Peripheral ): |
---|
374 | ######################## |
---|
375 | def __init__( self, name, base, size, channels ): |
---|
376 | Peripheral.__init__( self, name, base, size, 'NIC', 'NONE', channels ) |
---|
377 | return |
---|
378 | |
---|
379 | ######################## |
---|
380 | class Cma( Peripheral ): |
---|
381 | ######################## |
---|
382 | def __init__( self, name, base, size, channels ): |
---|
383 | Peripheral.__init__( self, name, base, size, 'CMA', 'NONE', channels ) |
---|
384 | return |
---|
385 | |
---|
386 | ######################## |
---|
387 | class Fbf( Peripheral ): |
---|
388 | ######################## |
---|
389 | def __init__( self, name, base, size ): |
---|
390 | Peripheral.__init__( self, name, base, size, 'FBF', 'NONE' ) |
---|
391 | return |
---|
392 | |
---|
393 | ######################## |
---|
394 | class Tim( Peripheral ): |
---|
395 | ######################## |
---|
396 | def __init__( self, name, base, size, channels ): |
---|
397 | Peripheral.__init__( self, name, base, size, 'TIM', 'NONE', channels ) |
---|
398 | return |
---|
399 | |
---|
400 | ######################## |
---|
401 | class Iob( Peripheral ): |
---|
402 | ######################## |
---|
403 | def __init__( self, name, base, size ): |
---|
404 | Peripheral.__init__( self, name, base, size, 'IOB', 'NONE' ) |
---|
405 | return |
---|
406 | |
---|
407 | ######################## |
---|
408 | class Rom( Peripheral ): |
---|
409 | ######################## |
---|
410 | def __init__( self, name, base, size ): |
---|
411 | Peripheral.__init__( self, name, base, size, 'ROM', 'NONE' ) |
---|
412 | return |
---|
413 | |
---|
414 | ######################## |
---|
415 | class Mmc( Peripheral ): |
---|
416 | ######################## |
---|
417 | def __init__( self, name, base, size ): |
---|
418 | Peripheral.__init__( self, name, base, size, 'MMC', 'NONE' ) |
---|
419 | return |
---|
420 | |
---|
421 | ######################## |
---|
422 | class Xcu( Peripheral ): |
---|
423 | ######################## |
---|
424 | def __init__( self, name, base, size, channels ): |
---|
425 | Peripheral.__init__( self, name, base, size, 'XCU', 'NONE', channels ) |
---|
426 | self.irqs = [] |
---|
427 | return |
---|
428 | |
---|
429 | def add ( self, irq ): |
---|
430 | self.irqs.append( irq ) |
---|
431 | return |
---|
432 | |
---|
433 | ######################## |
---|
434 | class Icu( Peripheral ): |
---|
435 | ######################## |
---|
436 | def __init__( self, name, base, size, channels ): |
---|
437 | Peripheral.__init__( self, name, base, size, 'ICU', 'NONE', channels ) |
---|
438 | self.irqs = [] |
---|
439 | return |
---|
440 | |
---|
441 | ###################### |
---|
442 | def add ( self, irq ): |
---|
443 | self.irqs.append( irq ) |
---|
444 | return |
---|
445 | |
---|
446 | ######################## |
---|
447 | class Pic( Peripheral ): |
---|
448 | ######################## |
---|
449 | def __init__( self, name, base, size, channels ): |
---|
450 | Peripheral.__init__( self, name, base, size, 'PIC', 'NONE', channels ) |
---|
451 | self.irqs = [] |
---|
452 | return |
---|
453 | |
---|
454 | ###################### |
---|
455 | def add ( self, irq ): |
---|
456 | self.irqs.append( irq ) |
---|
457 | return |
---|
458 | |
---|
459 | ######################## |
---|
460 | class XcuIrq ( object ): |
---|
461 | ######################## |
---|
462 | def __init__( self, srctype, srcid, isrtype, channel = 0, dstid = 0 ): |
---|
463 | assert srctype in ['HWI','WTI','PTI'] |
---|
464 | assert isrtype in ['ISR_DEFAULT','ISR_TICK','ISR_TTY_RX','ISR_TTY_TX', |
---|
465 | 'ISR_BDV', 'ISR_TIMER', 'ISR_WAKUP', 'ISR_NIC_RX', |
---|
466 | 'ISR_NIC_TX','ISR_CMA','ISR_MMC'] |
---|
467 | assert srcid < 32 |
---|
468 | self.srctype = srctype |
---|
469 | self.srcid = srcid |
---|
470 | self.isrtype = isrtype |
---|
471 | self.channel = channel |
---|
472 | self.dstid = dstid |
---|
473 | return |
---|
474 | |
---|
475 | #################### |
---|
476 | def __str__( self ): # xml for an xcuIrq |
---|
477 | s = ' <irq srctype="%s" srcid="%d" isr="%s" channel="%d" dstid="%d" />\n' \ |
---|
478 | % (self.srctype, self.srcid, self.isrtype, self.channel, self.dstid) |
---|
479 | return s |
---|
480 | |
---|
481 | ######################## |
---|
482 | class PicIrq ( object ): |
---|
483 | ######################## |
---|
484 | def __init__( self, srcid, dstx, dsty, dstid ): |
---|
485 | assert srcid < 32 |
---|
486 | self.srcid = srcid |
---|
487 | self.dstx = dstx |
---|
488 | self.dsty = dsty |
---|
489 | self.dstid = dstid |
---|
490 | return |
---|
491 | |
---|
492 | #################### |
---|
493 | def __str__( self ): # xml for a picIrq |
---|
494 | s = ' <irq srcid="%d" dstx="%d" dsty="%d" dstid="%d" />\n' \ |
---|
495 | % (self.srcid, self.dstx, self.dsty, self.dstid) |
---|
496 | return s |
---|
497 | |
---|
498 | |
---|
499 | # Local Variables: |
---|
500 | # tab-width: 4; |
---|
501 | # c-basic-offset: 4; |
---|
502 | # c-file-offsets:((innamespace . 0)(inline-open . 0)); |
---|
503 | # indent-tabs-mode: nil; |
---|
504 | # End: |
---|
505 | # |
---|
506 | # vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 |
---|
507 | |
---|