#include "hwcl.h"
+static class cl_mem_error_registry mem_error_registry;
+
/*
* 3rd version of memory system
*/
-cl_memory::cl_memory(char *id, t_addr asize, int awidth):
+cl_memory::cl_memory(const char *id, t_addr asize, int awidth):
cl_base()
{
size= asize;
{
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;
cl_memory::valid_address(t_addr addr)
{
return(addr >= start_address &&
- addr < start_address+size);
+ addr < start_address+size);
}
t_addr
t_addr
-cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
+cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console_base *con)
{
int i;
t_addr lva= lowest_valid_address();
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;
}
t_addr
-cl_memory::dump(class cl_console *con)
+cl_memory::dump(class cl_console_base *con)
{
return(dump(dump_finished, dump_finished+10*8-1, 8, 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;
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)
*/
cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
- t_addr addr):
+ t_addr addr):
cl_base()
{
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;
/* 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;
/* 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;
/* 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;
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);
}
}
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;
+ }
}
}
* Address space
*/
-cl_address_space::cl_address_space(char *id,
- t_addr astart, t_addr asize, int awidth):
+cl_address_space::cl_address_space(const char *id,
+ 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();
}
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 */
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<class cl_address_decoder *>(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)
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]);
}
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))
{
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_base *con)
{
#define D if (con) con->debug
D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name());
for (i= 0; i < decoders->count; i++)
{
class cl_address_decoder *d=
- dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
+ dynamic_cast<class cl_address_decoder *>(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
}
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)
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())
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);
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())
{
* Memory chip
*/
-cl_memory_chip::cl_memory_chip(char *id, int asize, int awidth, int initial):
+cl_memory_chip::cl_memory_chip(const char *id, int asize, int awidth, int initial):
cl_memory(id, asize, awidth)
{
array= (t_mem *)malloc(size * sizeof(t_mem));
int i;
for (i= 0; i < size; i++)
set(i,
- (init_value<0)?rand():(init_value));
+ (init_value<0)?rand():(init_value));
return(0);
}
*/
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;
bool
-cl_address_decoder::activate(class cl_console *con)
+cl_address_decoder::activate(class cl_console_base *con)
{
#define D if (con) con->debug
D("Activation of an address decoder\n");
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
if (begin > a)
a= begin;
while (a <= end &&
- a <= as_end)
+ a <= as_end)
{
address_space->undecode_cell(a);
a++;
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)
by_chip= bychip;
}
-void *
+const void *
cl_decoder_list::key_of(void *item)
{
class cl_address_decoder *d= (class cl_address_decoder *)item;
}
int
-cl_decoder_list::compare(void *key1, void *key2)
+cl_decoder_list::compare(const void *key1, const void *key2)
{
- t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);
+ const t_addr k1= *(static_cast<const t_addr *>(key1)), k2= *(static_cast<const t_addr*>(key2));
if (k1 == k2)
return(0);
else if (k1 > k2)
/* All of memory errors */
-class cl_error_class *cl_error_mem::error_mem_class;
-
cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
{
mem= amem;
addr= aaddr;
- if (NULL == error_mem_class)
- error_mem_class= new cl_error_class(err_error, "memory", classification, ERROR_OFF);
- classification= error_mem_class;
+ classification= mem_error_registry.find("memory");
}
/* Invalid address in memory access */
-class cl_error_class *cl_error_mem_invalid_address::error_mem_invalid_address_class;
-
cl_error_mem_invalid_address::
cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
cl_error_mem(amem, aaddr)
{
- if (NULL == error_mem_invalid_address_class)
- error_mem_invalid_address_class= new cl_error_class(err_error, "invalid_address", classification);
- classification= error_mem_invalid_address_class;
+ classification= mem_error_registry.find("invalid_address");
}
void
-cl_error_mem_invalid_address::print(class cl_commander *c)
+cl_error_mem_invalid_address::print(class cl_commander_base *c)
{
- FILE *f= c->get_out();
- cmd_fprintf(f, "%s: invalid address ", get_type_name());
- cmd_fprintf(f, mem->addr_format, addr);
- cmd_fprintf(f, " in memory %s.\n", mem->get_name());
+ c->dd_printf("%s: invalid address ", get_type_name());
+ c->dd_printf(mem->addr_format, addr);
+ c->dd_printf(" in memory %s.\n", mem->get_name());
}
/* Non-decoded address space access */
-class cl_error_class *cl_error_mem_non_decoded::error_mem_non_decoded_class;
-
cl_error_mem_non_decoded::
cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
cl_error_mem(amem, aaddr)
{
- if (NULL == error_mem_non_decoded_class)
- error_mem_non_decoded_class= new cl_error_class(err_error, "non_decoded", classification);
- classification= error_mem_non_decoded_class;
+ classification= mem_error_registry.find("non_decoded");
}
void
-cl_error_mem_non_decoded::print(class cl_commander *c)
+cl_error_mem_non_decoded::print(class cl_commander_base *c)
+{
+ c->dd_printf("%s: access of non-decoded address ", get_type_name());
+ c->dd_printf(mem->addr_format, addr);
+ c->dd_printf(" in memory %s.\n", mem->get_name());
+}
+
+cl_mem_error_registry::cl_mem_error_registry(void)
{
- FILE *f= c->get_out();
- cmd_fprintf(f, "%s: access of non-decoded address ", get_type_name());
- cmd_fprintf(f, mem->addr_format, addr);
- cmd_fprintf(f, " in memory %s.\n", mem->get_name());
+ 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));
}