X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fsim.src%2Fmem.cc;h=adf34b8cb1f723bc197f552c9fc680940f14290d;hb=a8b895ee0de37ed91bcc35e1633da977a638e4bf;hp=7d9a780fdc15ff321c9e40a6e739a28eeca0aa30;hpb=f27da39dbcab5678aca6d8462f1cc37a643f37e9;p=fw%2Fsdcc diff --git a/sim/ucsim/sim.src/mem.cc b/sim/ucsim/sim.src/mem.cc index 7d9a780f..adf34b8c 100644 --- a/sim/ucsim/sim.src/mem.cc +++ b/sim/ucsim/sim.src/mem.cc @@ -41,12 +41,15 @@ // cmd #include "newcmdcl.h" +#include "cmdutil.h" // local #include "memcl.h" #include "hwcl.h" +static class cl_mem_error_registry mem_error_registry; + /* * 3rd version of memory system */ @@ -75,12 +78,12 @@ cl_memory::init(void) { addr_format= (char *)malloc(10); sprintf(addr_format, "0x%%0%dx", - size-1<=0xf?1: - (size-1<=0xff?2: - (size-1<=0xfff?3: - (size-1<=0xffff?4: - (size-1<=0xfffff?5: - (size-1<=0xffffff?6:12)))))); + size-1<=0xf?1: + (size-1<=0xff?2: + (size-1<=0xfff?3: + (size-1<=0xffff?4: + (size-1<=0xfffff?5: + (size-1<=0xffffff?6:12)))))); data_format= (char *)malloc(10); sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0)); data_mask= 1; @@ -99,7 +102,7 @@ bool cl_memory::valid_address(t_addr addr) { return(addr >= start_address && - addr < start_address+size); + addr < start_address+size); } t_addr @@ -172,42 +175,42 @@ cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con) if (stop > hva) stop= hva; while ((start <= stop) && - (start < hva)) + (start < hva)) { con->dd_printf(addr_format, start); con->dd_printf(" "); for (i= 0; - (i < bpl) && - (start+i < hva) && - (start+i <= stop); - i++) - { - con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" "); - } + (i < bpl) && + (start+i < hva) && + (start+i <= stop); + i++) + { + con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" "); + } while (i < bpl) - { - int j; - j= width/4 + ((width%4)?1:0) + 1; - while (j) - { - con->dd_printf(" "); - j--; - } - i++; - } + { + int j; + j= width/4 + ((width%4)?1:0) + 1; + while (j) + { + con->dd_printf(" "); + j--; + } + i++; + } for (i= 0; (i < bpl) && - (start+i < hva) && - (start+i <= stop); - i++) - { - long c= read(start+i); - con->dd_printf("%c", isprint(255&c)?(255&c):'.'); - if (width > 8) - con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.'); - if (width > 16) - con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.'); - if (width > 24) - con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.'); - } + (start+i < hva) && + (start+i <= stop); + i++) + { + long c= read(start+i); + con->dd_printf("%c", isprint(255&c)?(255&c):'.'); + if (width > 8) + con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.'); + if (width > 16) + con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.'); + if (width > 24) + con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.'); + } con->dd_printf("\n"); dump_finished= start+i; start+= bpl; @@ -223,7 +226,7 @@ cl_memory::dump(class cl_console *con) bool cl_memory::search_next(bool case_sensitive, - t_mem *array, int len, t_addr *addr) + t_mem *array, int len, t_addr *addr) { t_addr a; int i; @@ -239,26 +242,26 @@ cl_memory::search_next(bool case_sensitive, found= DD_FALSE; while (!found && - a+len <= size) + a+len <= size) { bool match= DD_TRUE; for (i= 0; i < len && match; i++) - { - t_mem d1, d2; - d1= get(a+i); - d2= array[i]; - if (!case_sensitive) - { - if (/*d1 < 128*/isalpha(d1)) - d1= toupper(d1); - if (/*d2 < 128*/isalpha(d2)) - d2= toupper(d2); - } - match= d1 == d2; - } + { + t_mem d1, d2; + d1= get(a+i); + d2= array[i]; + if (!case_sensitive) + { + if (/*d1 < 128*/isalpha(d1)) + d1= toupper(d1); + if (/*d2 < 128*/isalpha(d2)) + d2= toupper(d2); + } + match= d1 == d2; + } found= match; if (!found) - a++; + a++; } if (addr) @@ -272,7 +275,7 @@ cl_memory::search_next(bool case_sensitive, */ cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell, - t_addr addr): + t_addr addr): cl_base() { cell= acell; @@ -283,8 +286,8 @@ cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell, } cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell, - t_addr addr, - t_mem *data_place, t_mem the_mask): + t_addr addr, + t_mem *data_place, t_mem the_mask): cl_base() { cell= acell; @@ -324,8 +327,8 @@ cl_memory_operator::write(t_mem val) /* Memory operator for hw callbacks */ cl_hw_operator::cl_hw_operator(class cl_memory_cell *acell, t_addr addr, - t_mem *data_place, t_mem the_mask, - class cl_hw *ahw): + t_mem *data_place, t_mem the_mask, + class cl_hw *ahw): cl_memory_operator(acell, addr, data_place, the_mask) { hw= ahw; @@ -375,8 +378,8 @@ cl_hw_operator::write(t_mem val) /* Write event break on cell */ cl_write_operator::cl_write_operator(class cl_memory_cell *acell, t_addr addr, - t_mem *data_place, t_mem the_mask, - class cl_uc *auc, class cl_brk *the_bp): + t_mem *data_place, t_mem the_mask, + class cl_uc *auc, class cl_brk *the_bp): cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp) { uc= auc; @@ -398,8 +401,8 @@ cl_write_operator::write(t_mem val) /* Read event break on cell */ cl_read_operator::cl_read_operator(class cl_memory_cell *acell, t_addr addr, - t_mem *data_place, t_mem the_mask, - class cl_uc *auc, class cl_brk *the_bp): + t_mem *data_place, t_mem the_mask, + class cl_uc *auc, class cl_brk *the_bp): cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp) { uc= auc; @@ -429,6 +432,7 @@ cl_memory_cell::cl_memory_cell(void): flags= CELL_NON_DECODED; width= 8; *data= 0; + operators= NULL; #ifdef STATISTIC nuof_writes= nuof_reads= 0; @@ -601,10 +605,10 @@ cl_memory_cell::append_operator(class cl_memory_operator *op) class cl_memory_operator *o= operators, *n; n= o->get_next(); while (n) - { - o= n; - n= o->get_next(); - } + { + o= n; + n= o->get_next(); + } o->set_next(op); } } @@ -633,14 +637,14 @@ cl_memory_cell::del_operator(class cl_brk *brk) else { while (op->get_next() && - !op->get_next()->match(brk)) - op= op->get_next(); + !op->get_next()->match(brk)) + op= op->get_next(); if (op->get_next()) - { - class cl_memory_operator *m= op->get_next(); - op->set_next(m->get_next());; - delete m; - } + { + class cl_memory_operator *m= op->get_next(); + op->set_next(m->get_next());; + delete m; + } } } @@ -693,18 +697,13 @@ cl_dummy_cell::set(t_mem val) */ cl_address_space::cl_address_space(char *id, - t_addr astart, t_addr asize, int awidth): + t_addr astart, t_addr asize, int awidth): cl_memory(id, asize, awidth) { start_address= astart; decoders= new cl_decoder_list(2, 2, DD_FALSE); - cells= (class cl_memory_cell **)malloc(size * sizeof(class cl_memory_cell*)); - int i; - for (i= 0; i < size; i++) - { - cells[i]= new cl_memory_cell(); - cells[i]->init(); - } + cells= (class cl_memory_cell **)calloc(size, sizeof(class cl_memory_cell*)); + dummy= new cl_dummy_cell(); } @@ -722,79 +721,42 @@ cl_address_space::~cl_address_space(void) t_mem cl_address_space::read(t_addr addr) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - { - err_inv_addr(addr); - return(dummy->read()); - } - return(cells[idx]->read()); + return get_cell(addr)->read(); } t_mem cl_address_space::read(t_addr addr, enum hw_cath skip) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) + cl_memory_cell *cell = get_cell(addr); + if (cell == dummy) { - err_inv_addr(addr); - return(dummy->read()); + return dummy->read(); } - return(cells[idx]->read(skip)); + return cell->read(skip); } t_mem cl_address_space::get(t_addr addr) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - { - err_inv_addr(addr); - return(dummy->get()); - } - return(cells[idx]->get()); + return get_cell(addr)->get(); } t_mem cl_address_space::write(t_addr addr, t_mem val) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - { - err_inv_addr(addr); - return(dummy->write(val)); - } - return(cells[idx]->write(val)); + return get_cell(addr)->write(val); } void cl_address_space::set(t_addr addr, t_mem val) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - { - err_inv_addr(addr); - dummy->set(val); - return; - } - cells[idx]->set(val); + get_cell(addr)->set(val); } t_mem cl_address_space::wadd(t_addr addr, long what) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - { - err_inv_addr(addr); - } - return(cells[idx]->wadd(what)); + return get_cell(addr)->wadd(what); } /* Set or clear bits, without callbacks */ @@ -802,25 +764,42 @@ cl_address_space::wadd(t_addr addr, long what) void cl_address_space::set_bit1(t_addr addr, t_mem bits) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) + cl_memory_cell *cell = get_cell(addr); + if (cell == dummy) + { return; - class cl_memory_cell *cell= cells[idx]; + } cell->set_bit1(bits); } void cl_address_space::set_bit0(t_addr addr, t_mem bits) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - return; - class cl_memory_cell *cell= cells[idx]; + cl_memory_cell *cell = get_cell(addr); + if (cell == dummy) + { + return; + } cell->set_bit0(bits); } +class cl_address_decoder * +cl_address_space::get_decoder(t_addr addr) +{ + int i; + for (i= 0; i < decoders->count; i++) + { + class cl_address_decoder *d= + dynamic_cast(decoders->object_at(i)); + if (!d) + continue; + if (d->covers(addr, addr)) + { + return d; + } + } + return NULL; +} class cl_memory_cell * cl_address_space::get_cell(t_addr addr) @@ -832,6 +811,18 @@ cl_address_space::get_cell(t_addr addr) err_inv_addr(addr); return(dummy); } + if (cells[idx] == NULL) + { + cells[idx]= new cl_memory_cell(); + cells[idx]->init(); + class cl_address_decoder *decoder; + decoder = get_decoder(addr); + if (decoder && decoder->activated) + { + decode_cell(addr, decoder->memchip, + addr - decoder->as_begin + decoder->chip_begin); + } + } return(cells[idx]); } @@ -839,53 +830,31 @@ cl_address_space::get_cell(t_addr addr) int cl_address_space::get_cell_flag(t_addr addr) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - { - return(dummy->get_flags()); - } - return(cells[addr]->get_flags()); + return get_cell(addr)->get_flags(); } bool cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - { - return(dummy->get_flag(flag)); - } - return(cells[addr]->get_flag(flag)); + return get_cell(addr)->get_flag(flag); } void cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag) { - t_addr idx= addr-start_address; - class cl_memory_cell *cell; - - if (idx >= size || - addr < start_address) - { - cell= dummy; - } - else - cell= cells[addr]; - cell->set_flag(flag, set_to); + get_cell(addr)->set_flag(flag, set_to); } bool cl_address_space::decode_cell(t_addr addr, - class cl_memory_chip *chip, t_addr chipaddr) + class cl_memory_chip *chip, t_addr chipaddr) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - return(DD_FALSE); - class cl_memory_cell *cell= cells[idx]; + cl_memory_cell *cell = get_cell(addr); + if (cell == dummy) + { + return(DD_FALSE); + } if (!cell->get_flag(CELL_NON_DECODED)) { @@ -903,15 +872,20 @@ cl_address_space::undecode_cell(t_addr addr) t_addr idx= addr-start_address; if (idx >= size || addr < start_address) - return; - class cl_memory_cell *cell= cells[idx]; - - cell->un_decode(); + { + err_inv_addr(addr); + return; + } + if (cells[idx] == NULL) + { + return; + } + cells[idx]->un_decode(); } void cl_address_space::undecode_area(class cl_address_decoder *skip, - t_addr begin, t_addr end,class cl_console *con) + t_addr begin, t_addr end,class cl_console *con) { #define D if (con) con->debug D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name()); @@ -919,57 +893,57 @@ cl_address_space::undecode_area(class cl_address_decoder *skip, for (i= 0; i < decoders->count; i++) { class cl_address_decoder *d= - dynamic_cast(decoders->object_at(i)); + dynamic_cast(decoders->object_at(i)); if (!d || - d == skip) - continue; + d == skip) + continue; D(" Checking decoder 0x%x-0x%x -> %s[0x%x]\n", - d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin); + d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin); if (d->fully_covered_by(begin, end)) - { - // decoder can be removed - D(" Can be removed\n"); - decoders->disconn(d); - i--; - delete d; - if (decoders->count == 0) - break; - } + { + // decoder can be removed + D(" Can be removed\n"); + decoders->disconn(d); + i--; + delete d; + if (decoders->count == 0) + break; + } else if (d->covers(begin, end)) - { - // decoder must be split - D(" Must be split\n"); - class cl_address_decoder *nd= d->split(begin, end); - D(" After split:\n"); - D(" 0x%x-0x%x -> %s[0x%x]\n", - d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin); - if (nd) - { - decoders->add(nd); - D(" 0x%x-0x%x -> %s[0x%x]\n", - nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin); - nd->activate(con); - } - } + { + // decoder must be split + D(" Must be split\n"); + class cl_address_decoder *nd= d->split(begin, end); + D(" After split:\n"); + D(" 0x%x-0x%x -> %s[0x%x]\n", + d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin); + if (nd) + { + decoders->add(nd); + D(" 0x%x-0x%x -> %s[0x%x]\n", + nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin); + nd->activate(con); + } + } else if (d->is_in(begin, end)) - { - // decoder sould shrink - D(" Sould shrink\n"); - if (d->shrink_out_of(begin, end)) - { - D(" Can be removed after shrink\n"); - decoders->disconn(d); - i--; - delete d; - if (decoders->count == 0) - break; - } - else - { - D(" Shrinked to 0x%x-0x%x -> %s[0x%x]\n", - d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin); - } - } + { + // decoder sould shrink + D(" Sould shrink\n"); + if (d->shrink_out_of(begin, end)) + { + D(" Can be removed after shrink\n"); + decoders->disconn(d); + i--; + delete d; + if (decoders->count == 0) + break; + } + else + { + D(" Shrinked to 0x%x-0x%x -> %s[0x%x]\n", + d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin); + } + } } #undef D } @@ -977,14 +951,14 @@ cl_address_space::undecode_area(class cl_address_decoder *skip, class cl_memory_cell * cl_address_space::register_hw(t_addr addr, class cl_hw *hw, - int *ith, - bool announce) + int *ith, + bool announce) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - return(0); - class cl_memory_cell *cell= cells[idx]; + cl_memory_cell *cell = get_cell(addr); + if (cell == dummy) + { + return(NULL); + } cell->add_hw(hw, ith, addr); //printf("adding hw %s to cell 0x%x(%d) of %s\n", hw->id_string, addr, idx, get_name("as")); if (announce) @@ -996,11 +970,12 @@ cl_address_space::register_hw(t_addr addr, class cl_hw *hw, void cl_address_space::set_brk(t_addr addr, class cl_brk *brk) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - return; - class cl_memory_cell *cell= cells[idx]; + cl_memory_cell *cell = get_cell(addr); + if (cell == dummy) + { + return; + } + class cl_memory_operator *op; switch (brk->get_event()) @@ -1008,12 +983,12 @@ cl_address_space::set_brk(t_addr addr, class cl_brk *brk) case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: //e= 'W'; op= new cl_write_operator(cell, addr, cell->get_data(), cell->get_mask(), - uc, brk); + uc, brk); break; case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR: //e= 'R'; op= new cl_read_operator(cell, addr, cell->get_data(), cell->get_mask(), - uc, brk); + uc, brk); break; case brkNONE: set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK); @@ -1031,11 +1006,11 @@ cl_address_space::set_brk(t_addr addr, class cl_brk *brk) void cl_address_space::del_brk(t_addr addr, class cl_brk *brk) { - t_addr idx= addr-start_address; - if (idx >= size || - addr < start_address) - return; - class cl_memory_cell *cell= cells[idx]; + cl_memory_cell *cell = get_cell(addr); + if (cell == dummy) + { + return; + } switch (brk->get_event()) { @@ -1101,7 +1076,7 @@ cl_memory_chip::init(void) int i; for (i= 0; i < size; i++) set(i, - (init_value<0)?rand():(init_value)); + (init_value<0)?rand():(init_value)); return(0); } @@ -1158,8 +1133,8 @@ cl_memory_chip::set_bit0(t_addr addr, t_mem bits) */ cl_address_decoder::cl_address_decoder(class cl_memory *as, - class cl_memory *chip, - t_addr asb, t_addr ase, t_addr cb) + class cl_memory *chip, + t_addr asb, t_addr ase, t_addr cb) { if (as->is_address_space()) address_space= (class cl_address_space *)as; @@ -1236,16 +1211,6 @@ cl_address_decoder::activate(class cl_console *con) address_space->undecode_area(this, as_begin, as_end, con); - t_addr asa, ca; - for (asa= as_begin, ca= chip_begin; - asa <= as_end; - asa++, ca++) - { - if (!address_space->decode_cell(asa, memchip, ca)) - { - D("Decoding 0x%06x->0x%06x failed\n", asa, ca); - } - } activated= DD_TRUE; #undef D @@ -1296,7 +1261,7 @@ cl_address_decoder::shrink_out_of(t_addr begin, t_addr end) if (begin > a) a= begin; while (a <= end && - a <= as_end) + a <= as_end) { address_space->undecode_cell(a); a++; @@ -1320,15 +1285,15 @@ cl_address_decoder::split(t_addr begin, t_addr end) if (begin > as_begin) { if (as_end > end) - nd= new cl_address_decoder(address_space, memchip, - end+1, as_end, chip_begin+(end-as_begin)+1); + nd= new cl_address_decoder(address_space, memchip, + end+1, as_end, chip_begin+(end-as_begin)+1); shrink_out_of(begin, as_end); } else if (end < as_end) { if (as_begin < begin) - nd= new cl_address_decoder(address_space, memchip, - as_begin, begin-1, chip_begin); + nd= new cl_address_decoder(address_space, memchip, + as_begin, begin-1, chip_begin); shrink_out_of(end+1, as_end); } if (nd) @@ -1375,62 +1340,54 @@ cl_decoder_list::compare(void *key1, void *key2) */ /* All of memory errors */ -ERROR_CLASS_DEF_PARENT_ON(err_error, mem, "memory", - error_class_base, ERROR_ON); cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr) { mem= amem; addr= aaddr; - classification= &error_mem_class; + classification= mem_error_registry.find("memory"); } /* Invalid address in memory access */ -ERROR_CLASS_DEF_PARENT(err_error, - mem_invalid_address, - "invalid_address", - error_mem_class); cl_error_mem_invalid_address:: cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr): cl_error_mem(amem, aaddr) { - classification= &error_mem_invalid_address_class; + classification= mem_error_registry.find("invalid_address"); } void cl_error_mem_invalid_address::print(class cl_commander *c) { - c->dd_printf(get_type_name()); - c->dd_printf(": invalid address ", get_type_name()); + c->dd_printf("%s: invalid address ", get_type_name()); c->dd_printf(mem->addr_format, addr); - c->dd_printf(" in memory "); - c->dd_printf(mem->get_name()); - c->dd_printf(".\n"); + c->dd_printf(" in memory %s.\n", mem->get_name()); } /* Non-decoded address space access */ -ERROR_CLASS_DEF_PARENT(err_error, - mem_non_decoded, - "non_decoded", - error_mem_class); cl_error_mem_non_decoded:: cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr): cl_error_mem(amem, aaddr) { - classification= &error_mem_non_decoded_class; + classification= mem_error_registry.find("non_decoded"); } void cl_error_mem_non_decoded::print(class cl_commander *c) { - c->dd_printf(get_type_name()); - c->dd_printf(": access of non-decoded address "); + c->dd_printf("%s: access of non-decoded address ", get_type_name()); c->dd_printf(mem->addr_format, addr); - c->dd_printf(" in memory "); - c->dd_printf(mem->get_name()); - c->dd_printf(".\n"); + c->dd_printf(" in memory %s.\n", mem->get_name()); +} + +cl_mem_error_registry::cl_mem_error_registry(void) +{ + class cl_error_class *prev = mem_error_registry.find("non-classified"); + prev = register_error(new cl_error_class(err_error, "memory", prev, ERROR_OFF)); + prev = register_error(new cl_error_class(err_error, "invalid_address", prev)); + prev = register_error(new cl_error_class(err_error, "non_decoded", prev)); }