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
52 * 3rd version of memory system
55 cl_memory::cl_memory(char *id, t_addr asize, int awidth):
60 addr_format= data_format= 0;
66 cl_memory::~cl_memory(void)
77 addr_format= (char *)malloc(10);
78 sprintf(addr_format, "0x%%0%dx",
84 (size-1<=0xffffff?6:12))))));
85 data_format= (char *)malloc(10);
86 sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0));
94 dump_finished= start_address;
100 cl_memory::valid_address(t_addr addr)
102 return(addr >= start_address &&
103 addr < start_address+size);
107 cl_memory::inc_address(t_addr addr, int val)
110 return(((signed)addr+val)%size);
111 addr-= start_address;
114 addr+= start_address;
119 cl_memory::inc_address(t_addr addr)
122 return(((signed)addr+1)%size);
123 addr-= start_address;
126 addr+= start_address;
131 cl_memory::validate_address(t_addr addr)
133 while (addr < start_address)
135 if (addr > start_address+size)
137 addr-= start_address;
139 addr+= start_address;
146 cl_memory::err_inv_addr(t_addr addr)
150 class cl_error *e= new cl_error_mem_invalid_address(this, addr);
155 cl_memory::err_non_decoded(t_addr addr)
159 class cl_error *e= new cl_error_mem_non_decoded(this, addr);
165 cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
168 t_addr lva= lowest_valid_address();
169 t_addr hva= highest_valid_address();
175 while ((start <= stop) &&
178 con->dd_printf(addr_format, start); con->dd_printf(" ");
185 con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" ");
190 j= width/4 + ((width%4)?1:0) + 1;
198 for (i= 0; (i < bpl) &&
203 long c= read(start+i);
204 con->dd_printf("%c", isprint(255&c)?(255&c):'.');
206 con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
208 con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
210 con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
212 con->dd_printf("\n");
213 dump_finished= start+i;
216 return(dump_finished);
220 cl_memory::dump(class cl_console *con)
222 return(dump(dump_finished, dump_finished+10*8-1, 8, con));
226 cl_memory::search_next(bool case_sensitive,
227 t_mem *array, int len, t_addr *addr)
246 for (i= 0; i < len && match; i++)
253 if (/*d1 < 128*/isalpha(d1))
255 if (/*d2 < 128*/isalpha(d2))
275 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
286 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
288 t_mem *data_place, t_mem the_mask):
299 cl_memory_operator::set_data(t_mem *data_place, t_mem the_mask)
307 cl_memory_operator::read(void)
310 return(next_operator->read());
316 cl_memory_operator::write(t_mem val)
319 return(next_operator->write(val));
321 return(*data= (val & mask));
325 /* Memory operator for hw callbacks */
327 cl_hw_operator::cl_hw_operator(class cl_memory_cell *acell, t_addr addr,
328 t_mem *data_place, t_mem the_mask,
330 cl_memory_operator(acell, addr, data_place, the_mask)
337 cl_hw_operator::read(void)
345 next_operator->read();
351 cl_hw_operator::read(enum hw_cath skip)
356 hw->cathegory != skip)
360 next_operator->read();
366 cl_hw_operator::write(t_mem val)
369 hw->write(cell, &val);
371 val= next_operator->write(val);
372 return(*data= (val & mask));
376 /* Write event break on cell */
378 cl_write_operator::cl_write_operator(class cl_memory_cell *acell, t_addr addr,
379 t_mem *data_place, t_mem the_mask,
380 class cl_uc *auc, class cl_brk *the_bp):
381 cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp)
388 cl_write_operator::write(t_mem val)
390 //printf("write event at 0x%x bp=%p\n",address,bp);
393 return(next_operator->write(val));
395 return(*data= (val & mask));
399 /* Read event break on cell */
401 cl_read_operator::cl_read_operator(class cl_memory_cell *acell, t_addr addr,
402 t_mem *data_place, t_mem the_mask,
403 class cl_uc *auc, class cl_brk *the_bp):
404 cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp)
411 cl_read_operator::read(void)
413 //printf("read event at 0x%x bp=%p\n",address,bp);
416 return(next_operator->read());
426 cl_memory_cell::cl_memory_cell(void):
429 data= (t_mem *)malloc(sizeof(t_mem));
430 flags= CELL_NON_DECODED;
436 nuof_writes= nuof_reads= 0;
448 cl_memory_cell::~cl_memory_cell(void)
450 if ((flags & CELL_NON_DECODED) &&
456 cl_memory_cell::init(void)
465 cl_memory_cell::get_flags(void)
471 cl_memory_cell::get_flag(enum cell_flag flag)
473 return(flags & flag);
477 cl_memory_cell::set_flags(TYPE_UBYTE what)
483 cl_memory_cell::set_flag(enum cell_flag flag, bool val)
493 cl_memory_cell::un_decode(void)
495 if ((flags & CELL_NON_DECODED) == 0)
497 data= (t_mem *)malloc(sizeof(t_mem));
498 flags|= CELL_NON_DECODED;
503 cl_memory_cell::decode(class cl_memory_chip *chip, t_addr addr)
505 if (flags & CELL_NON_DECODED)
507 data= chip->get_slot(addr);
510 data= (t_mem *)malloc(sizeof(t_mem));
511 flags|= CELL_NON_DECODED;
514 flags&= ~(CELL_NON_DECODED);
519 cl_memory_cell::read(void)
525 return(operators->read());
530 cl_memory_cell::read(enum hw_cath skip)
536 return(operators->read(skip));
541 cl_memory_cell::get(void)
547 cl_memory_cell::write(t_mem val)
553 return(operators->write(val));
559 cl_memory_cell::set(t_mem val)
568 cl_memory_cell::add(long what)
570 *data= (*data + what) & mask;
575 cl_memory_cell::wadd(long what)
577 t_mem d= (*data + what) & mask;
582 cl_memory_cell::set_bit1(t_mem bits)
589 cl_memory_cell::set_bit0(t_mem bits)
597 cl_memory_cell::append_operator(class cl_memory_operator *op)
603 class cl_memory_operator *o= operators, *n;
615 cl_memory_cell::prepend_operator(class cl_memory_operator *op)
619 op->set_next(operators);
625 cl_memory_cell::del_operator(class cl_brk *brk)
629 class cl_memory_operator *op= operators;
630 if (operators->match(brk))
632 operators= op->get_next();
637 while (op->get_next() &&
638 !op->get_next()->match(brk))
642 class cl_memory_operator *m= op->get_next();
643 op->set_next(m->get_next());;
650 class cl_memory_cell *
651 cl_memory_cell::add_hw(class cl_hw *hw, int *ith, t_addr addr)
653 class cl_hw_operator *o= new cl_hw_operator(this, addr, data, mask, hw);
659 cl_memory_cell::get_hw(int ith)
664 class cl_event_handler *
665 cl_memory_cell::get_event_handler(void)
672 * Dummy cell for non-existent addresses
676 cl_dummy_cell::write(t_mem val)
681 *data= rand() & mask;
686 cl_dummy_cell::set(t_mem val)
688 *data= rand() & mask;
697 cl_address_space::cl_address_space(char *id,
698 t_addr astart, t_addr asize, int awidth):
699 cl_memory(id, asize, awidth)
701 start_address= astart;
702 decoders= new cl_decoder_list(2, 2, DD_FALSE);
703 cells= (class cl_memory_cell **)malloc(size * sizeof(class cl_memory_cell*));
705 for (i= 0; i < size; i++)
707 cells[i]= new cl_memory_cell();
710 dummy= new cl_dummy_cell();
713 cl_address_space::~cl_address_space(void)
717 for (i= 0; i < size; i++)
725 cl_address_space::read(t_addr addr)
727 t_addr idx= addr-start_address;
729 addr < start_address)
732 return(dummy->read());
734 return(cells[idx]->read());
738 cl_address_space::read(t_addr addr, enum hw_cath skip)
740 t_addr idx= addr-start_address;
742 addr < start_address)
745 return(dummy->read());
747 return(cells[idx]->read(skip));
751 cl_address_space::get(t_addr addr)
753 t_addr idx= addr-start_address;
755 addr < start_address)
758 return(dummy->get());
760 return(cells[idx]->get());
764 cl_address_space::write(t_addr addr, t_mem val)
766 t_addr idx= addr-start_address;
768 addr < start_address)
771 return(dummy->write(val));
773 return(cells[idx]->write(val));
777 cl_address_space::set(t_addr addr, t_mem val)
779 t_addr idx= addr-start_address;
781 addr < start_address)
787 cells[idx]->set(val);
791 cl_address_space::wadd(t_addr addr, long what)
793 t_addr idx= addr-start_address;
795 addr < start_address)
799 return(cells[idx]->wadd(what));
802 /* Set or clear bits, without callbacks */
805 cl_address_space::set_bit1(t_addr addr, t_mem bits)
807 t_addr idx= addr-start_address;
809 addr < start_address)
811 class cl_memory_cell *cell= cells[idx];
812 cell->set_bit1(bits);
816 cl_address_space::set_bit0(t_addr addr, t_mem bits)
818 t_addr idx= addr-start_address;
820 addr < start_address)
822 class cl_memory_cell *cell= cells[idx];
823 cell->set_bit0(bits);
827 class cl_memory_cell *
828 cl_address_space::get_cell(t_addr addr)
830 t_addr idx= addr-start_address;
832 addr < start_address)
842 cl_address_space::get_cell_flag(t_addr addr)
844 t_addr idx= addr-start_address;
846 addr < start_address)
848 return(dummy->get_flags());
850 return(cells[addr]->get_flags());
854 cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag)
856 t_addr idx= addr-start_address;
858 addr < start_address)
860 return(dummy->get_flag(flag));
862 return(cells[addr]->get_flag(flag));
866 cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag)
868 t_addr idx= addr-start_address;
869 class cl_memory_cell *cell;
872 addr < start_address)
878 cell->set_flag(flag, set_to);
883 cl_address_space::decode_cell(t_addr addr,
884 class cl_memory_chip *chip, t_addr chipaddr)
886 t_addr idx= addr-start_address;
888 addr < start_address)
890 class cl_memory_cell *cell= cells[idx];
892 if (!cell->get_flag(CELL_NON_DECODED))
897 cell->decode(chip, chipaddr);
899 return(!cell->get_flag(CELL_NON_DECODED));
903 cl_address_space::undecode_cell(t_addr addr)
905 t_addr idx= addr-start_address;
907 addr < start_address)
909 class cl_memory_cell *cell= cells[idx];
915 cl_address_space::undecode_area(class cl_address_decoder *skip,
916 t_addr begin, t_addr end,class cl_console *con)
918 #define D if (con) con->debug
919 D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name());
921 for (i= 0; i < decoders->count; i++)
923 class cl_address_decoder *d=
924 dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
928 D(" Checking decoder 0x%x-0x%x -> %s[0x%x]\n",
929 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
930 if (d->fully_covered_by(begin, end))
932 // decoder can be removed
933 D(" Can be removed\n");
934 decoders->disconn(d);
937 if (decoders->count == 0)
940 else if (d->covers(begin, end))
942 // decoder must be split
943 D(" Must be split\n");
944 class cl_address_decoder *nd= d->split(begin, end);
945 D(" After split:\n");
946 D(" 0x%x-0x%x -> %s[0x%x]\n",
947 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
951 D(" 0x%x-0x%x -> %s[0x%x]\n",
952 nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin);
956 else if (d->is_in(begin, end))
958 // decoder sould shrink
959 D(" Sould shrink\n");
960 if (d->shrink_out_of(begin, end))
962 D(" Can be removed after shrink\n");
963 decoders->disconn(d);
966 if (decoders->count == 0)
971 D(" Shrinked to 0x%x-0x%x -> %s[0x%x]\n",
972 d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
980 class cl_memory_cell *
981 cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
985 t_addr idx= addr-start_address;
987 addr < start_address)
989 class cl_memory_cell *cell= cells[idx];
990 cell->add_hw(hw, ith, addr);
991 //printf("adding hw %s to cell 0x%x(%d) of %s\n", hw->id_string, addr, idx, get_name("as"));
993 ;//uc->sim->/*app->*/mem_cell_changed(this, addr);//FIXME
999 cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
1001 t_addr idx= addr-start_address;
1003 addr < start_address)
1005 class cl_memory_cell *cell= cells[idx];
1006 class cl_memory_operator *op;
1008 switch (brk->get_event())
1010 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1012 op= new cl_write_operator(cell, addr, cell->get_data(), cell->get_mask(),
1015 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1017 op= new cl_read_operator(cell, addr, cell->get_data(), cell->get_mask(),
1021 set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
1030 cell->append_operator(op);
1034 cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
1036 t_addr idx= addr-start_address;
1038 addr < start_address)
1040 class cl_memory_cell *cell= cells[idx];
1042 switch (brk->get_event())
1044 case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
1045 case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
1046 cell->del_operator(brk);
1049 set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
1059 * List of address spaces
1062 cl_address_space_list::cl_address_space_list(class cl_uc *the_uc):
1063 cl_list(2, 2, "address spaces")
1069 cl_address_space_list::add(class cl_address_space *mem)
1072 t_index ret= cl_list::add(mem);
1075 class cl_event_address_space_added e(mem);
1076 uc->handle_event(e);
1086 cl_memory_chip::cl_memory_chip(char *id, int asize, int awidth, int initial):
1087 cl_memory(id, asize, awidth)
1089 array= (t_mem *)malloc(size * sizeof(t_mem));
1090 init_value= initial;
1093 cl_memory_chip::~cl_memory_chip(void)
1100 cl_memory_chip::init(void)
1104 for (i= 0; i < size; i++)
1106 (init_value<0)?rand():(init_value));
1112 cl_memory_chip::get_slot(t_addr addr)
1117 return(&array[addr]);
1122 cl_memory_chip::get(t_addr addr)
1127 return(array[addr]);
1131 cl_memory_chip::set(t_addr addr, t_mem val)
1136 array[addr]= val & data_mask;
1140 cl_memory_chip::set_bit1(t_addr addr, t_mem bits)
1145 array[addr]|= (bits & data_mask);
1149 cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
1154 array[addr]&= ((~bits) & data_mask);
1162 cl_address_decoder::cl_address_decoder(class cl_memory *as,
1163 class cl_memory *chip,
1164 t_addr asb, t_addr ase, t_addr cb)
1166 if (as->is_address_space())
1167 address_space= (class cl_address_space *)as;
1170 if (chip->is_chip())
1171 memchip= (class cl_memory_chip *)chip;
1177 activated= DD_FALSE;
1180 cl_address_decoder::~cl_address_decoder(void)
1184 for (a= as_begin; a <= as_end; a++)
1185 address_space->undecode_cell(a);
1189 cl_address_decoder::init(void)
1196 cl_address_decoder::activate(class cl_console *con)
1198 #define D if (con) con->debug
1199 D("Activation of an address decoder\n");
1202 D("Already activated\n");
1205 if (!address_space ||
1206 !address_space->is_address_space())
1208 D("No or non address space\n");
1212 !memchip->is_chip())
1214 D("No or non memory chip\n");
1217 if (as_begin > as_end)
1219 D("Wrong address area specification\n");
1222 if (chip_begin >= memchip->get_size())
1224 D("Wrong chip area specification\n");
1227 if (as_begin < address_space->start_address ||
1228 as_end >= address_space->start_address + address_space->get_size())
1230 D("Specified area is out of address space\n");
1233 if (as_end-as_begin > memchip->get_size()-chip_begin)
1235 D("Specified area is out of chip size\n");
1239 address_space->undecode_area(this, as_begin, as_end, con);
1242 for (asa= as_begin, ca= chip_begin;
1246 if (!address_space->decode_cell(asa, memchip, ca))
1248 D("Decoding 0x%06x->0x%06x failed\n", asa, ca);
1259 cl_address_decoder::fully_covered_by(t_addr begin, t_addr end)
1261 if (begin <= as_begin &&
1268 cl_address_decoder::is_in(t_addr begin, t_addr end)
1270 if (begin >= as_begin &&
1273 if (end >= as_begin &&
1280 cl_address_decoder::covers(t_addr begin, t_addr end)
1282 if (begin > as_begin &&
1289 /* Returns TRUE if shrunken decoder is unnecessary */
1292 cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
1303 address_space->undecode_cell(a);
1306 if (begin > as_begin)
1310 chip_begin+= (end-as_begin+1);
1313 if (as_end < as_begin)
1318 class cl_address_decoder *
1319 cl_address_decoder::split(t_addr begin, t_addr end)
1321 class cl_address_decoder *nd= 0;
1322 if (begin > as_begin)
1325 nd= new cl_address_decoder(address_space, memchip,
1326 end+1, as_end, chip_begin+(end-as_begin)+1);
1327 shrink_out_of(begin, as_end);
1329 else if (end < as_end)
1331 if (as_begin < begin)
1332 nd= new cl_address_decoder(address_space, memchip,
1333 as_begin, begin-1, chip_begin);
1334 shrink_out_of(end+1, as_end);
1343 * List of address decoders
1346 cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):
1347 cl_sorted_list(alimit, adelta, "decoder list")
1349 Duplicates= DD_TRUE;
1354 cl_decoder_list::key_of(void *item)
1356 class cl_address_decoder *d= (class cl_address_decoder *)item;
1358 return(&(d->chip_begin));
1360 return(&(d->as_begin));
1364 cl_decoder_list::compare(void *key1, void *key2)
1366 t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);
1376 * Errors in memory handling
1379 /* All of memory errors */
1381 class cl_error_class *cl_error_mem::error_mem_class;
1383 cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
1387 if (NULL == error_mem_class)
1388 error_mem_class= new cl_error_class(err_error, "memory", classification, ERROR_OFF);
1389 classification= error_mem_class;
1392 /* Invalid address in memory access */
1394 class cl_error_class *cl_error_mem_invalid_address::error_mem_invalid_address_class;
1396 cl_error_mem_invalid_address::
1397 cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
1398 cl_error_mem(amem, aaddr)
1400 if (NULL == error_mem_invalid_address_class)
1401 error_mem_invalid_address_class= new cl_error_class(err_error, "invalid_address", classification);
1402 classification= error_mem_invalid_address_class;
1406 cl_error_mem_invalid_address::print(class cl_commander *c)
1408 FILE *f= c->get_out();
1409 cmd_fprintf(f, "%s: invalid address ", get_type_name());
1410 cmd_fprintf(f, mem->addr_format, addr);
1411 cmd_fprintf(f, " in memory %s.\n", mem->get_name());
1414 /* Non-decoded address space access */
1416 class cl_error_class *cl_error_mem_non_decoded::error_mem_non_decoded_class;
1418 cl_error_mem_non_decoded::
1419 cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
1420 cl_error_mem(amem, aaddr)
1422 if (NULL == error_mem_non_decoded_class)
1423 error_mem_non_decoded_class= new cl_error_class(err_error, "non_decoded", classification);
1424 classification= error_mem_non_decoded_class;
1428 cl_error_mem_non_decoded::print(class cl_commander *c)
1430 FILE *f= c->get_out();
1431 cmd_fprintf(f, "%s: access of non-decoded address ", get_type_name());
1432 cmd_fprintf(f, mem->addr_format, addr);
1433 cmd_fprintf(f, " in memory %s.\n", mem->get_name());