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(const 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_base *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_base *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(const 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 **)calloc(size, sizeof(class cl_memory_cell*));
707 dummy= new cl_dummy_cell();
710 cl_address_space::~cl_address_space(void)
714 for (i= 0; i < size; i++)
722 cl_address_space::read(t_addr addr)
724 return get_cell(addr)->read();
728 cl_address_space::read(t_addr addr, enum hw_cath skip)
730 cl_memory_cell *cell = get_cell(addr);
733 return dummy->read();
735 return cell->read(skip);
739 cl_address_space::get(t_addr addr)
741 return get_cell(addr)->get();
745 cl_address_space::write(t_addr addr, t_mem val)
747 return get_cell(addr)->write(val);
751 cl_address_space::set(t_addr addr, t_mem val)
753 get_cell(addr)->set(val);
757 cl_address_space::wadd(t_addr addr, long what)
759 return get_cell(addr)->wadd(what);
762 /* Set or clear bits, without callbacks */
765 cl_address_space::set_bit1(t_addr addr, t_mem bits)
767 cl_memory_cell *cell = get_cell(addr);
772 cell->set_bit1(bits);
776 cl_address_space::set_bit0(t_addr addr, t_mem bits)
778 cl_memory_cell *cell = get_cell(addr);
783 cell->set_bit0(bits);
786 class cl_address_decoder *
787 cl_address_space::get_decoder(t_addr addr)
790 for (i= 0; i < decoders->count; i++)
792 class cl_address_decoder *d=
793 dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
796 if (d->covers(addr, addr))
804 class cl_memory_cell *
805 cl_address_space::get_cell(t_addr addr)
807 t_addr idx= addr-start_address;
809 addr < start_address)
814 if (cells[idx] == NULL)
816 cells[idx]= new cl_memory_cell();
818 class cl_address_decoder *decoder;
819 decoder = get_decoder(addr);
820 if (decoder && decoder->activated)
822 decode_cell(addr, decoder->memchip,
823 addr - decoder->as_begin + decoder->chip_begin);
831 cl_address_space::get_cell_flag(t_addr addr)
833 return get_cell(addr)->get_flags();
837 cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag)
839 return get_cell(addr)->get_flag(flag);
843 cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag)
845 get_cell(addr)->set_flag(flag, set_to);
850 cl_address_space::decode_cell(t_addr addr,
851 class cl_memory_chip *chip, t_addr chipaddr)
853 cl_memory_cell *cell = get_cell(addr);
859 if (!cell->get_flag(CELL_NON_DECODED))
864 cell->decode(chip, chipaddr);
866 return(!cell->get_flag(CELL_NON_DECODED));
870 cl_address_space::undecode_cell(t_addr addr)
872 t_addr idx= addr-start_address;
874 addr < start_address)
879 if (cells[idx] == NULL)
883 cells[idx]->un_decode();
887 cl_address_space::undecode_area(class cl_address_decoder *skip,
888 t_addr begin, t_addr end,class cl_console_base *con)
890 #define D if (con) con->debug
891 D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name());
893 for (i= 0; i < decoders->count; i++)
895 class cl_address_decoder *d=
896 dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
900 D(" Checking decoder 0x%x-0x%x -> %s[0x%x]\n",
901 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
902 if (d->fully_covered_by(begin, end))
904 // decoder can be removed
905 D(" Can be removed\n");
906 decoders->disconn(d);
909 if (decoders->count == 0)
912 else if (d->covers(begin, end))
914 // decoder must be split
915 D(" Must be split\n");
916 class cl_address_decoder *nd= d->split(begin, end);
917 D(" After split:\n");
918 D(" 0x%x-0x%x -> %s[0x%x]\n",
919 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
923 D(" 0x%x-0x%x -> %s[0x%x]\n",
924 nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin);
928 else if (d->is_in(begin, end))
930 // decoder sould shrink
931 D(" Sould shrink\n");
932 if (d->shrink_out_of(begin, end))
934 D(" Can be removed after shrink\n");
935 decoders->disconn(d);
938 if (decoders->count == 0)
943 D(" Shrinked to 0x%x-0x%x -> %s[0x%x]\n",
944 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
952 class cl_memory_cell *
953 cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
957 cl_memory_cell *cell = get_cell(addr);
962 cell->add_hw(hw, ith, addr);
963 //printf("adding hw %s to cell 0x%x(%d) of %s\n", hw->id_string, addr, idx, get_name("as"));
965 ;//uc->sim->/*app->*/mem_cell_changed(this, addr);//FIXME
971 cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
973 cl_memory_cell *cell = get_cell(addr);
979 class cl_memory_operator *op;
981 switch (brk->get_event())
983 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
985 op= new cl_write_operator(cell, addr, cell->get_data(), cell->get_mask(),
988 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
990 op= new cl_read_operator(cell, addr, cell->get_data(), cell->get_mask(),
994 set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
1003 cell->append_operator(op);
1007 cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
1009 cl_memory_cell *cell = get_cell(addr);
1015 switch (brk->get_event())
1017 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1018 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1019 cell->del_operator(brk);
1022 set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
1032 * List of address spaces
1035 cl_address_space_list::cl_address_space_list(class cl_uc *the_uc):
1036 cl_list(2, 2, "address spaces")
1042 cl_address_space_list::add(class cl_address_space *mem)
1045 t_index ret= cl_list::add(mem);
1048 class cl_event_address_space_added e(mem);
1049 uc->handle_event(e);
1059 cl_memory_chip::cl_memory_chip(const char *id, int asize, int awidth, int initial):
1060 cl_memory(id, asize, awidth)
1062 array= (t_mem *)malloc(size * sizeof(t_mem));
1063 init_value= initial;
1066 cl_memory_chip::~cl_memory_chip(void)
1073 cl_memory_chip::init(void)
1077 for (i= 0; i < size; i++)
1079 (init_value<0)?rand():(init_value));
1085 cl_memory_chip::get_slot(t_addr addr)
1090 return(&array[addr]);
1095 cl_memory_chip::get(t_addr addr)
1100 return(array[addr]);
1104 cl_memory_chip::set(t_addr addr, t_mem val)
1109 array[addr]= val & data_mask;
1113 cl_memory_chip::set_bit1(t_addr addr, t_mem bits)
1118 array[addr]|= (bits & data_mask);
1122 cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
1127 array[addr]&= ((~bits) & data_mask);
1135 cl_address_decoder::cl_address_decoder(class cl_memory *as,
1136 class cl_memory *chip,
1137 t_addr asb, t_addr ase, t_addr cb)
1139 if (as->is_address_space())
1140 address_space= (class cl_address_space *)as;
1143 if (chip->is_chip())
1144 memchip= (class cl_memory_chip *)chip;
1150 activated= DD_FALSE;
1153 cl_address_decoder::~cl_address_decoder(void)
1157 for (a= as_begin; a <= as_end; a++)
1158 address_space->undecode_cell(a);
1162 cl_address_decoder::init(void)
1169 cl_address_decoder::activate(class cl_console_base *con)
1171 #define D if (con) con->debug
1172 D("Activation of an address decoder\n");
1175 D("Already activated\n");
1178 if (!address_space ||
1179 !address_space->is_address_space())
1181 D("No or non address space\n");
1185 !memchip->is_chip())
1187 D("No or non memory chip\n");
1190 if (as_begin > as_end)
1192 D("Wrong address area specification\n");
1195 if (chip_begin >= memchip->get_size())
1197 D("Wrong chip area specification\n");
1200 if (as_begin < address_space->start_address ||
1201 as_end >= address_space->start_address + address_space->get_size())
1203 D("Specified area is out of address space\n");
1206 if (as_end-as_begin > memchip->get_size()-chip_begin)
1208 D("Specified area is out of chip size\n");
1212 address_space->undecode_area(this, as_begin, as_end, con);
1222 cl_address_decoder::fully_covered_by(t_addr begin, t_addr end)
1224 if (begin <= as_begin &&
1231 cl_address_decoder::is_in(t_addr begin, t_addr end)
1233 if (begin >= as_begin &&
1236 if (end >= as_begin &&
1243 cl_address_decoder::covers(t_addr begin, t_addr end)
1245 if (begin > as_begin &&
1252 /* Returns TRUE if shrunken decoder is unnecessary */
1255 cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
1266 address_space->undecode_cell(a);
1269 if (begin > as_begin)
1273 chip_begin+= (end-as_begin+1);
1276 if (as_end < as_begin)
1281 class cl_address_decoder *
1282 cl_address_decoder::split(t_addr begin, t_addr end)
1284 class cl_address_decoder *nd= 0;
1285 if (begin > as_begin)
1288 nd= new cl_address_decoder(address_space, memchip,
1289 end+1, as_end, chip_begin+(end-as_begin)+1);
1290 shrink_out_of(begin, as_end);
1292 else if (end < as_end)
1294 if (as_begin < begin)
1295 nd= new cl_address_decoder(address_space, memchip,
1296 as_begin, begin-1, chip_begin);
1297 shrink_out_of(end+1, as_end);
1306 * List of address decoders
1309 cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):
1310 cl_sorted_list(alimit, adelta, "decoder list")
1312 Duplicates= DD_TRUE;
1317 cl_decoder_list::key_of(void *item)
1319 class cl_address_decoder *d= (class cl_address_decoder *)item;
1321 return(&(d->chip_begin));
1323 return(&(d->as_begin));
1327 cl_decoder_list::compare(const void *key1, const void *key2)
1329 const t_addr k1= *(static_cast<const t_addr *>(key1)), k2= *(static_cast<const t_addr*>(key2));
1339 * Errors in memory handling
1342 /* All of memory errors */
1344 cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
1348 classification= mem_error_registry.find("memory");
1351 /* Invalid address in memory access */
1353 cl_error_mem_invalid_address::
1354 cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
1355 cl_error_mem(amem, aaddr)
1357 classification= mem_error_registry.find("invalid_address");
1361 cl_error_mem_invalid_address::print(class cl_commander_base *c)
1363 c->dd_printf("%s: invalid address ", get_type_name());
1364 c->dd_printf(mem->addr_format, addr);
1365 c->dd_printf(" in memory %s.\n", mem->get_name());
1368 /* Non-decoded address space access */
1370 cl_error_mem_non_decoded::
1371 cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
1372 cl_error_mem(amem, aaddr)
1374 classification= mem_error_registry.find("non_decoded");
1378 cl_error_mem_non_decoded::print(class cl_commander_base *c)
1380 c->dd_printf("%s: access of non-decoded address ", get_type_name());
1381 c->dd_printf(mem->addr_format, addr);
1382 c->dd_printf(" in memory %s.\n", mem->get_name());
1385 cl_mem_error_registry::cl_mem_error_registry(void)
1387 class cl_error_class *prev = mem_error_registry.find("non-classified");
1388 prev = register_error(new cl_error_class(err_error, "memory", prev, ERROR_OFF));
1389 prev = register_error(new cl_error_class(err_error, "invalid_address", prev));
1390 prev = register_error(new cl_error_class(err_error, "non_decoded", prev));