2 * Simulator of microcontrollers (mem.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
11 This file is part of microcontroller simulator: ucsim.
13 UCSIM is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 UCSIM is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with UCSIM; see the file COPYING. If not, write to the Free
25 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
51 static class cl_mem_error_registry mem_error_registry;
54 * 3rd version of memory system
57 cl_memory::cl_memory(char *id, t_addr asize, int awidth):
62 addr_format= data_format= 0;
68 cl_memory::~cl_memory(void)
79 addr_format= (char *)malloc(10);
80 sprintf(addr_format, "0x%%0%dx",
86 (size-1<=0xffffff?6:12))))));
87 data_format= (char *)malloc(10);
88 sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0));
96 dump_finished= start_address;
102 cl_memory::valid_address(t_addr addr)
104 return(addr >= start_address &&
105 addr < start_address+size);
109 cl_memory::inc_address(t_addr addr, int val)
112 return(((signed)addr+val)%size);
113 addr-= start_address;
116 addr+= start_address;
121 cl_memory::inc_address(t_addr addr)
124 return(((signed)addr+1)%size);
125 addr-= start_address;
128 addr+= start_address;
133 cl_memory::validate_address(t_addr addr)
135 while (addr < start_address)
137 if (addr > start_address+size)
139 addr-= start_address;
141 addr+= start_address;
148 cl_memory::err_inv_addr(t_addr addr)
152 class cl_error *e= new cl_error_mem_invalid_address(this, addr);
157 cl_memory::err_non_decoded(t_addr addr)
161 class cl_error *e= new cl_error_mem_non_decoded(this, addr);
167 cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
170 t_addr lva= lowest_valid_address();
171 t_addr hva= highest_valid_address();
177 while ((start <= stop) &&
180 con->dd_printf(addr_format, start); con->dd_printf(" ");
187 con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" ");
192 j= width/4 + ((width%4)?1:0) + 1;
200 for (i= 0; (i < bpl) &&
205 long c= read(start+i);
206 con->dd_printf("%c", isprint(255&c)?(255&c):'.');
208 con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
210 con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
212 con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
214 con->dd_printf("\n");
215 dump_finished= start+i;
218 return(dump_finished);
222 cl_memory::dump(class cl_console *con)
224 return(dump(dump_finished, dump_finished+10*8-1, 8, con));
228 cl_memory::search_next(bool case_sensitive,
229 t_mem *array, int len, t_addr *addr)
248 for (i= 0; i < len && match; i++)
255 if (/*d1 < 128*/isalpha(d1))
257 if (/*d2 < 128*/isalpha(d2))
277 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
288 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
290 t_mem *data_place, t_mem the_mask):
301 cl_memory_operator::set_data(t_mem *data_place, t_mem the_mask)
309 cl_memory_operator::read(void)
312 return(next_operator->read());
318 cl_memory_operator::write(t_mem val)
321 return(next_operator->write(val));
323 return(*data= (val & mask));
327 /* Memory operator for hw callbacks */
329 cl_hw_operator::cl_hw_operator(class cl_memory_cell *acell, t_addr addr,
330 t_mem *data_place, t_mem the_mask,
332 cl_memory_operator(acell, addr, data_place, the_mask)
339 cl_hw_operator::read(void)
347 next_operator->read();
353 cl_hw_operator::read(enum hw_cath skip)
358 hw->cathegory != skip)
362 next_operator->read();
368 cl_hw_operator::write(t_mem val)
371 hw->write(cell, &val);
373 val= next_operator->write(val);
374 return(*data= (val & mask));
378 /* Write event break on cell */
380 cl_write_operator::cl_write_operator(class cl_memory_cell *acell, t_addr addr,
381 t_mem *data_place, t_mem the_mask,
382 class cl_uc *auc, class cl_brk *the_bp):
383 cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp)
390 cl_write_operator::write(t_mem val)
392 //printf("write event at 0x%x bp=%p\n",address,bp);
395 return(next_operator->write(val));
397 return(*data= (val & mask));
401 /* Read event break on cell */
403 cl_read_operator::cl_read_operator(class cl_memory_cell *acell, t_addr addr,
404 t_mem *data_place, t_mem the_mask,
405 class cl_uc *auc, class cl_brk *the_bp):
406 cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp)
413 cl_read_operator::read(void)
415 //printf("read event at 0x%x bp=%p\n",address,bp);
418 return(next_operator->read());
428 cl_memory_cell::cl_memory_cell(void):
431 data= (t_mem *)malloc(sizeof(t_mem));
432 flags= CELL_NON_DECODED;
438 nuof_writes= nuof_reads= 0;
450 cl_memory_cell::~cl_memory_cell(void)
452 if ((flags & CELL_NON_DECODED) &&
458 cl_memory_cell::init(void)
467 cl_memory_cell::get_flags(void)
473 cl_memory_cell::get_flag(enum cell_flag flag)
475 return(flags & flag);
479 cl_memory_cell::set_flags(TYPE_UBYTE what)
485 cl_memory_cell::set_flag(enum cell_flag flag, bool val)
495 cl_memory_cell::un_decode(void)
497 if ((flags & CELL_NON_DECODED) == 0)
499 data= (t_mem *)malloc(sizeof(t_mem));
500 flags|= CELL_NON_DECODED;
505 cl_memory_cell::decode(class cl_memory_chip *chip, t_addr addr)
507 if (flags & CELL_NON_DECODED)
509 data= chip->get_slot(addr);
512 data= (t_mem *)malloc(sizeof(t_mem));
513 flags|= CELL_NON_DECODED;
516 flags&= ~(CELL_NON_DECODED);
521 cl_memory_cell::read(void)
527 return(operators->read());
532 cl_memory_cell::read(enum hw_cath skip)
538 return(operators->read(skip));
543 cl_memory_cell::get(void)
549 cl_memory_cell::write(t_mem val)
555 return(operators->write(val));
561 cl_memory_cell::set(t_mem val)
570 cl_memory_cell::add(long what)
572 *data= (*data + what) & mask;
577 cl_memory_cell::wadd(long what)
579 t_mem d= (*data + what) & mask;
584 cl_memory_cell::set_bit1(t_mem bits)
591 cl_memory_cell::set_bit0(t_mem bits)
599 cl_memory_cell::append_operator(class cl_memory_operator *op)
605 class cl_memory_operator *o= operators, *n;
617 cl_memory_cell::prepend_operator(class cl_memory_operator *op)
621 op->set_next(operators);
627 cl_memory_cell::del_operator(class cl_brk *brk)
631 class cl_memory_operator *op= operators;
632 if (operators->match(brk))
634 operators= op->get_next();
639 while (op->get_next() &&
640 !op->get_next()->match(brk))
644 class cl_memory_operator *m= op->get_next();
645 op->set_next(m->get_next());;
652 class cl_memory_cell *
653 cl_memory_cell::add_hw(class cl_hw *hw, int *ith, t_addr addr)
655 class cl_hw_operator *o= new cl_hw_operator(this, addr, data, mask, hw);
661 cl_memory_cell::get_hw(int ith)
666 class cl_event_handler *
667 cl_memory_cell::get_event_handler(void)
674 * Dummy cell for non-existent addresses
678 cl_dummy_cell::write(t_mem val)
683 *data= rand() & mask;
688 cl_dummy_cell::set(t_mem val)
690 *data= rand() & mask;
699 cl_address_space::cl_address_space(char *id,
700 t_addr astart, t_addr asize, int awidth):
701 cl_memory(id, asize, awidth)
703 start_address= astart;
704 decoders= new cl_decoder_list(2, 2, DD_FALSE);
705 cells= (class cl_memory_cell **)malloc(size * sizeof(class cl_memory_cell*));
707 for (i= 0; i < size; i++)
709 cells[i]= new cl_memory_cell();
712 dummy= new cl_dummy_cell();
715 cl_address_space::~cl_address_space(void)
719 for (i= 0; i < size; i++)
727 cl_address_space::read(t_addr addr)
729 t_addr idx= addr-start_address;
731 addr < start_address)
734 return(dummy->read());
736 return(cells[idx]->read());
740 cl_address_space::read(t_addr addr, enum hw_cath skip)
742 t_addr idx= addr-start_address;
744 addr < start_address)
747 return(dummy->read());
749 return(cells[idx]->read(skip));
753 cl_address_space::get(t_addr addr)
755 t_addr idx= addr-start_address;
757 addr < start_address)
760 return(dummy->get());
762 return(cells[idx]->get());
766 cl_address_space::write(t_addr addr, t_mem val)
768 t_addr idx= addr-start_address;
770 addr < start_address)
773 return(dummy->write(val));
775 return(cells[idx]->write(val));
779 cl_address_space::set(t_addr addr, t_mem val)
781 t_addr idx= addr-start_address;
783 addr < start_address)
789 cells[idx]->set(val);
793 cl_address_space::wadd(t_addr addr, long what)
795 t_addr idx= addr-start_address;
797 addr < start_address)
801 return(cells[idx]->wadd(what));
804 /* Set or clear bits, without callbacks */
807 cl_address_space::set_bit1(t_addr addr, t_mem bits)
809 t_addr idx= addr-start_address;
811 addr < start_address)
813 class cl_memory_cell *cell= cells[idx];
814 cell->set_bit1(bits);
818 cl_address_space::set_bit0(t_addr addr, t_mem bits)
820 t_addr idx= addr-start_address;
822 addr < start_address)
824 class cl_memory_cell *cell= cells[idx];
825 cell->set_bit0(bits);
829 class cl_memory_cell *
830 cl_address_space::get_cell(t_addr addr)
832 t_addr idx= addr-start_address;
834 addr < start_address)
844 cl_address_space::get_cell_flag(t_addr addr)
846 t_addr idx= addr-start_address;
848 addr < start_address)
850 return(dummy->get_flags());
852 return(cells[addr]->get_flags());
856 cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag)
858 t_addr idx= addr-start_address;
860 addr < start_address)
862 return(dummy->get_flag(flag));
864 return(cells[addr]->get_flag(flag));
868 cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag)
870 t_addr idx= addr-start_address;
871 class cl_memory_cell *cell;
874 addr < start_address)
880 cell->set_flag(flag, set_to);
885 cl_address_space::decode_cell(t_addr addr,
886 class cl_memory_chip *chip, t_addr chipaddr)
888 t_addr idx= addr-start_address;
890 addr < start_address)
892 class cl_memory_cell *cell= cells[idx];
894 if (!cell->get_flag(CELL_NON_DECODED))
899 cell->decode(chip, chipaddr);
901 return(!cell->get_flag(CELL_NON_DECODED));
905 cl_address_space::undecode_cell(t_addr addr)
907 t_addr idx= addr-start_address;
909 addr < start_address)
911 class cl_memory_cell *cell= cells[idx];
917 cl_address_space::undecode_area(class cl_address_decoder *skip,
918 t_addr begin, t_addr end,class cl_console *con)
920 #define D if (con) con->debug
921 D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name());
923 for (i= 0; i < decoders->count; i++)
925 class cl_address_decoder *d=
926 dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
930 D(" Checking decoder 0x%x-0x%x -> %s[0x%x]\n",
931 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
932 if (d->fully_covered_by(begin, end))
934 // decoder can be removed
935 D(" Can be removed\n");
936 decoders->disconn(d);
939 if (decoders->count == 0)
942 else if (d->covers(begin, end))
944 // decoder must be split
945 D(" Must be split\n");
946 class cl_address_decoder *nd= d->split(begin, end);
947 D(" After split:\n");
948 D(" 0x%x-0x%x -> %s[0x%x]\n",
949 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
953 D(" 0x%x-0x%x -> %s[0x%x]\n",
954 nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin);
958 else if (d->is_in(begin, end))
960 // decoder sould shrink
961 D(" Sould shrink\n");
962 if (d->shrink_out_of(begin, end))
964 D(" Can be removed after shrink\n");
965 decoders->disconn(d);
968 if (decoders->count == 0)
973 D(" Shrinked to 0x%x-0x%x -> %s[0x%x]\n",
974 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
982 class cl_memory_cell *
983 cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
987 t_addr idx= addr-start_address;
989 addr < start_address)
991 class cl_memory_cell *cell= cells[idx];
992 cell->add_hw(hw, ith, addr);
993 //printf("adding hw %s to cell 0x%x(%d) of %s\n", hw->id_string, addr, idx, get_name("as"));
995 ;//uc->sim->/*app->*/mem_cell_changed(this, addr);//FIXME
1001 cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
1003 t_addr idx= addr-start_address;
1005 addr < start_address)
1007 class cl_memory_cell *cell= cells[idx];
1008 class cl_memory_operator *op;
1010 switch (brk->get_event())
1012 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1014 op= new cl_write_operator(cell, addr, cell->get_data(), cell->get_mask(),
1017 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1019 op= new cl_read_operator(cell, addr, cell->get_data(), cell->get_mask(),
1023 set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
1032 cell->append_operator(op);
1036 cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
1038 t_addr idx= addr-start_address;
1040 addr < start_address)
1042 class cl_memory_cell *cell= cells[idx];
1044 switch (brk->get_event())
1046 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1047 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1048 cell->del_operator(brk);
1051 set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
1061 * List of address spaces
1064 cl_address_space_list::cl_address_space_list(class cl_uc *the_uc):
1065 cl_list(2, 2, "address spaces")
1071 cl_address_space_list::add(class cl_address_space *mem)
1074 t_index ret= cl_list::add(mem);
1077 class cl_event_address_space_added e(mem);
1078 uc->handle_event(e);
1088 cl_memory_chip::cl_memory_chip(char *id, int asize, int awidth, int initial):
1089 cl_memory(id, asize, awidth)
1091 array= (t_mem *)malloc(size * sizeof(t_mem));
1092 init_value= initial;
1095 cl_memory_chip::~cl_memory_chip(void)
1102 cl_memory_chip::init(void)
1106 for (i= 0; i < size; i++)
1108 (init_value<0)?rand():(init_value));
1114 cl_memory_chip::get_slot(t_addr addr)
1119 return(&array[addr]);
1124 cl_memory_chip::get(t_addr addr)
1129 return(array[addr]);
1133 cl_memory_chip::set(t_addr addr, t_mem val)
1138 array[addr]= val & data_mask;
1142 cl_memory_chip::set_bit1(t_addr addr, t_mem bits)
1147 array[addr]|= (bits & data_mask);
1151 cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
1156 array[addr]&= ((~bits) & data_mask);
1164 cl_address_decoder::cl_address_decoder(class cl_memory *as,
1165 class cl_memory *chip,
1166 t_addr asb, t_addr ase, t_addr cb)
1168 if (as->is_address_space())
1169 address_space= (class cl_address_space *)as;
1172 if (chip->is_chip())
1173 memchip= (class cl_memory_chip *)chip;
1179 activated= DD_FALSE;
1182 cl_address_decoder::~cl_address_decoder(void)
1186 for (a= as_begin; a <= as_end; a++)
1187 address_space->undecode_cell(a);
1191 cl_address_decoder::init(void)
1198 cl_address_decoder::activate(class cl_console *con)
1200 #define D if (con) con->debug
1201 D("Activation of an address decoder\n");
1204 D("Already activated\n");
1207 if (!address_space ||
1208 !address_space->is_address_space())
1210 D("No or non address space\n");
1214 !memchip->is_chip())
1216 D("No or non memory chip\n");
1219 if (as_begin > as_end)
1221 D("Wrong address area specification\n");
1224 if (chip_begin >= memchip->get_size())
1226 D("Wrong chip area specification\n");
1229 if (as_begin < address_space->start_address ||
1230 as_end >= address_space->start_address + address_space->get_size())
1232 D("Specified area is out of address space\n");
1235 if (as_end-as_begin > memchip->get_size()-chip_begin)
1237 D("Specified area is out of chip size\n");
1241 address_space->undecode_area(this, as_begin, as_end, con);
1244 for (asa= as_begin, ca= chip_begin;
1248 if (!address_space->decode_cell(asa, memchip, ca))
1250 D("Decoding 0x%06x->0x%06x failed\n", asa, ca);
1261 cl_address_decoder::fully_covered_by(t_addr begin, t_addr end)
1263 if (begin <= as_begin &&
1270 cl_address_decoder::is_in(t_addr begin, t_addr end)
1272 if (begin >= as_begin &&
1275 if (end >= as_begin &&
1282 cl_address_decoder::covers(t_addr begin, t_addr end)
1284 if (begin > as_begin &&
1291 /* Returns TRUE if shrunken decoder is unnecessary */
1294 cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
1305 address_space->undecode_cell(a);
1308 if (begin > as_begin)
1312 chip_begin+= (end-as_begin+1);
1315 if (as_end < as_begin)
1320 class cl_address_decoder *
1321 cl_address_decoder::split(t_addr begin, t_addr end)
1323 class cl_address_decoder *nd= 0;
1324 if (begin > as_begin)
1327 nd= new cl_address_decoder(address_space, memchip,
1328 end+1, as_end, chip_begin+(end-as_begin)+1);
1329 shrink_out_of(begin, as_end);
1331 else if (end < as_end)
1333 if (as_begin < begin)
1334 nd= new cl_address_decoder(address_space, memchip,
1335 as_begin, begin-1, chip_begin);
1336 shrink_out_of(end+1, as_end);
1345 * List of address decoders
1348 cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):
1349 cl_sorted_list(alimit, adelta, "decoder list")
1351 Duplicates= DD_TRUE;
1356 cl_decoder_list::key_of(void *item)
1358 class cl_address_decoder *d= (class cl_address_decoder *)item;
1360 return(&(d->chip_begin));
1362 return(&(d->as_begin));
1366 cl_decoder_list::compare(void *key1, void *key2)
1368 t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);
1378 * Errors in memory handling
1381 /* All of memory errors */
1383 cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
1387 classification= mem_error_registry.find("memory");
1390 /* Invalid address in memory access */
1392 cl_error_mem_invalid_address::
1393 cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
1394 cl_error_mem(amem, aaddr)
1396 classification= mem_error_registry.find("invalid_address");
1400 cl_error_mem_invalid_address::print(class cl_commander *c)
1402 FILE *f= c->get_out();
1403 cmd_fprintf(f, "%s: invalid address ", get_type_name());
1404 cmd_fprintf(f, mem->addr_format, addr);
1405 cmd_fprintf(f, " in memory %s.\n", mem->get_name());
1408 /* Non-decoded address space access */
1410 cl_error_mem_non_decoded::
1411 cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
1412 cl_error_mem(amem, aaddr)
1414 classification= mem_error_registry.find("non_decoded");
1418 cl_error_mem_non_decoded::print(class cl_commander *c)
1420 FILE *f= c->get_out();
1421 cmd_fprintf(f, "%s: access of non-decoded address ", get_type_name());
1422 cmd_fprintf(f, mem->addr_format, addr);
1423 cmd_fprintf(f, " in memory %s.\n", mem->get_name());
1426 cl_mem_error_registry::cl_mem_error_registry(void)
1428 class cl_error_class *prev = mem_error_registry.find("non-classified");
1429 prev = register_error(new cl_error_class(err_error, "memory", prev, ERROR_OFF));
1430 prev = register_error(new cl_error_class(err_error, "invalid_address", prev));
1431 prev = register_error(new cl_error_class(err_error, "non_decoded", prev));