Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / pfe / src / SS_Python.i
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_Python.i
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23
24%{
25#include "SS_Node.h"
26#include "SS_Model.h"
27#include "SS_Registers.h"
28#include "SS_Strand.h"
29#include "SS_Io.h"
30#include "SS_Tte.h"
31#include "SS_SnapShot.h"
32#include "SS_PythonTracer.h"
33#include "SS_PythonAsiReg.h"
34#include "SS_AddressMap.h"
35#include "spix_sparc.h"
36
37
38/* val2ptr() converts an integer value back to proper pointer *\
39\* that within the swig framework will get the right type. */
40
41template<class Ptr>
42Ptr* val2ptr( int64_t val )
43{
44 union
45 {
46 Ptr* ptr;
47#if defined(ARCH_V8)
48 int32_t val;
49#elif (defined(ARCH_V9) || defined(ARCH_X64))
50 int64_t val;
51#else
52#error "Define ARCH=v9 or ARCH=v8plus or ARCH=amd64"
53#endif
54 } u;
55
56 u.val = val;
57 return u.ptr;
58}
59
60%}
61
62typedef unsigned char uint8_t;
63typedef signed char int8_t;
64typedef unsigned short uint16_t;
65typedef signed short int16_t;
66typedef unsigned int uint32_t;
67typedef unsigned int uint_t;
68typedef signed int int32_t;
69#if (defined(ARCH_V9) || defined(ARCH_X64))
70typedef unsigned long uint64_t;
71typedef signed long int64_t;
72#else
73#ifdef ARCH_V8
74typedef unsigned long long uint64_t;
75typedef signed long long int64_t;
76#else
77#error "Define ARCH=v9 or ARCH=v8plus or ARCH=amd64"
78#endif
79#endif
80
81typedef int64_t SS_Vaddr;
82typedef uint64_t SS_Paddr;
83
84%typemap(python,in) PyObject *func
85{
86 if (!PyCallable_Check($input))
87 {
88 PyErr_SetString(PyExc_TypeError, "Need a callable object!");
89 return NULL;
90 }
91 $1 = $input;
92}
93
94/*============================================================================*\
95 * dis *
96\*============================================================================*/
97
98%inline %{
99/* ha144505: we need to stay away from having the uint32_t; it confuses SWIG */
100char* dis( int64_t opc, uint64_t pc )
101{
102 uint32_t _opc = uint32_t(opc);
103 static char buffer[256];
104 size_t n = spix_sparc_dis(buffer,256,spix_sparc_iop(SPIX_SPARC_V9,&_opc),&_opc,pc);
105 buffer[n] = 0;
106 return buffer;
107}
108%}
109
110/*============================================================================*\
111 * SS_Node *
112\*============================================================================*/
113
114class SS_Node
115{
116 public:
117 const char* get_node_name();
118};
119
120/*============================================================================*\
121 * SS_Registers *
122\*============================================================================*/
123
124class SS_Registers
125{
126 public:
127 enum Error
128 {
129 OK,
130 NOT_AVAILABLE
131 };
132
133 enum Index
134 {
135 INDEX_BEGIN,
136 INDEX_END,
137 ALIAS_BEGIN,
138 ALIAS_END,
139
140 PR_TT,
141 PR_TPC,
142 PR_TNPC,
143 PR_TSTATE,
144 HPR_HTSTATE
145 };
146
147 static const char* get_name( Index );
148};
149
150/*============================================================================*\
151 * SS_BreakPoint *
152\*============================================================================*/
153
154class SS_BreakPoint
155{
156 public:
157 typedef uint_t Ident;
158
159 enum Error
160 {
161 OK,
162 ID_UNKNOWN
163 };
164
165 enum Break
166 {
167 ON_INST_VA,
168 ON_INST_PA,
169 ON_INST_WORD,
170 ON_DATA_VA,
171 ON_DATA_PA,
172 ON_DATA_LOAD,
173 ON_DATA_STORE,
174 ON_TRAP,
175 ON_RED_MODE
176 };
177
178 %immutable;
179 Break type;
180 Ident id;
181 bool enabled;
182 SS_BreakPoint* next;
183
184 uint64_t va;
185 uint64_t pa;
186 uint_t tt;
187 %mutable;
188};
189
190/*============================================================================*\
191 * SS_TrapInfo *
192\*============================================================================*/
193
194class SS_TrapInfo
195{
196 public:
197 %immutable;
198 uint_t trap_type;
199 char* name;
200 uint_t priority;
201 %mutable;
202};
203
204%inline %{
205SS_TrapInfo* get_trap_info( uint_t tt ) { return &SS_Trap::table[tt]; }
206%}
207
208/*============================================================================*\
209 * SS_AsiMap *
210\*============================================================================*/
211
212class SS_AsiMap
213{
214 public:
215 %extend {
216 SS_AsiSpace* get( uint8_t asi ) { return &(self->operator[](asi)); }
217 }
218};
219
220/*============================================================================*\
221 * SS_AsiCtrReg *
222\*============================================================================*/
223
224class SS_AsiCtrReg
225{
226 public:
227 SS_AsiCtrReg( const char* __name, uint64_t __mask_ro, uint64_t __mask_r1c, uint64_t __mask_rw, uint64_t __mask_w1c, uint64_t __init );
228
229 const char* name();
230
231 uint64_t get();
232 void set( uint64_t v );
233 void set_unmasked( uint64_t v );
234
235 static SS_AsiSpace::Error ld64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* data );
236 static SS_AsiSpace::Error st64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t data );
237 static SS_AsiSpace::Error rd64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* data );
238 static SS_AsiSpace::Error wr64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t data );
239};
240
241class SS_SharedAsiCtrReg : public SS_AsiCtrReg
242{
243 public:
244 SS_SharedAsiCtrReg( const char* __name, uint64_t __mask_ro, uint64_t __mask_r1c, uint64_t __mask_rw, uint64_t __mask_w1c, uint64_t __init );
245
246 int lock();
247 int unlock();
248 int trylock();
249
250 static SS_AsiSpace::Error ld64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* data );
251 static SS_AsiSpace::Error st64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t data );
252 static SS_AsiSpace::Error rd64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t* data );
253 static SS_AsiSpace::Error wr64( SS_Node*, void*, SS_Strand*, SS_Vaddr, uint64_t data );
254};
255
256class SS_PythonAsiReg : public SS_AsiCtrReg
257{
258 public:
259 SS_PythonAsiReg();
260
261 void set_ld64( PyObject* func );
262 void clr_ld64();
263 void set_st64( PyObject* func );
264 void clr_st64();
265 void set_rd64( PyObject* func );
266 void clr_rd64();
267 void set_wr64( PyObject* func );
268 void clr_wr64();
269};
270
271
272/*============================================================================*\
273 * SS_AsiSpace *
274\*============================================================================*/
275
276class SS_AsiSpace
277{
278 public:
279 enum Error
280 {
281 OK,
282 NO_ASI,
283 NO_READ,
284 NO_WRITE
285 };
286
287 typedef Error (*Read) ( SS_Node* obj, void* reg, SS_Strand* s, SS_Vaddr, uint64_t* data );
288 typedef Error (*Write)( SS_Node* obj, void* reg, SS_Strand* s, SS_Vaddr, uint64_t data );
289
290
291 %extend {
292 void add( uint64_t lo, uint64_t hi, SS_Node* obj, void* reg, Read ld, Write st, Read rd, Write wr )
293 {
294 self->add((SS_Vaddr)lo,(SS_Vaddr)hi,obj,reg,ld,st,rd,wr);
295 }
296
297 void add_state( SS_PythonAsiReg* reg, uint64_t va )
298 {
299 self->add((SS_Vaddr)va,(SS_Vaddr)va,(SS_Node*)0,reg,
300 &SS_PythonAsiReg::ld64,&SS_PythonAsiReg::st64,
301 &SS_PythonAsiReg::rd64,&SS_PythonAsiReg::st64);
302 }
303 void add_space( SS_PythonAsiReg* reg, uint64_t lo, uint64_t hi )
304 {
305 self->add((SS_Vaddr)lo,(SS_Vaddr)hi,(SS_Node*)0,reg,
306 &SS_PythonAsiReg::ld64,&SS_PythonAsiReg::st64,
307 &SS_PythonAsiReg::rd64,&SS_PythonAsiReg::st64);
308 }
309 }
310};
311
312/*============================================================================*\
313 * SS_Access *
314\*============================================================================*/
315
316class SS_Access
317{
318 public:
319 enum Type
320 {
321 LOAD,
322 STORE,
323 STP,
324 SWAP,
325 CAS,
326 LDST
327 };
328};
329
330/*============================================================================*\
331 * SS_Tracer *
332\*============================================================================*/
333
334class SS_Tracer
335{
336 public:
337 enum TrapMode
338 {
339 TRAP,
340 INST_TRAP,
341 DATA_TRAP
342 };
343
344 enum MemAccess
345 {
346 LD_CODE,
347 ST_DATA,
348 LD_DATA,
349 ST_PART,
350 ST_SWAP,
351 LD_SWAP,
352 ST_CAS,
353 LD_CAS,
354 ST_LDST,
355 LD_LDST,
356 FLUSH,
357 PREFETCH
358 };
359};
360
361/*============================================================================*\
362 * SS_PythonTracer *
363\*============================================================================*/
364
365class SS_PythonTracer : public SS_Tracer
366{
367 public:
368 SS_PythonTracer();
369
370 void clr_exe_instr();
371 void set_exe_instr( PyObject* func );
372
373 void clr_reg_value();
374 void set_reg_value( PyObject* func );
375
376 void clr_trap();
377 void set_trap( PyObject* func );
378
379 void clr_mem_access();
380 void set_mem_access( PyObject* func );
381
382 void clr_tlb_update();
383 void set_tlb_update( PyObject* func );
384
385 void clr_end_instr();
386 void set_end_instr( PyObject* func );
387};
388
389/*============================================================================*\
390 * SS_Instr *
391\*============================================================================*/
392
393%inline %{
394/* ss_instr() is used when get an uint64_t value but need a proper
395 SS_Tte python object pointer type */
396
397SS_Instr* ss_instr( int64_t p )
398{
399 return val2ptr<SS_Instr>(p);
400}
401%}
402
403class SS_Instr
404{
405 public:
406 %extend {
407 uint32_t get_opc() { return self->opc.get(); }
408 }
409};
410
411/*============================================================================*\
412 * SS_Strand *
413\*============================================================================*/
414
415class SS_Strand
416{
417 public:
418 const char* get_node_name();
419
420 char* icache_info(uint64_t pa);
421
422 char* icache_set(uint_t set);
423
424 char* dcache_set(uint_t set);
425
426 char* l2cache_set(uint_t set);
427
428 char* l2cache_set(uint_t bank, uint_t set);
429
430 %immutable;
431 SS_Registers::Error reg_error;
432 SS_AsiSpace::Error asi_error;
433 %mutable;
434
435 %extend {
436 const char* get_state_name( SS_Registers::Index index )
437 {
438 return (self->get_state_name)(self,index);
439 }
440 uint64_t get_reg( SS_Registers::Index index )
441 {
442 uint64_t value;
443 self->reg_error = (self->get_state)(self,index,&value);
444 return value;
445 }
446 void set_reg( SS_Registers::Index index, uint64_t value )
447 {
448 self->reg_error = (self->set_state)(self,index,value);
449 }
450
451 uint64_t get_reg_tl( uint64_t tl, SS_Registers::Index index )
452 {
453 uint64_t value, save_tl;
454 (self->get_state)(self,SS_Registers::PR_TL,&save_tl);
455 (self->set_state)(self,SS_Registers::PR_TL,tl);
456 self->reg_error = (self->get_state)(self,index,&value);
457 (self->set_state)(self,SS_Registers::PR_TL,save_tl);
458 return value;
459 }
460 void set_reg_tl( uint64_t tl, SS_Registers::Index index, uint64_t value )
461 {
462 uint64_t save_tl;
463 (self->get_state)(self,SS_Registers::PR_TL,&save_tl);
464 (self->set_state)(self,SS_Registers::PR_TL,tl);
465 self->reg_error = (self->set_state)(self,index,value);
466 (self->set_state)(self,SS_Registers::PR_TL,save_tl);
467 }
468
469 uint64_t get_reg_gl( uint64_t gl, SS_Registers::Index index )
470 {
471 uint64_t value, save_gl;
472 (self->get_state)(self,SS_Registers::PR_GL,&save_gl);
473 (self->set_state)(self,SS_Registers::PR_GL,gl);
474 self->reg_error = (self->get_state)(self,index,&value);
475 (self->set_state)(self,SS_Registers::PR_GL,save_gl);
476 return value;
477 }
478 void set_reg_gl( uint64_t gl, SS_Registers::Index index, uint64_t value )
479 {
480 uint64_t save_gl;
481 (self->get_state)(self,SS_Registers::PR_GL,&save_gl);
482 (self->set_state)(self,SS_Registers::PR_GL,gl);
483 self->reg_error = (self->set_state)(self,index,value);
484 (self->set_state)(self,SS_Registers::PR_GL,save_gl);
485 }
486
487 uint64_t get_reg_wp( uint64_t wp, SS_Registers::Index index )
488 {
489 uint64_t value, save_wp;
490 (self->get_state)(self,SS_Registers::PR_CWP,&save_wp);
491 (self->set_state)(self,SS_Registers::PR_CWP,wp);
492 self->reg_error = (self->get_state)(self,index,&value);
493 (self->set_state)(self,SS_Registers::PR_CWP,save_wp);
494 return value;
495 }
496 void set_reg_wp( uint64_t wp, SS_Registers::Index index, uint64_t value )
497 {
498 uint64_t save_wp;
499 (self->get_state)(self,SS_Registers::PR_CWP,&save_wp);
500 (self->set_state)(self,SS_Registers::PR_CWP,wp);
501 self->reg_error = (self->set_state)(self,index,value);
502 (self->set_state)(self,SS_Registers::PR_CWP,save_wp);
503 }
504
505 uint64_t get_asi( uint8_t asi, uint64_t addr )
506 {
507 uint64_t data;
508 self->asi_error = self->asi_map.rd64(self,asi,SS_Vaddr(addr),&data);
509 return data;
510 }
511 void set_asi( uint8_t asi, uint64_t addr, uint64_t data )
512 {
513 self->asi_error = self->asi_map.wr64(self,asi,SS_Vaddr(addr),data);
514 }
515 }
516
517 uint64_t run_step( uint64_t n );
518 uint64_t trc_step( uint64_t n );
519
520 void add_tracer( SS_Tracer* );
521 void del_tracer( SS_Tracer* );
522
523 %immutable;
524 SS_BreakPoint* break_points;
525 SS_BreakPoint* break_hit;
526 %mutable;
527
528 SS_BreakPoint::Ident break_on_trap( uint_t tt );
529 SS_BreakPoint::Ident break_on_red_mode();
530
531 SS_BreakPoint::Error break_enable( SS_BreakPoint::Ident id );
532 SS_BreakPoint::Error break_disable( SS_BreakPoint::Ident id );
533 SS_BreakPoint::Error break_delete( SS_BreakPoint::Ident id );
534
535 SS_AsiMap asi_map;
536
537 // Wrap to avoid swig issues with int64_t
538 %extend {
539 SS_BreakPoint::Ident break_on_inst_va( uint64_t va )
540 {
541 return self->break_on_inst_va(SS_Vaddr(va));
542 }
543 SS_Paddr va2pa( uint64_t va )
544 {
545 return self->va2pa(SS_Vaddr(va));
546 }
547 SS_Paddr va2pa( uint64_t va, uint_t ctx )
548 {
549 return self->va2pa(SS_Vaddr(va),ctx);
550 }
551 SS_Paddr va2pa( uint64_t va, uint_t ctx, uint_t pid )
552 {
553 return self->va2pa(SS_Vaddr(va),ctx,pid);
554 }
555 SS_Paddr ra2pa( uint64_t ra )
556 {
557 return self->ra2pa(SS_Vaddr(ra));
558 }
559 SS_Paddr ra2pa( uint64_t ra, uint_t pid )
560 {
561 return self->ra2pa(SS_Vaddr(ra),pid);
562 }
563 }
564};
565
566/*============================================================================*\
567 * SS_Tte *
568\*============================================================================*/
569
570%inline %{
571/* ss_tte() is used when get an uint64_t value but need a proper
572 SS_Tte python object pointer type */
573
574SS_Tte* ss_tte( int64_t p )
575{
576 return val2ptr<SS_Tte>(p);
577}
578%}
579
580class SS_Tte
581{
582 public:
583 SS_Tte();
584
585 int p();
586 int x();
587 int w();
588 int nfo();
589 int ie();
590 int cp();
591 int cv();
592 int e();
593 int tag_parity_error();
594 int data_parity_error();
595 int valid_bit();
596 int real_bit();
597
598 uint8_t pid();
599 uint16_t context();
600 uint8_t page_size();
601 SS_Vaddr tag();
602 SS_Paddr taddr();
603
604 void p( int f );
605 void x( int f );
606 void w( int f );
607 void nfo( int f );
608 void ie( int f );
609 void cp( int f );
610 void cv( int f);
611 void e( int f);
612 void tag_parity_error( int f );
613 void data_parity_error( int f );
614 void valid_bit( int f );
615 void real_bit( int f );
616
617 void pid( uint8_t p );
618 void context( uint16_t c );
619 void page_size( uint8_t p );
620 void taddr( SS_Paddr t );
621
622
623 // Wrap to avoid swig issues with int64_t
624 %extend {
625 void tag( uint64_t t )
626 {
627 self->tag(SS_Vaddr(t));
628 }
629 SS_Paddr trans( uint64_t va )
630 {
631 return self->trans(SS_Vaddr(va));
632 }
633 bool match_real( uint64_t ra, uint_t pid )
634 {
635 return self->match_real(SS_Vaddr(ra),pid);
636 }
637 bool match_virt( uint64_t va, uint64_t ctxt, uint_t pid )
638 {
639 return self->match_virt(SS_Vaddr(va),ctxt,pid);
640 }
641 bool match_virt( uint64_t va, uint64_t ctxt0, uint64_t ctxt1, uint_t pid )
642 {
643 return self->match_virt(SS_Vaddr(va),ctxt0,ctxt1,pid);
644 }
645 void insert_tsb_tte( uint16_t pid, uint64_t tag, uint64_t data, uint64_t addr )
646 {
647 self->insert_tsb_tte(pid,tag,data,SS_Vaddr(addr));
648 }
649 }
650
651};
652
653/*============================================================================*\
654 * SS_Tlb *
655\*============================================================================*/
656
657%inline %{
658/* ss_tlb() is used when get an uint64_t value but need a proper
659 SS_Tlb python object pointer type */
660
661SS_Tlb* ss_tlb( uint64_t p )
662{
663 return val2ptr<SS_Tlb>(p);
664}
665%}
666
667class SS_Tlb
668{
669 public:
670 uint_t tlb_id();
671 bool is_inst_tlb();
672 bool is_data_tlb();
673
674 uint_t size();
675
676 SS_Tte* get( uint_t index );
677 void set( uint_t index, SS_Tte* tte );
678
679 void flush( SS_Tte* tte );
680
681 int next_valid_index( int );
682};
683
684/*============================================================================*\
685 * SS_SnapShot *
686\*============================================================================*/
687
688class SS_SnapShot
689{
690 public:
691 SS_SnapShot( FILE* f, bool _load );
692};
693
694/*============================================================================*\
695 * SS_AddressMap *
696\*============================================================================*/
697
698class SS_AddressMap
699{
700 public:
701};
702
703%inline %{
704SS_Io* get_io() { return &SS_Io::io; }
705%}
706
707class SS_Io : public SS_AddressMap
708{
709 public:
710 void poke8( uint_t sid,uint64_t addr, uint8_t data );
711 void poke16( uint_t sid,uint64_t addr, uint16_t data );
712 %extend { /* python 2.4 became pedantic about int values with signbit set, this avoids the nagging */
713 void poke32( uint_t sid, int64_t addr, uint64_t data )
714 {
715 self->poke32(sid,addr,uint32_t(data));
716 }
717 }
718 void poke64( uint_t sid, uint64_t addr, uint64_t data );
719
720 uint8_t peek8u ( uint_t sid, uint64_t addr );
721 int8_t peek8s ( uint_t sid, uint64_t addr );
722 uint16_t peek16u( uint_t sid, uint64_t addr );
723 int16_t peek16s( uint_t sid, uint64_t addr );
724 uint32_t peek32u( uint_t sid, uint64_t addr );
725 int32_t peek32s( uint_t sid, uint64_t addr );
726 uint64_t peek64 ( uint_t sid, uint64_t addr );
727
728};
729
730class SS_Model
731{
732 public:
733 uint_t cpu_cnt();
734
735 void flush( SS_Paddr pa );
736 void snapshot( SS_SnapShot& ss );
737 %extend {
738 void ras_enable( )
739 {
740 self->ras_enable(0);
741 }
742 }
743 void ras_enable( char* cmd );
744};