<commit_before>/*!
	\file		src/kernel/i386/mm/pmem_pa.c	
	\author		Samuel
	\version 	3.0
	\date	
  			Created: 01-Jun-2008 17:00
  			Last modified: 01-Jun-2008 17:00
	\brief	physical memory manager initialization routines
	\note		all these routines uses physical memory and dont know about va.
*/
#include <string.h>
#include <kernel/multiboot.h>
#include <kernel/debug.h>
#include <kernel/mm/vm.h>
#include <kernel/mm/virtual_page.h>
#include <kernel/mm/pmem.h>
#include <kernel/i386/pmem.h>

extern UINT32 ebss;

#define BOOT_ADDRESS(addr)	(((UINT32)addr - KERNEL_VIRTUAL_ADDRESS_TEXT_START)+KERNEL_PHYSICAL_ADDRESS_LOAD )

#define KERNEL_PTE_FLAG		(PAGE_PRESENT | PAGE_READ_WRITE | PAGE_SUPERUSER | PAGE_GLOBAL)

static UINT32 InitMemoryArea(MEMORY_AREA_PTR ma_pa, MEMORY_MAP_PTR memory_map_array, int memory_map_count);
static void * GetFreePhysicalPage();
static void InitKernelPageDirectory(UINT32 k_map_end);
static void EnterKernelPageTableEntry(UINT32 va, UINT32 pa);


/*!
	\brief	 Initialize physical memory.
	\param	 mb_info: Pointer to multiboot info structure
	\return	 void
*/
void InitPhysicalMemoryManagerPhaseI(unsigned long magic, MULTIBOOT_INFO_PTR mbi)
{
	UINT32 vpa_size;
	if ( magic != MULTIBOOT_BOOTLOADER_MAGIC )
		return;/*we will panic in main()*/
		
	//get physical address of the memory area - currently no NUMA support for i386
	* ((int *)BOOT_ADDRESS ( &memory_area_count ) )  = 1;
	vpa_size = InitMemoryArea( (MEMORY_AREA_PTR) BOOT_ADDRESS(memory_areas), (MEMORY_MAP_PTR)mbi->mmap_addr,  mbi->mmap_length / sizeof(MEMORY_MAP) );
	
	InitKernelPageDirectory( PAGE_ALIGN_UP(&ebss) );
}

/*! Intializes the memory area information
	\return size of all virtual page array in bytes
*/
static UINT32 InitMemoryArea(MEMORY_AREA_PTR ma_pa, MEMORY_MAP_PTR memory_map_array, int memory_map_count)
{
	UINT32 total_size = 0;	//total bytes occupied by virtual page array
	int i;
	for(i=0; i<memory_map_count; i++)
	{
		//use only available RAM
		if( memory_map_array[i].type == 1 )
		{
			PHYSICAL_MEMORY_REGION_PTR pmr_pa;
			int total_virtual_pages, virtual_page_array_size;

			//if memory start is less than 1MB then skip it because we cant use it
			if ( memory_map_array[i].base_addr_low < (1024 * 1024) )
				continue;
			//we cant use the kernel code and data area
			if ( memory_map_array[i].base_addr_low < BOOT_ADDRESS(&ebss) &&
				(memory_map_array[i].base_addr_low + memory_map_array[i].length_low) > BOOT_ADDRESS(&ebss) 
				)
			{
				memory_map_array[i].base_addr_low = BOOT_ADDRESS(&ebss);
			}
			
			//calculate virtual page array size
			total_virtual_pages =  memory_map_array[i].length_low / PAGE_SIZE;
			virtual_page_array_size = PAGE_ALIGN_UP ( total_virtual_pages * sizeof(VIRTUAL_PAGE) );
			total_size += virtual_page_array_size;
			//adjust total_virtual_pages
			total_virtual_pages = (memory_map_array[i].length_low - virtual_page_array_size) / PAGE_SIZE;

			//get physical address of the physical memory region
			pmr_pa = &ma_pa->physical_memory_regions[ma_pa->physical_memory_regions_count];
			
			pmr_pa->start_physical_address = memory_map_array[i].base_addr_low + virtual_page_array_size;
			pmr_pa->end_physical_address = memory_map_array[i].base_addr_low + memory_map_array[i].length_low;
			pmr_pa->virtual_page_array = (VIRTUAL_PAGE_PTR)memory_map_array[i].base_addr_low; 
			pmr_pa->virtual_page_count = total_virtual_pages;
						
			ma_pa->physical_memory_regions_count++;
		}<commit_msg>Fixed a bug in address calculation for starting address of virtual page array<commit_after>/*!
	\file		src/kernel/i386/mm/pmem_pa.c	
	\author		Samuel
	\version 	3.0
	\date	
  			Created: 01-Jun-2008 17:00
  			Last modified: 01-Jun-2008 17:00
	\brief	physical memory manager initialization routines
	\note		all these routines uses physical memory and dont know about va.
*/
#include <string.h>
#include <kernel/multiboot.h>
#include <kernel/debug.h>
#include <kernel/mm/vm.h>
#include <kernel/mm/virtual_page.h>
#include <kernel/mm/pmem.h>
#include <kernel/i386/pmem.h>

extern UINT32 ebss;

#define BOOT_ADDRESS(addr)	(((UINT32)addr - KERNEL_VIRTUAL_ADDRESS_TEXT_START)+KERNEL_PHYSICAL_ADDRESS_LOAD )

#define KERNEL_PTE_FLAG		(PAGE_PRESENT | PAGE_READ_WRITE | PAGE_SUPERUSER | PAGE_GLOBAL)

static UINT32 InitMemoryArea(MEMORY_AREA_PTR ma_pa, MEMORY_MAP_PTR memory_map_array, int memory_map_count);
static void * GetFreePhysicalPage();
static void InitKernelPageDirectory(UINT32 k_map_end);
static void EnterKernelPageTableEntry(UINT32 va, UINT32 pa);


/*!
	\brief	 Initialize physical memory.
	\param	 mb_info: Pointer to multiboot info structure
	\return	 void
*/
void InitPhysicalMemoryManagerPhaseI(unsigned long magic, MULTIBOOT_INFO_PTR mbi)
{
	UINT32 vpa_size;
	if ( magic != MULTIBOOT_BOOTLOADER_MAGIC )
		return;/*we will panic in main()*/
		
	//get physical address of the memory area - currently no NUMA support for i386
	* ((int *)BOOT_ADDRESS ( &memory_area_count ) )  = 1;
	vpa_size = InitMemoryArea( (MEMORY_AREA_PTR) BOOT_ADDRESS(memory_areas), (MEMORY_MAP_PTR)mbi->mmap_addr,  mbi->mmap_length / sizeof(MEMORY_MAP) );
	
	InitKernelPageDirectory( PAGE_ALIGN_UP(&ebss) );
}

/*! Intializes the memory area information
	\return size of all virtual page array in bytes
*/
static UINT32 InitMemoryArea(MEMORY_AREA_PTR ma_pa, MEMORY_MAP_PTR memory_map_array, int memory_map_count)
{
	UINT32 total_size = 0;	//total bytes occupied by virtual page array
	UINT32 kernel_end = PAGE_ALIGN_UP (  BOOT_ADDRESS(&ebss) );
	int i;
	for(i=0; i<memory_map_count; i++)
	{
		//use only available RAM
		if( memory_map_array[i].type == 1 )
		{
			PHYSICAL_MEMORY_REGION_PTR pmr_pa;
			int total_virtual_pages, virtual_page_array_size;

			//if memory start is less than 1MB then skip it because we cant use it
			if ( memory_map_array[i].base_addr_low < (1024 * 1024) )
				continue;
			//we cant use the kernel code and data area
			if ( memory_map_array[i].base_addr_low <  kernel_end )
			{
				memory_map_array[i].length_low -=  kernel_end - memory_map_array[i].base_addr_low;
				memory_map_array[i].base_addr_low = kernel_end;
			}
			
			//calculate virtual page array size
			total_virtual_pages =  memory_map_array[i].length_low / PAGE_SIZE;
			virtual_page_array_size = PAGE_ALIGN_UP ( total_virtual_pages * sizeof(VIRTUAL_PAGE) );
			//adjust total_virtual_pages
			total_virtual_pages = (memory_map_array[i].length_low - virtual_page_array_size) / PAGE_SIZE;
			
			total_size += virtual_page_array_size;

			//get physical address of the physical memory region
			pmr_pa = &ma_pa->physical_memory_regions[ma_pa->physical_memory_regions_count];
			
			pmr_pa->start_physical_address = memory_map_array[i].base_addr_low + virtual_page_array_size;
			pmr_pa->end_physical_address = memory_map_array[i].base_addr_low + memory_map_array[i].length_low;
			pmr_pa->virtual_page_array = (VIRTUAL_PAGE_PTR)memory_map_array[i].base_addr_low; 
			pmr_pa->virtual_page_count = total_virtual_pages;
						
			ma_pa->physical_memory_regions_count++;
		}
{'fraction_non_alphanumeric': 0.09394631639063393, 'fraction_numerical': 0.017989720159908625, 'mean_word_length': 4.936440677966102, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4644862', 'n_tokens_mistral': 2774, 'n_tokens_neox': 2492, 'n_words': 542}