예제 #1
0
void createPageTableEntry(uint64_t address,uint64_t physical_address,uint64_t cr3_content){
	int pml4e_index = getpml4e_index(address);
	uint64_t *pml4e_block = (uint64_t*)(cr3_content );

	if(pml4e_block[pml4e_index] == 0){
		//////print("##pml4e--index= %d##",pml4e_index);
		uint64_t pdpte_block = create_page_block(512);
		pml4e_block[pml4e_index] = get_physical_address(pdpte_block & ALIGN_4KB_PAGE) | PTE_P | PTE_W | PTE_U;
	}

	uint64_t *pdtpe_block = (uint64_t*)get_linear_address(pml4e_block[pml4e_index] & ALIGN_4KB_PAGE) ;
	int pdtpe_index = getpdpte_index(address);
	if(pdtpe_block[pdtpe_index] == 0){
		//	////print("##-pdtpe--index= %d--##",pdtpe_index);
		uint64_t pde_block = create_page_block(512);
		pdtpe_block[pdtpe_index] = get_physical_address(pde_block & ALIGN_4KB_PAGE) | PTE_P | PTE_W | PTE_U;
	}

	uint64_t *pde_block = (uint64_t*)get_linear_address(pdtpe_block[pdtpe_index] & ALIGN_4KB_PAGE);
	int pde_index = getpde_index(address);
	if(pde_block[pde_index] == 0){
		//	////print("-@@pde--index= %d@@--",pde_index);
		uint64_t pte_block = create_page_block(512);
		pde_block[pde_index] = get_physical_address(pte_block & ALIGN_4KB_PAGE) | PTE_P | PTE_W | PTE_U;
	}

	uint64_t *pte_block = (uint64_t*)get_linear_address(pde_block[pde_index] & ALIGN_4KB_PAGE);
	int pte_index = getpte_index(address);
//	if(pte_block[pte_index] == 0){
		//	////print("-!!pte--index= %d!!--",pte_index);
	uint64_t pageBlock = physical_address ;
		//pageBlock = pageBlock & ALIGN_4KB_PAGE;
	pte_block[pte_index] = pageBlock | PTE_P | PTE_W | PTE_U;
//	}
}
예제 #2
0
파일: modules.c 프로젝트: podusowski/draco
void modules_init(multiboot_info_t * multiboot_info)
{
	printf("[ "MODULE_NAME" ] loading multiboot modules\n");

	uint32 i;
	void * proc_mem;

	module_t *modules = (module_t *)multiboot_info->mods_addr;
	for (i = 0; i < multiboot_info->mods_count; i++)
	{

		/** ELF EXEC */
		/*
		if (*((char *)(modules[i].mod_start)) == 0x7f)
		{
			elf_dump(modules[i].mod_start);
			printf("%s ", modules[i].string);
			elf_exec(modules[i].string, modules[i].mod_start, modules[i].mod_end - modules[i].mod_start);
			continue;
		}
		*/

		//printf("  %s\n", modules[i].string);

		proc_mem = proc_createenv(modules[i].mod_end - modules[i].mod_start);
		memcpy(get_physical_address(proc_mem, KERNEL_MEMORY), modules[i].mod_start, modules[i].mod_end - modules[i].mod_start);
		proc_add(modules[i].string, PROC_CLASS_A, proc_mem, modules[i].mod_end - modules[i].mod_start, KERNEL_MEMORY);
	}
}
예제 #3
0
void enable_paging(uint64_t cr3_content){
	uint64_t physical_addr = get_physical_address((uint64_t)cr3_content);
	//	__asm__("cli");	
	__asm__ volatile("mov %0, %%cr3;"

			:
			:"r"(physical_addr)
			:
			);
	//	__asm__("sti");
}
예제 #4
0
/* Initialize a SE linked list. */
void ll_init(se_ll_t *ll, void *buffer, size_t size) {
    ll->num_entries = 0; /* 1 Entry. */

    if (buffer != NULL) {
        ll->addr_info.address = (uint32_t) get_physical_address(buffer);
        ll->addr_info.size = (uint32_t) size;
    } else {
        ll->addr_info.address = 0;
        ll->addr_info.size = 0;
    }
    
    flush_dcache_range((uint8_t *)ll, (uint8_t *)ll + sizeof(*ll));
}
예제 #5
0
int add_transaction(	tick_t now, int transaction_type, int slot_id,int *chan_id){
	transaction_t   *this_t = NULL;
	uint64_t    address = 0;
	addresses_t     this_a; 
	int		transaction_index;
	int		thread_id;
	thread_id = get_thread_id(global_biu,slot_id);

		address 			= get_physical_address(global_biu, slot_id);
		this_a.physical_address 	= address;
		// We need to setup an option in case address is already broken down!
		if (convert_address(dram_system.config.physical_address_mapping_policy, &dram_system.config,&(this_a)) == ADDRESS_MAPPING_FAILURE) {
		  /* ignore address mapping failure for now... */
	  }
//	  if(thread_id != -1){
	  if(thread_id != -1 ){
		int scramble_id = get_thread_set(thread_id);
		this_a.chan_id     = (this_a.chan_id + scramble_id) % dram_system.config.channel_count;
		this_a.rank_id     = (this_a.rank_id + scramble_id) % dram_system.config.rank_count;
		this_a.bank_id     = (this_a.bank_id + scramble_id) % dram_system.config.bank_count;
		this_a.row_id      = (this_a.row_id + scramble_id) % dram_system.config.row_count;
	  }

	*chan_id = this_a.chan_id;
	if(dram_system.dram_controller[this_a.chan_id].transaction_queue.transaction_count >= (dram_system.config.max_tq_size)){
	  return MEM_STATE_INVALID;
	} 
	transaction_index = dram_system.dram_controller[this_a.chan_id].transaction_queue.transaction_count;
	if (dram_system.dram_controller[this_a.chan_id].transaction_queue.transaction_count <= 0) {
	  dram_system.tq_info.last_transaction_retired_time = dram_system.current_dram_time;
	  //fprintf(stdout,"Reset retired time to %llu\n",dram_system.tq_info.last_transaction_retired_time);
	}
	this_a.thread_id = thread_id;
	this_t = &(dram_system.dram_controller[this_a.chan_id].transaction_queue.entry[transaction_index]);	/* in order queue. Grab next entry */
	
	this_t->status 			= MEM_STATE_VALID;
	this_t->arrival_time 		= now;
	this_t->completion_time 	= 0;
	this_t->transaction_type 	= transaction_type;
	this_t->transaction_id 	= dram_system.tq_info.transaction_id_ctr++;
	this_t->slot_id			= slot_id;
	this_t->critical_word_ready	= FALSE;
	this_t->critical_word_available	= FALSE;
	this_t->critical_word_ready_time= 0;
	this_t->issued_data = false;
	this_t->issued_command = false;
	this_t->issued_cas = false;
	this_t->issued_ras = false;
	this_t->tindex = transaction_index;


	// Update Address
	this_t->address.physical_address= address;
	this_t->address.chan_id= this_a.chan_id;
	this_t->address.bank_id= this_a.bank_id;
	this_t->address.rank_id= this_a.rank_id;
	this_t->address.row_id= this_a.row_id;
	  /* STATS FOR RANK & CHANNEL */
	  rank_distrib[ this_a.chan_id ][ this_a.rank_id ]++;
	  tot_reqs++;

	  /* */
		
	mem_gather_stat(GATHER_REQUEST_LOCALITY_STAT, (int)address);		/* send this address to the stat collection */

	if(get_transaction_debug()){
		print_addresses(&(this_a));
	}
	/*
	//Ohm--stat for dram_access
	dram_system.dram_controller[this_a.chan_id].rank[this_a.rank_id].r_p_info.dram_access++;
	dram_system.dram_controller[this_a.chan_id].rank[this_a.rank_id].r_p_gblinfo.dram_access++;
	*/
	this_t->next_c = transaction2commands(now,
			this_t->transaction_id,
			transaction_type,
			&(this_a)); 
	this_t->status = MEM_STATE_SCHEDULED;
	dram_system.dram_controller[this_a.chan_id].transaction_queue.transaction_count++;

	/* If the transaction selection policy is MOST/LEAST than you sort it */
	int trans_sel_policy = get_transaction_selection_policy(global_biu);
	if (trans_sel_policy == MOST_PENDING || trans_sel_policy == LEAST_PENDING) {
	  add_trans_pending_queue(this_a.chan_id,transaction_index);
	}
	
	if (transaction_type == MEMORY_WRITE_COMMAND) {
	  if (dram_system.dram_controller[this_t->address.chan_id].active_write_trans++ > 4) 
		dram_system.dram_controller[this_t->address.chan_id].active_write_flag = true;
	}
	return transaction_index;
}
예제 #6
0
signed int dma_init_channel(uint8_t direction, uint32_t channel, int segmentationSetting, uint32_t txrx_register, uint32_t size, uint32_t Setting1Index, uint32_t Setting2Index, void* handler) {
	int i = 0;
	DMAInfo* dma = &dmaInfo[channel];

	if (!dma->signalled) {
		dma->segmentBuffer = memalign(0x20, 32 * sizeof(*dma->segmentBuffer));
		memset(dma->segmentBuffer, 0, (32 * sizeof(*dma->segmentBuffer)));

		//bufferPrintf("cdma: new segment buffer 0x%08x.\r\n", dma->segmentBuffer);

		if (!dma->segmentBuffer)
			system_panic("CDMA: can't allocate command chain\r\n");

		for (i = 0; i != 32; i ++)
			dma->segmentBuffer[i].address = get_physical_address((uint32_t)(&dma->segmentBuffer[i+1]));

		dma->signalled = 1;
		dma->txrx_register = 0;
		dma->unk_separator = 0;

		interrupt_set_int_type(DMA_CHANNEL_INTERRUPT_BASE + channel, 0);
		interrupt_install(DMA_CHANNEL_INTERRUPT_BASE + channel, dmaIRQHandler, channel);
		interrupt_enable(DMA_CHANNEL_INTERRUPT_BASE + channel);
	}

	dma->irq_state = 0;
	dma->dmaSegmentNumber = 0;
	dma->segmentationSetting = segmentationSetting;
	dma->segmentOffset = 0;
	dma->dataSize = size;
	dma->unsegmentedSize = size;
	dma->handler = handler;
	dma->channel = channel;

	uint8_t Setting1;
	uint8_t Setting2;

	switch(Setting1Index)
	{
	case 1:
		Setting1 = 0 << 2;
		break;

	case 2:
		Setting1 = 1 << 2;
		break;

	case 4:
		Setting1 = 2 << 2;
		break;

	default:
		return -1;
	}

	switch (Setting2Index)
	{
	case 1:
		Setting2 = 0 << 4;
		break;

	case 2:
		Setting2 = 1 << 4;
		break;

	case 4:
		Setting2 = 2 << 4;
		break;

	case 8:
		Setting2 = 3 << 4;
		break;

	case 16:
		Setting2 = 4 << 4;
		break;

	case 32:
		Setting2 = 5 << 4;
		break;

	default:
		return -1;
	}

	uint32_t channel_reg = channel << 12;
	SET_REG(DMA + channel_reg, 2);

	uint8_t direction_setting;
	if (direction == 1) // if out
		direction_setting = 1 << 1;
	else
		direction_setting = 0 << 1;

	SET_REG(DMA + DMA_SETTINGS + channel_reg, dma->unk_separator | Setting1 | Setting2 | direction_setting);
	SET_REG(DMA + DMA_TXRX_REGISTER + channel_reg, txrx_register);
	SET_REG(DMA + DMA_SIZE + channel_reg, size);

	if (dma->dmaAESInfo)
		dma->current_segment = 0;

	dma_continue_async(channel);
	return 0;
}
예제 #7
0
void dma_continue_async(int channel) {

	//bufferPrintf("cdma: continue_async.\r\n");

	uint32_t endOffset;
	uint8_t segmentId;
	uint32_t segmentLength;
	uint32_t value;
	DMAInfo* dma = &dmaInfo[channel];

	if (!dma->unsegmentedSize)
		system_panic("CDMA: ASSERT FAILED\r\n");

	dma->previousUnsegmentedSize = dma->unsegmentedSize;
	dma->previousDmaSegmentNumber = dma->dmaSegmentNumber;
	dma->previousSegmentOffset = dma->segmentOffset;

	if (dma->dmaAESInfo)
	{
		endOffset = dma->segmentationSetting + 8 * dma->dmaSegmentNumber;
		for (segmentId = 0; segmentId != 28;) {
			if (!dma->unsegmentedSize)
				break;

			dma->segmentBuffer[segmentId].value = 2;
			dma->dmaAESInfo->ivGenerator(dma->dmaAESInfo->ivParameter, dma->current_segment, dma->segmentBuffer[segmentId].iv);
			segmentId++;
			dma->current_segment++;
			segmentLength = 0;

			int encryptedSegmentOffset;
			int encryptedSegmentOffsetEnd = 0;
			for (encryptedSegmentOffset = 0; encryptedSegmentOffset < dma->dmaAESInfo->dataSize; encryptedSegmentOffset += segmentLength) {
				encryptedSegmentOffsetEnd = dma->dmaAESInfo->dataSize;
				if (encryptedSegmentOffset >= encryptedSegmentOffsetEnd)
					break;

				segmentLength = endOffset + 4 - dma->segmentOffset;
				if (encryptedSegmentOffset + segmentLength > encryptedSegmentOffsetEnd)
					segmentLength = encryptedSegmentOffsetEnd - encryptedSegmentOffset;

				value = 0x10003;
				if (!encryptedSegmentOffset)
					value = 0x30003;

				dma->segmentBuffer[segmentId].value = value;
				dma->segmentBuffer[segmentId].offset = dma->segmentOffset + endOffset;
				dma->segmentBuffer[segmentId].length = segmentLength;

				if (!segmentLength)
					system_panic("Caught trying to generate zero-length cdma segment on channel %d, irqState: %d\r\n", channel, dma->irq_state);

				dma->segmentOffset += segmentLength;

				if (dma->segmentOffset >= endOffset + 4)
				{
					endOffset += 8;
					++dma->dmaSegmentNumber;
					dma->segmentOffset = 0;
				}

				++segmentId;
			}

			dma->unsegmentedSize -= encryptedSegmentOffsetEnd;
		}

		if (!dma->unsegmentedSize)
			dma->segmentBuffer[segmentId-1].value |= 0x100;

		dma->segmentBuffer[segmentId].value = 0;
	} else {
		for (segmentId = 0; segmentId < 31; segmentId++) {
			int segmentLength = dma->segmentationSetting + 8 * dma->dmaSegmentNumber + 4 - dma->segmentOffset;

			dma->segmentBuffer[segmentId].value = 3;
			dma->segmentBuffer[segmentId].offset = dma->segmentationSetting + 8 * dma->dmaSegmentNumber + dma->segmentOffset;
			dma->segmentBuffer[segmentId].length = segmentLength;

			if (!segmentLength)
				system_panic("Caught trying to generate zero-length cdma segment on channel %d, irqState: %d\r\n", channel, dma->irq_state);

			dma->segmentOffset = 0;

			if (segmentLength >= dma->unsegmentedSize) {
				dma->segmentBuffer[segmentId].value |= 0x100;
				dma->unsegmentedSize = 0;
				break;
			}

			dma->unsegmentedSize -= segmentLength;
			dma->dmaSegmentNumber++;
		}

		dma->segmentBuffer[segmentId+1].value = 0;
	}

	DataCacheOperation(1, (uint32_t)dma->segmentBuffer, 32 * sizeof(*dma->segmentBuffer));

	uint32_t channel_reg = channel << 12;
	SET_REG(DMA + channel_reg + 0x14, get_physical_address((uint32_t)dma->segmentBuffer));

	value = 0x1C0009;

	if (dma->dmaAESInfo)
		value |= (dma->dmaAES_channel << 8);

	//bufferPrintf("cdma: continue async 0x%08x.\r\n", value);
	SET_REG(DMA + channel_reg, value);
}