Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / verilog / niu / sparse_mem_model / pli / src / mal.cpp
CommitLineData
86530b38
AT
1/***********************************************************************
2 * Functions to generate and manage random memory address
3 * * Orignal Author(s): Arvind Srinivasan
4 * * Modifier(s):
5 * * Project(s): Neptune
6 * *
7 * * Copyright (c) 2004 Sun Microsystems, Inc.
8 * *
9 * * All Rights Reserved.
10 * *
11 * * This verilog model is the confidential and proprietary property of
12 * * Sun Microsystems, Inc., and the possession or use of this model
13 * * requires a written license from Sun Microsystems, Inc.
14 * *
15************************************************************************/
16
17#include <iostream>
18#include <stdio.h>
19
20#ifdef N2_AXIS
21#else
22 #include <map>
23 using namespace std;
24#endif
25
26#include "vera_directc.h"
27
28#define MASKL 0xffffffff
29#define MAX_ITER 1000
30#define VALID 1
31
32#define NOHOLES 0
33#define INC_NOHOLES 100
34#define RANDOM_HOLES 200
35
36#if defined(__cplusplus)
37extern "C" {
38#endif
39
40
41unsigned int MASKH ;
42unsigned int VIRTMASKH ;
43
44static int verbose;
45class PAGEINFO {
46public:
47 unsigned int mask;
48 unsigned int value;
49 unsigned int reloc;
50 int id;
51 int xlate_on;
52 int valid;
53 unsigned int byte_allocated;
54 int page_size;
55 unsigned int calc_value();
56 unsigned int calc_reloc();
57 unsigned char check_addr_match(unsigned long long int addr);
58 unsigned long long int xlate_addr( unsigned long long int addr);
59 PAGEINFO() {
60 valid = 0;
61 mask = 0;
62 xlate_on = 0;
63 byte_allocated = 0;
64 }
65
66};
67unsigned int PAGEINFO::calc_value() {
68 value = random();
69// VJH This code can be cleaned up but seems OK for now..confer with Arvind/Vernon
70#ifdef NEPTUNE
71 if(id<64) {
72 value = value & mask & 0x0fffffff ; // Force top bits to be 0 for now-
73 } else
74 value = value & mask & 0x0fffffe0 ; // Force top bits to be 0 for now-
75// HACK NEED TO CLEAN THIS
76 value = value & mask & 0x0fffffff ; // Force top bits to be 0 for now-
77#else
78 #ifdef N2_FC
79 if(id<64) {
80 value = value & mask & 0x000fffff ; // Force top bits to be 0 for now-
81 } else
82 value = value & mask & 0x000fffe0 ; // Force top bits to be 0 for now-
83
84 value = value & mask & 0x000fffff ; // Force top bits to be 0 for now-
85 #else
86 if(id<64) {
87 value = value & mask & 0x07ffffff ; // Force top bits to be 0 for now-
88 } else
89 value = value & mask & 0x07ffffe0 ; // Force top bits to be 0 for now-
90
91 value = value & mask & 0x07ffffff ; // Force top bits to be 0 for now-
92 #endif
93#endif
94 value = value & VIRTMASKH; // for supporting 32bit address mode in Neptune
95 if(verbose) printf(" MALLOC_DEBUG: Value for id - %d set to %x \n",id,value);
96 return(value);
97}
98unsigned int PAGEINFO::calc_reloc() {
99/* For neptune, we need to block the following address range 0xF8FFFFFF - 0xF5000000
100 * This belongs to the EEPROM
101 *
102 */
103
104#define NEPT_EEPROM_BASE_MAX 0xF8FFF
105#define NEPT_EEPROM_BASE_MIN 0xF5000
106
107
108#ifdef NEPTUNE
109 int match;
110 int i;
111 match =0;
112 i=0;
113 while(match==0) {
114 reloc = random();
115 reloc = reloc & mask;
116 if((reloc<=NEPT_EEPROM_BASE_MAX) && ( reloc >= NEPT_EEPROM_BASE_MIN)) {
117 // continue
118 i++;
119 if(i>1000) {
120 // cannot converge...
121 printf("PAGEINFO::calc_reloc ERROR Cannot find a suitable reloc for PageID - %d \n",id);
122 reloc = 0;
123 }
124 } else { match=1; }
125 }
126#else
127 reloc = random();
128 reloc = reloc & mask;
129#endif
130
131
132#ifdef NEPTUNE
133 reloc = reloc & 0x0fffffff; // Force top bits to be 0 for now-
134#else
135 #ifdef N2_FC
136 reloc = reloc & 0x000fffff; // Force top bits to be 0 for now-
137 #else
138
139// OLD CODE if(id<64) {
140// OLD CODE reloc = reloc & 0x07ffffff; // Force top bits to be 0 for now-
141// OLD CODE } else
142// OLD CODE reloc = reloc & 0x07ffffe0; // Force top bits to be 0 for now-
143// VJH Doesn't this following line over-writes the previous lines?
144//
145 reloc = reloc & 0x07ffffff; // Force top bits to be 0 for now-
146 #endif
147#endif
148 reloc = reloc & VIRTMASKH; // for supporting 32bit address mode in Neptune
149 if(verbose) printf(" MALLOC_DEBUG: reloc for id - %d set to %x \n",id,reloc);
150 return(reloc);
151}
152
153unsigned long long int PAGEINFO::xlate_addr( unsigned long long int addr) {
154
155 unsigned int xlate;
156 unsigned long long int retval;
157 unsigned int p = addr & 0xfff;
158 unsigned long long int orig_address;
159 orig_address = addr;
160 addr = addr >> 12;
161 xlate = addr & 0xffffffff;
162 xlate = reloc & mask | xlate & (mask ^ 0xffffffff);
163 retval = xlate;
164 retval = retval <<12 | p;
165#ifdef NEPTUNE
166 /* This is only to check if EEPROM base address is not getting generated.*/
167 if((retval<=NEPT_EEPROM_BASE_MAX) && ( retval >= NEPT_EEPROM_BASE_MIN)) {
168 printf(" MALLOC_DEBUG: Xlated Address is within EEPROM Range!! ERROR! FIX THIS!!!\n");
169 retval = 0;
170 }
171#endif
172 if(verbose) printf(" MALLOC_DEBUG: Xlated Address = %llx orig address - %llx \n",retval,orig_address);
173 return(retval);
174
175}
176unsigned char PAGEINFO::check_addr_match(unsigned long long int addr){
177 addr = addr>>12;
178 if(valid ) {
179 if((addr& mask)==reloc) {
180 return(1);
181 } else {
182 return(0);
183 }
184 } else return(0);
185
186}
187
188PAGEINFO *page[128];
189static int pages_allocated = 0; // needed to prevent user errors
190static unsigned char page_bits[32];
191
192#ifdef N2_AXIS
193 #define VALID_BIT (1ULL<<56)
194 unsigned long long *hash_mem=NULL;
195 int num_entries;
196 int max_entries=1*1024*1024;
197#else
198 map< unsigned long long int,unsigned char> hash_mem;
199#endif
200
201static int BITS_TO_IGNORE;
202
203int deleteHashTabEntry (unsigned long long int addr){
204
205// printf(" MALLOC DEBUG in deleteHashTabEntry addr = %x xx = %x \n",addr,hash_mem[addr]);
206#ifdef N2_AXIS
207unsigned long long match=addr|VALID_BIT;
208int i;
209if (!hash_mem){
210 printf(" AXIS_MALLOC_DEBUG: ERROR: remove entry when hash table==NULL \n"); return (0);
211 }
212for (i=0;i<num_entries;i++){
213 if (hash_mem[i]==match){
214 hash_mem[i]=0ULL;
215 return 1;
216 }
217}
218printf(" AXIS_MALLOC_DEBUG: address not found ERROR \n");
219 return(0);
220
221#else
222 if(hash_mem.find(addr)!=hash_mem.end()) {
223 hash_mem.erase(hash_mem.find(addr));
224 // printf(" MALLOC_DEBUG: deleteaddress - %x found \n",addr);
225 return(1);
226 } else {
227 printf(" MALLOC_DEBUG: deleteaddress - %x not found ERROR \n",addr);
228 return(0);
229 }
230#endif
231
232}
233
234#ifdef N2_AXIS
235int getHashTabEntry (unsigned long long int addr){
236unsigned long long match=addr|VALID_BIT;
237int i;
238if (!hash_mem){
239 printf(" AXIS_MALLOC_DEBUG: get entry when hash table==NULL \n");
240 hash_mem=(unsigned long long *)calloc(max_entries,sizeof(unsigned long long));
241 if (!hash_mem){
242 printf(" could not calloc %d bytes \n", max_entries*sizeof(unsigned long long)); exit(1);
243 }
244 }
245for (i=0;i<num_entries;i++){
246 if (hash_mem[i]==match){
247 return VALID;
248 }
249}
250 return(0);
251}
252void addHashTabEntry(unsigned long long int addr){
253
254unsigned long long match=addr|VALID_BIT;
255int i;
256if (num_entries < max_entries){
257 hash_mem[num_entries++] = match;
258 return;
259}else {
260 for (i=0;i<num_entries;i++){
261 if (!hash_mem[i]){
262 hash_mem[i]=match;
263 return;
264 }
265 }
266}
267printf("ERROR: AXIS MALLOC DEBUG table is full adding %llx\n", addr);
268}
269#else
270int getHashTabEntry (unsigned long long int addr){
271 map<unsigned long long int,unsigned char>:: iterator it;
272 it = hash_mem.find(addr);
273 // printf("MALLOC DEBUG1 getHashTabEntry addr = %llx xx = %x \n",addr,hash_mem[addr]);
274
275 if(it!=hash_mem.end()) {
276 // printf("MALLOC DEBUG1 getHashTabEntry return VALID addr = %llx xx = %x \n",addr,hash_mem[addr]);
277 return(VALID);
278 }
279 else return(0);
280}
281
282void addHashTabEntry(unsigned long long int addr){
283
284 hash_mem[addr] = 1;
285 // printf(" MALLOC DEBUG1 addHashTabEntry addr = %llx xx = %x \n",addr,hash_mem[addr]);
286}
287#endif
288
289int check_page_match(unsigned long long int addr, int page_id) {
290unsigned long long int addr_to_check, mask , value, reloc;
291
292addr_to_check = addr >> 12; // <- this determines the block size
293mask = page[page_id]->mask;
294value = page[page_id]->value;
295reloc = page[page_id]->reloc;
296
297// printf(" value - %x \n",value);
298// printf(" mask - %x \n",mask);
299// printf(" addr_to_check - %x \n",addr_to_check);
300// printf(" addr - %llx \n",addr);
301
302// add your function
303if((addr_to_check & mask) == value)
304 return(0);
305else {
306 // printf("MAL_CPP : NO Match found\n");
307 return(1);
308 }
309}
310
311
312
313#ifdef N2_AXIS
314int check_allocated ( unsigned long long int addr, int no_of_blocks,int page_id){
315#else
316int check_allocated ( unsigned long long int addr, int no_of_blocks,int page_id,int alignment){
317#endif
318
319int i;
320unsigned long long int xlate_addr;
321unsigned long long int addr_with_blocks;
322unsigned int block_size;
323int status0,status1;
324
325if(addr == 0) return(1);
326
327
328block_size = 1<<BITS_TO_IGNORE;
329
330//
331
332// translate this address and then check
333if(page[page_id]->xlate_on)
334 xlate_addr = page[page_id]->xlate_addr(addr);
335else xlate_addr = addr;
336
337// translate this address and then check
338status0 = check_page_match(addr, page_id);
339status1 = check_page_match(addr + (no_of_blocks* block_size) ,page_id);
340if(status1 | status0) return(1);
341
342
343addr = xlate_addr >>BITS_TO_IGNORE; // <- this determines the block size
344for(i=0;i<no_of_blocks;i++) {
345 if(getHashTabEntry(addr + i) == VALID ) {
346 return(1); // This address is already allocated
347 }
348}
349addr_with_blocks = xlate_addr + no_of_blocks* ( 1<<BITS_TO_IGNORE);
350
351addr = addr_with_blocks >>BITS_TO_IGNORE; // <- this determines the block size
352
353#ifdef N2_AXIS
354for(i=0;i<1;i++) {
355 if(getHashTabEntry(addr + i) == VALID ) {
356 return(1); // This address is already allocated
357 }
358}
359#else
360if(alignment<block_size) {
361 // Only when alignment is less than the blocks size, there are chances that
362 // the assigned blocks will straddle
363 for(i=0;i<1;i++) {
364 if(getHashTabEntry(addr + i) == VALID ) {
365 return(1); // This address is already allocated
366 }
367 }
368}
369#endif
370
371return(0);
372
373}
374
375
376unsigned long long int malloc_addr(int no_of_blocks, int block_size, unsigned int page_mask, int page_id,int alignment) {
377
378 // block size has to be power of 2
379
380unsigned long long int addr;
381unsigned int page_mask_h;
382unsigned int page_mask_l;
383
384unsigned int value_h;
385unsigned int value_l;
386
387// MASK sets up the range of address needed
388//
389 addr =0;
390 int cnt;
391 int status;
392
393 int i;
394 unsigned int a;
395 i = 0;
396 a = alignment>>1;
397 while(a) {
398 a = a>>1;
399 i++;
400 }
401 unsigned int mask_4K;
402 mask_4K = 0x0;
403 for(int j = 0; j < i; j ++) {
404 mask_4K = mask_4K | ( 1<<j);
405 }
406 mask_4K = 0xffffffff ^ mask_4K;
407
408 unsigned int value;
409 value = page[page_id]->value;
410 page_mask = page[page_id]->mask ;
411
412 page_mask_l = ((page_mask & 0x000fffff) << 12);
413 page_mask_h = (page_mask & 0xfff00000) >> 20;
414
415 value_h = ((page[page_id]->value & 0x000fffff) << 12);
416 value_l = (page[page_id]->value & 0xfff00000) >> 20;
417
418 unsigned int addr_43_12;
419
420 cnt =0;
421 status =1;
422 while( status & (cnt < MAX_ITER)) {
423#ifdef NEPTUNE
424 addr_43_12 = 0x0fffffff & random() & ( page_mask ^0xffffffff ) | value;
425 addr_43_12 = addr_43_12 & VIRTMASKH;
426#else
427 #ifdef N2_FC
428 addr_43_12 = 0x000fffff & random() & ( page_mask ^0xffffffff ) | value;
429 #else
430 addr_43_12 = 0x07ffffff & random() & ( page_mask ^0xffffffff ) | value;
431 #endif
432#endif
433 addr = (unsigned long long int ) (addr_43_12 & ( 0xfffffff0 | (( ( mask_4K&0xf000)>>12 )&0xf)))<<12 ;
434 // printf(" MALLOC_DEBUG: 1 addr = %llx status = %d cnt = %d \n",addr,status,cnt);
435 /// FIX FOR RDMC addr = (addr |( ( random() & MASKL & mask_4K ) & 0xfff)) ;
436 addr = (addr |( ( random() & MASKL & mask_4K ) & 0xfff)) ;
437#ifdef N2_AXIS
438 status = check_allocated(addr, no_of_blocks,page_id);
439#else
440 status = check_allocated(addr, no_of_blocks,page_id,alignment);
441#endif
442 // printf(" MALLOC_DEBUG: 2 addr = %llx status = %d cnt = %d \n",addr,status,cnt);
443 cnt ++;
444 }
445 if(cnt==MAX_ITER) {
446 printf(" MALLOC_DEBUG: Cannot allocate Memory, Free up some locations ---\n");
447 return(0);
448 }
449
450 // Add all the allocated entries into the hash table
451
452 page[page_id]->byte_allocated = page[page_id]->byte_allocated + block_size* no_of_blocks;
453 // printf(" MALLOC_DEBUG: PageID %d - BytesAllocated - %d\n",page_id,page[page_id]->byte_allocated);
454
455 unsigned long long int addr_tobe_added;
456
457 addr_tobe_added = (page[page_id]->xlate_addr(addr)) >> BITS_TO_IGNORE;
458
459 for(int i =0;i<no_of_blocks;i++) {
460 addHashTabEntry(addr_tobe_added + i);
461 }
462 // Add the next block if overflow is detected
463#ifdef N2_AXIS
464addr_tobe_added = ((page[page_id]->xlate_addr(addr)) + block_size* no_of_blocks) >> BITS_TO_IGNORE;
465 addHashTabEntry(addr_tobe_added);
466#else
467 if(alignment<block_size) {
468 addr_tobe_added = ((page[page_id]->xlate_addr(addr)) + block_size* no_of_blocks) >> BITS_TO_IGNORE;
469 addHashTabEntry(addr_tobe_added);
470 }
471#endif
472
473 return(addr);
474}
475
476int free_addr(unsigned long long int addr, int no_of_blocks,int page_id){
477 // if return value is 0 then there has been an error
478 int status,i;
479 unsigned long long int addr_tobe_deleted;
480 int block_size;
481 unsigned int alignment;
482
483 if((page_id<0)| ( page_id>127)) {
484 printf("free_addr: Incorrect PAGE ID Specified!! TB ERROR\n");
485 return(-1);
486 }
487 block_size = 1 << BITS_TO_IGNORE; // Start with some number --
488
489 alignment = addr&0xfff;
490 addr_tobe_deleted = addr >> BITS_TO_IGNORE;
491
492 status = 0;
493 for(i =0; i< no_of_blocks; i ++) {
494 status = deleteHashTabEntry(addr_tobe_deleted + i) + status;
495 }
496 if(alignment) { // else already 4K alignment
497 if(alignment<block_size) {
498 status = deleteHashTabEntry(addr_tobe_deleted + 1) + status;
499 }
500 }
501
502 if(status) {
503 page[page_id]->byte_allocated = page[page_id]->byte_allocated - block_size* no_of_blocks;
504 if(verbose)
505#ifdef N2_AXIS
506 printf(" AXIS MALLOC_DEBUG: NoOfBytes Freed - %d PageID %d - Current BytesAllocated - %d\n",block_size*
507no_of_blocks, page_id,page[page_id]->byte_allocated);
508#else
509 printf(" MALLOC_DEBUG: NoOfBytes Freed - %d PageID %d - Current BytesAllocated - %d\n",block_size*no_of_blocks, page_id,page[page_id]->byte_allocated);
510#endif
511 }
512 return(status);
513}
514
515void set_block_size(int block_size, int mode_32b) {
516
517 BITS_TO_IGNORE = -1;
518
519 MASKH = mode_32b? 0x0 : 0xff;
520 VIRTMASKH = mode_32b? 0x000fffff: 0xffffffff;
521
522 int blocks;
523 blocks = block_size;
524 while(blocks) {
525 BITS_TO_IGNORE++;
526 blocks = blocks >>1;
527 }
528
529
530}
531
532
533int CheckPageId(vec32 *addrh, vec32 *addrl) {
534 int page_id = -1;
535 unsigned long long int addr;
536 int match;
537
538 addr = addrh->d & 0xff ; // Restrict this to 40 bits only for now
539 addr = addr<<32;
540 addr = addr | ( (unsigned long long int) addrl->d );
541
542 match =0;
543 page_id=-1;
544 while((match==0) && (page_id<128)) {
545 page_id++;
546 match = page[page_id]->check_addr_match(addr);
547 }
548 if(match) return(page_id) ;
549 else return(-1);
550
551}
552void MarkUsedLocations(vec32 *addrh, vec32 *addrl, int no_of_blocks) {
553
554 unsigned long long int addr;
555 unsigned long long int addr_tobe_added;
556
557 addr = addrh->d & 0xff ; // Restrict this to 40 bits only for now
558 addr = addr<<32;
559 addr = addr | ( (unsigned long long int) addrl->d );
560
561 addr_tobe_added = addr >>BITS_TO_IGNORE;
562 if(verbose) {
563 printf("MALLOC DEBUG Marking Addresses from %llx to Address %llx as Used \n", addr, (addr + no_of_blocks* (1<<BITS_TO_IGNORE)));
564 }
565
566 for(int i =0;i<no_of_blocks;i++) {
567 addHashTabEntry(addr_tobe_added + i);
568 }
569}
570unsigned long long int xlate_addr( unsigned long long int addr, int page_id ) {
571unsigned long long int retval;
572// translate this address and then check
573if(page[page_id]->xlate_on) {
574 retval = page[page_id]->xlate_addr(addr); }
575else retval = addr;
576
577return(retval);
578}
579
580
581vec32* XlateAddr( vec32 * addrh, vec32 * addrl, int page_id) {
582unsigned long long int init_addr;
583unsigned long long int xlateaddr;
584vec32 retval[2];
585
586 if(pages_allocated == 0) {
587 // enable only only one page ie page0
588 for(int i = 0; i <128;i++) {
589 page[i] = new PAGEINFO ();
590 page[i]->valid = 1;
591 page[i]->xlate_on = 0;
592 page[i]->page_size = -1;
593 page[i]->mask = 0;
594 page[i]->value = 0x0;
595 }
596 pages_allocated = 1;
597 }
598
599if(page_id <128) {
600 init_addr = addrh->d;
601 init_addr = init_addr <<32;
602 init_addr = init_addr | addrl->d;
603 xlateaddr = xlate_addr( init_addr, page_id);
604 retval[0].d = xlateaddr & 0xffffffff;
605 retval[0].c = 0x0;
606 retval[1].d = (unsigned long long int ) xlateaddr>>32;;
607 retval[1].c = 0x0;
608 return(retval);
609} else {
610 printf(" XlateAddr:: TESTBENCH ERROR \n");
611 retval[0].d = 0;
612 retval[0].c = 0xffffffff;
613 retval[1].d = 0;
614 retval[1].c = 0xffffffff;
615 return(retval);
616}
617}
618
619
620void SetExtMemBlockSize(int block_size, int mode_32b) {
621
622 set_block_size(block_size,mode_32b);
623
624}
625
626
627
628int FreeAddr (vec32 * addrh, vec32 * addrl, int no_of_blocks, int page_id){
629
630 unsigned long long int addr;
631 int status;
632 addr = addrh->d;
633 addr = addr <<32;
634 addr = addr | addrl->d;
635 status = free_addr(addr, no_of_blocks,page_id);
636 return(status);
637}
638
639int ForcePageContexts (int page_id, vec32 * mask, vec32 * value, vec32 * reloc) {
640 if(pages_allocated == 0) {
641 for(int i = 0; i <128;i++) {
642 page[i] = new PAGEINFO ();
643 page[i]->valid = 1;
644 page[i]->xlate_on = 0;
645 page[i]->page_size = -1;
646 page[i]->mask = 0;
647 page[i]->value = 0x0;
648 }
649 pages_allocated = 1;
650 }
651 if(page_id>=128) {
652 printf(" MALLOC_DEBUG: page id - %d greater than 128!! ERROR \n");
653 return(-1);
654 }
655 page[page_id]->valid = 1;
656 page[page_id]->xlate_on = 1;
657 page[page_id]->page_size = -1;
658 page[page_id]->mask = mask->d;
659 page[page_id]->value = value->d;
660 page[page_id]->reloc = reloc->d;
661
662 return(1);
663}
664
665vec32* MallocBlock(int no_of_blocks, int page_id, int alignment ) {
666
667 unsigned long long int addr;
668 vec32 returnval[2];
669 unsigned int addrl,addrh;
670 unsigned int page_mask;
671
672 int block_size;
673 block_size = 1 << BITS_TO_IGNORE; // Start with some number --
674
675 if(pages_allocated == 0) {
676 // enable only only one page ie page0
677 for(int i = 0; i <128;i++) {
678 page[i] = new PAGEINFO ();
679 page[i]->valid = 1;
680 page[i]->xlate_on = 0;
681 page[i]->page_size = -1;
682 page[i]->mask = 0;
683 page[i]->value = 0x0;
684 }
685 pages_allocated = 1;
686 }
687
688 if(page_id>=128) {
689 printf(" MALLOC_DEBUG: page id - %d greater than 128!! ERROR \n");
690 returnval[0].d = 0;
691 returnval[0].c = 0xffffffff;
692 returnval[1].d = 0;
693 returnval[1].c = 0xffffffff;
694 return(returnval);
695 }
696 if(page[page_id]->valid) {
697 // printf(" MALLOC_DEBUG: page_id - %d bytes_allocated - %d , page_size - %d \n",page_id,page[page_id]->byte_allocated,page[page_id]->page_size);
698 if( ( (block_size*no_of_blocks) + page[page_id]->byte_allocated ) > page[page_id]->page_size) {
699 printf(" MALLOC_DEBUG: No Space available!!! - ERROR \n");
700 returnval[0].d = 0;
701 returnval[0].c = 0xffffffff;
702 returnval[1].d = 0;
703 returnval[1].c = 0xffffffff;
704 return(returnval);
705 }
706
707 if(page[page_id]->xlate_on)
708 page_mask = page[page_id]->mask;
709 else page_mask = 0;
710
711#ifdef N2_AXIS
712#else
713 if(verbose)
714 printf(" MALLOC_DEBUG: malloc called with page_id - %d page_mask - %x \n",page_id,page_mask);
715#endif
716
717 addr = malloc_addr( no_of_blocks, block_size, page_mask, page_id,alignment);
718 if(verbose)
719 printf(" MALLOC_DEBUG: Virtual Allocated address = %llx with NoOfBlock - %d page_mask - %x page_id - %d BytesAllocated - %d Page Size - %d ByteAlignment - %d \n",addr,no_of_blocks, page_mask,page_id,page[page_id]->byte_allocated,page[page_id]->page_size, alignment);
720 if(addr==0) {
721 printf(" MALLOC_DEBUG: No Space available!!! - ERROR \n");
722 returnval[0].d = 0;
723 returnval[0].c = 0xffffffff;
724 returnval[1].d = 0;
725 returnval[1].c = 0xffffffff;
726 return(returnval);
727 }
728
729 // returnval = (vec32 *) malloc(sizeof(vec32));
730 addrl = addr & 0xffffffff;
731 addr = (unsigned long long int ) addr>>32;
732 addrh = addr;
733 returnval[0].d = addrl;
734 returnval[0].c = 0;
735 returnval[1].d = addrh;
736 returnval[1].c = 0;
737 } else {
738 printf(" MALLOC_DEBUG: page id - %d Not initialized!! ERROR \n",page_id);
739 returnval[0].d = 0;
740 returnval[0].c = 0;
741 returnval[1].d = 0;
742 returnval[1].c = 0;
743 }
744
745 return(returnval);
746
747
748}
749
750
751
752// Functions to return handle to page; ( top 20bits in Address)
753#ifdef N2_AXIS
754int check_page_handle_alloc ( unsigned int handle) {
755if (!hash_mem){
756 printf(" MALLOC_DEBUG: check_page_handle_alloc when hash table==NULL \n");
757 hash_mem=(unsigned long long *)calloc(max_entries,sizeof(unsigned long long));
758 if (!hash_mem){
759 printf(" could not calloc %d bytes \n", max_entries*sizeof(unsigned long long)); exit(1);
760 }
761
762 }
763 if (hash_mem[handle] & VALID_BIT)
764 return(VALID);
765else return(0);
766}
767#else
768map< unsigned int,unsigned char> page_handle;
769int check_page_handle_alloc ( unsigned int handle) {
770 map<unsigned int,unsigned char>:: iterator it;
771 it = page_handle.find(handle);
772 // printf(" addr = %x xx = %x \n",addr,hash_mem[addr]);
773 if(it!=page_handle.end())
774 return(VALID);
775 else return(0);
776}
777#endif
778vec32* GetPageHandle() {
779 unsigned int handle;
780 vec32 *retval;
781 retval = (vec32 *) malloc(sizeof(vec32));
782 int status;
783 status = 1;
784 while(status) {
785 handle = random() & 0xfffff;// 20 bits only
786 status = check_page_handle_alloc(handle);
787 }
788#ifdef N2_AXIS
789#else
790 page_handle[handle] = 1;
791#endif
792 if(verbose) printf(" MALLOC_DEBUG: Page Handle Allocated - %x \n",handle);
793 retval->d = handle;
794 retval->c = 0;
795 return(retval);
796}
797
798#ifdef N2_AXIS
799unsigned int DeletePageHandle( unsigned int handle) {
800if (hash_mem[handle] & VALID_BIT){
801 hash_mem[handle] =0;
802 return(1);
803 } else {
804 printf(" AXIS MALLOC_DEBUG: address not found ERROR \n");
805 return(0);
806 }
807}
808#else
809unsigned int DeletePageHandle( unsigned int handle) {
810 if(page_handle.find(handle)!=page_handle.end()) {
811 page_handle.erase(page_handle.find(handle));
812 return(1);
813 } else {
814 printf(" MALLOC_DEBUG: address not found ERROR \n");
815 return(0);
816 }
817}
818#endif
819
820// functions to return page masks
821
822vec32 * GetPageMask (int id) {
823 vec32 *retval;
824 retval = (vec32 *) malloc(sizeof(vec32));
825 if(page[id]->valid) {
826 retval->d = page[id]->mask;
827 } else
828 retval->d = 0;
829 retval->c = 0;
830 return(retval);
831}
832vec32 * GetPageValue (int id) {
833 vec32 *retval;
834 retval = (vec32 *) malloc(sizeof(vec32));
835 if(page[id]->valid) {
836 retval->d = page[id]->value;
837 } else
838 retval->d = 0;
839 retval->c = 0;
840 return(retval);
841}
842vec32 * GetPageReloc (int id) {
843 vec32 *retval;
844 retval = (vec32 *) malloc(sizeof(vec32));
845 if(page[id]->valid) {
846 retval->d = page[id]->reloc;
847 } else
848 retval->d = 0;
849 retval->c = 0;
850 return(retval);
851
852}
853int SetConfig ( int config, unsigned int gSeed ){
854 srandom(gSeed);
855 if(config == 1) {
856 verbose = 1;
857 }
858 else {
859 verbose = 0;
860 }
861 // Can have more configs here
862return 0;
863}
864
865int DeletePageContext ( int id) {
866 if(pages_allocated) {
867 delete page[id];
868 page[id] = new PAGEINFO ();
869 page[id]->xlate_on = 1;
870 return(1);
871 } else return(0);
872}
873int SetPageMask ( int no_of_pages /* NoOf4KPages*/, int type, int id) {
874
875
876
877 static int id_assigned = 0;
878 unsigned char b[32];
879 static int init= 0;
880 unsigned int mask;
881 int entry_free;
882 int cnt;
883 int index;
884 int status;
885 if(!init) {
886 for(int i = 0; i <128;i++) {
887 page[i] = new PAGEINFO ();
888 page[i]->xlate_on = 1;
889 }
890 init = 1;
891 pages_allocated = 1;
892#ifdef N2_AXIS
893#else
894 for(int i = 0; i < 32;i++) page_bits[i] = 0;
895#endif
896 }
897
898 if(page[id]->valid) {
899 printf(" MALLOC_DEBUG: ERROR- Pageid - %d already allocated - Delete this page before re-allocating \n",id);
900 return(-1);
901 }
902
903
904 if(no_of_pages == 1) { // Need 4K size
905
906 page[id]->mask = 0xffffffff;
907 page[id]->mask = page[id]->mask & VIRTMASKH;
908 page[id]->id = id;
909 page[id]->page_size = 4096;
910 unsigned int value = page[id]->calc_value();
911 unsigned int reloc = page[id]->calc_reloc();
912 page[id]->valid = 1;
913 status = 1;
914 return(status);
915 }
916 if(no_of_pages == -1) { // get the entire memory -- only one large page is valid
917 id = 0; // force to 0
918 page[id]->mask = 0;
919 page[id]->mask = page[id]->mask & VIRTMASKH;
920 page[id]->page_size = -1;
921 page[id]->xlate_on = 0;
922 page[id]->id = id;
923 unsigned int value = page[id]->calc_value();
924 unsigned int reloc = page[id]->calc_reloc();
925 page[id]->valid = 1;
926 status =1 ;
927 return(status);
928 }
929
930 cnt = 0;
931 int no_of_0s;
932 no_of_0s = 0;
933 int no_of_4Kpages = no_of_pages;
934 while(no_of_4Kpages) {
935 no_of_0s++;
936 no_of_4Kpages = no_of_4Kpages>>1;
937 }
938 // printf(" NoOf 0s = %d required for #%d NoOf4KPages \n",no_of_0s,no_of_pages);
939
940 // fill in appropriate number of 0s and return the mask
941
942#ifdef N2_AXIS
943 for(int i = 0; i < 32;i++) b[i] = 0;
944
945 if(type == 0 /* No holes*/) {
946 mask = 0xffffffff;
947 for(int i = 0 ; i < no_of_0s; i ++) {
948 mask = mask ^ ( 1 << i);
949 }
950 cnt = 0;
951 } else {
952 mask = 0xffffffff;
953 for(int i = 0 ; i < no_of_0s; i ++) {
954 entry_free = 0;
955 cnt = 0;
956 while(!entry_free & (cnt <32)) {
957 index = random() % 32;
958 cnt ++;
959 if(b[index]!=0) entry_free = 0;
960 else { entry_free = 1; b[index] = 1;}
961 }
962 // flip the appropriate bit as indicated by the index
963 mask = mask ^ ( 1 << index);
964 }
965 }
966#else
967 if(type== NOHOLES) {
968 mask = 0xffffffff;
969 for(int i = 0 ; i < no_of_0s; i ++) {
970 mask = mask ^ ( 1 << i);
971 }
972 cnt = 0;
973 } else if(type==INC_NOHOLES/*Noholes*/) {
974 // pick up the first available 0 from bottom
975 index = 31;
976 while((page_bits[index]==1)&( index >=0)) {
977 index--;
978 }
979
980 // move this index such that index+no_of_page <32
981 if( (index+no_of_0s) > 32) {
982 index = index - ( index + no_of_0s -32 );
983 }
984 int start_index = index;
985 // int end_index = index + no_of_0s;
986 int end_index = 32;
987 mask = 0xffffffff;
988 printf("MALLOC DEBUG start_index - %d end_index - %d \n",start_index,end_index);
989 for(int i= start_index; i< end_index;i++) {
990 mask = mask ^ ( 1 << (31 - i));
991 page_bits[i] = 1;
992 }
993 } else {
994 for(int i = 0; i < 32;i++) b[i] = 0;
995
996 if(type== RANDOM_HOLES) {
997 mask = 0xffffffff;
998 } else {
999 // add no of contg 0s based upon the type and leave the rest to
1000 // random
1001 mask = 0xffffffff;
1002 for(int i = 0 ; i < type; i ++) {
1003 mask = mask ^ ( 1 << i);
1004 b[i] = 1;
1005 }
1006 if((no_of_0s - type)<0) {
1007 printf("MALLOC USER ERROR In correct Type given!!! \n");
1008 status = -1;
1009 return(status);
1010 }
1011 }
1012 for(int i = 0 ; i < no_of_0s - type; i ++) {
1013 entry_free = 0;
1014 cnt = 0;
1015 while(!entry_free & (cnt <32)) {
1016 index = random() % 32;
1017 cnt ++;
1018 if(b[index]!=0) entry_free = 0;
1019 else { entry_free = 1; b[index] = 1;}
1020 }
1021 // flip the appropriate bit as indicated by the index
1022 mask = mask ^ ( 1 << index);
1023 }
1024 }
1025#endif
1026 if(cnt >= 32) {
1027 printf(" MALLOC_DEBUG: ERROR - All entries are occupied in the page mask generation!! \n");
1028 page[id]->valid = 0;
1029 page[id]->mask = 0;
1030 page[id]->id = id;
1031 page[id]->page_size = 0;
1032 unsigned int value = page[id]->calc_value();
1033 unsigned int reloc = page[id]->calc_reloc();
1034 page[id]->valid = 1;
1035 status = -1;
1036 return(status);
1037
1038 }
1039
1040 if(verbose) printf(" MALLOC_DEBUG: Page Mask Derived - %x \n",mask);
1041 page[id]->mask = mask;
1042 page[id]->id = id;
1043 page[id]->page_size = 4096*no_of_pages ;
1044 unsigned int value = page[id]->calc_value();
1045 unsigned int reloc = page[id]->calc_reloc();
1046 page[id]->valid = 1;
1047 status = 1;
1048 return(status);
1049}
1050
1051/*
1052int main() {
1053
1054
1055 int i;
1056 unsigned long long int addr;
1057 int block_size;
1058 int no_of_blocks;
1059
1060 block_size = 512; // Start with some number --
1061 no_of_blocks = 4; // 4 blocks of 512 bytes
1062
1063
1064 set_block_size(block_size);
1065
1066 for( i = 0; i< 100000; i ++) {
1067 addr = malloc_addr( no_of_blocks, block_size);
1068 printf(" i = %d addr = %x \n",i,addr);
1069
1070 }
1071
1072
1073return(1);
1074}
1075
1076*/
1077#if defined(__cplusplus)
1078} /* extern "C" */
1079#endif
1080