void * map_frames_direct(unsigned long count, unsigned long *start_mfn) { int i; unsigned long start_frame; void *start_va = NULL, *cur_va = NULL; if (count == 0) return NULL; if (free_mappings() < count) return NULL; start_frame = ((L2_BASE_INDEX + mmu_state.cur_l1_idx) << 8) | mmu_state.next_l2_idx; for (i = 0; i < count; i++) { cur_va = map_frame(start_frame + i); if (i == 0) start_va = cur_va; } *start_mfn = start_frame; return start_va; }
//---------------------------------------------------------------------- static void apply_symbols(void) { free_mappings(); if ( dataseg != BADADDR ) { for ( int i=0; i < numports; i++ ) { ea_t ea = calc_data_mem(ports[i].address); segment_t *s = getseg(ea); if ( s == NULL || s->type != SEG_IMEM ) continue; doByte(ea, 1); const char *name = ports[i].name; if ( !set_name(ea, name, SN_NOWARN) ) set_cmt(ea, name, 0); } ea_t ea = dataseg; segment_t *d = getseg(dataseg); if ( d != NULL ) { ea_t dataend = d->endEA; while ( 1 ) { ea = next_unknown(ea, dataend); if ( ea == BADADDR ) break; ea_t end = nextthat(ea, dataend, f_isHead, NULL); if ( end == BADADDR ) end = dataend; doByte(ea, end-ea); } create_mappings(); } } }
// create the mapping table static void create_mappings(void) { free_mappings(); for ( int i=0; i < numports; i++ ) { const char *name = ports[i].name; ea_t nameea = get_name_ea(BADADDR, name); if ( nameea != BADADDR && nameea > dataseg) add_mapping(ports[i].address, nameea-dataseg); } }
void * map_frame(unsigned long pfn) { int res = 0; uint32_t desc; void * va; if (mmu_state.next_l2_idx == L2_ENTRIES) res = alloc_l2(); if (res) { dprintk("mmu: map_frame alloc_l2 failed, res %d\n", res); return 0; } if (free_mappings() == 0) { dprintk("mmu: could not map page, no free mappings\n"); return 0; } dprintk("mmu: free_mappings() = 0x%x\n", free_mappings()); desc = DESC_SMALL_PAGE(pfn, FLAGS_CACHEABLE | FLAGS_BUFFERABLE); dprintk("mmu: l2[0x%x][0x%x] = 0x%x\n", mmu_state.cur_l1_idx, mmu_state.next_l2_idx, desc); dprintk("mmu: l2 base ptr = 0x%x\n", l2_page_table); l2_page_table[mmu_state.cur_l1_idx][mmu_state.next_l2_idx] = desc; va = (void *) (((L2_BASE_INDEX + mmu_state.cur_l1_idx) << 20) | (mmu_state.next_l2_idx << 12)); dprintk("mmu: mapped page, pfn = %ld, l1_idx = 0x%x, l2_idx = 0x%x, va = 0x%x\n", pfn, mmu_state.cur_l1_idx, mmu_state.next_l2_idx, va); mmu_state.next_l2_idx++; return va; }
void * map_frames(unsigned long *lst, unsigned long count) { int i; void *start_va = NULL; void *cur_va = NULL; if (count == 0) return NULL; if (free_mappings() < count) return NULL; for (i = 0; i < count; i++) { cur_va = map_frame(lst[i]); if (i == 0) start_va = cur_va; } return start_va; }
static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch(msgid) { case processor_t::init: helper.create("$ pic"); helper.supval(0, device, sizeof(device)); default: break; case processor_t::term: free_mappings(); free_ioports(ports, numports); break; case processor_t::newfile: // new file loaded { segment_t *s0 = get_first_seg(); if ( s0 != NULL ) { set_segm_name(s0, "CODE"); dataseg = AdditionalSegment(0x200, 0, "DATA"); segment_t *s1 = get_next_seg(s0->startEA); SetDefaultRegisterValue(s0, BANK, 0); SetDefaultRegisterValue(s1, BANK, 0); SetDefaultRegisterValue(s0, PCLATH, 0); SetDefaultRegisterValue(s1, PCLATH, 0); SetDefaultRegisterValue(s0, PCLATU, 0); SetDefaultRegisterValue(s1, PCLATU, 0); setup_device(IORESP_INT); apply_symbols(); } } break; case processor_t::oldfile: // old file loaded idpflags = (ushort)helper.altval(-1); dataseg = helper.altval(0); create_mappings(); for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) { if ( s->defsr[PCLATH-ph.regFirstSreg] == BADSEL ) s->defsr[PCLATH-ph.regFirstSreg] = 0; } break; case processor_t::closebase: case processor_t::savebase: helper.altset(0, dataseg); helper.altset(-1, idpflags); helper.supset(0, device); break; case processor_t::newprc: // new processor type { int n = va_arg(va, int); static bool set = false; if ( set ) return 0; set = true; if ( ptypes[n] != ptype ) { ptype = ptypes[n]; ph.cnbits = 12 + 2*n; } switch ( ptype ) { case PIC12: register_names[PCLATH] = "status"; cfgname = "pic12.cfg"; break; case PIC14: cfgname = "pic14.cfg"; break; case PIC16: register_names[BANK] = "bsr"; cfgname = "pic16.cfg"; idpflags = 0; ph.cnbits = 8; ph.regLastSreg = PCLATU; break; default: error("interr in setprc"); break; } } break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment break; } va_end(va); return 1; }