From a7fa9e9172deef4164d9d81c8da43ec0229c34ad Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 20 Mar 2018 16:16:53 +0100 Subject: bsp/pc386: Move libcpu content to bsps This patch is a part of the BSP source reorganization. Update #3285. --- c/src/lib/libcpu/i386/Makefile.am | 17 -- c/src/lib/libcpu/i386/configure.ac | 28 -- c/src/lib/libcpu/i386/cpuModel.S | 273 ------------------- c/src/lib/libcpu/i386/displayCpu.c | 243 ----------------- c/src/lib/libcpu/i386/idtr.S | 115 -------- c/src/lib/libcpu/i386/page.c | 519 ------------------------------------- 6 files changed, 1195 deletions(-) delete mode 100644 c/src/lib/libcpu/i386/Makefile.am delete mode 100644 c/src/lib/libcpu/i386/configure.ac delete mode 100644 c/src/lib/libcpu/i386/cpuModel.S delete mode 100644 c/src/lib/libcpu/i386/displayCpu.c delete mode 100644 c/src/lib/libcpu/i386/idtr.S delete mode 100644 c/src/lib/libcpu/i386/page.c (limited to 'c/src/lib/libcpu') diff --git a/c/src/lib/libcpu/i386/Makefile.am b/c/src/lib/libcpu/i386/Makefile.am deleted file mode 100644 index ec7a4c4a48..0000000000 --- a/c/src/lib/libcpu/i386/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -ACLOCAL_AMFLAGS = -I ../../../aclocal - -noinst_PROGRAMS = - -include $(top_srcdir)/../../../automake/compile.am - -noinst_PROGRAMS += score.rel -score_rel_SOURCES = displayCpu.c cpuModel.S cpuModel.h idtr.S cpu.h -score_rel_CPPFLAGS = $(AM_CPPFLAGS) -score_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -noinst_PROGRAMS += page.rel -page_rel_SOURCES = page.c page.h -page_rel_CPPFLAGS = $(AM_CPPFLAGS) -page_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/lib/libcpu/i386/configure.ac b/c/src/lib/libcpu/i386/configure.ac deleted file mode 100644 index 3f0f59543a..0000000000 --- a/c/src/lib/libcpu/i386/configure.ac +++ /dev/null @@ -1,28 +0,0 @@ -## Process this file with autoconf to produce a configure script. - -AC_PREREQ([2.69]) -AC_INIT([rtems-c-src-lib-libcpu-i386],[_RTEMS_VERSION],[https://devel.rtems.org/newticket]) -AC_CONFIG_SRCDIR([idtr.S]) -RTEMS_TOP([../../../../..],[../../..]) -RTEMS_SOURCE_TOP -RTEMS_BUILD_TOP - -RTEMS_CANONICAL_TARGET_CPU - -AM_INIT_AUTOMAKE([no-define foreign subdir-objects 1.12.2]) -AM_MAINTAINER_MODE - -RTEMS_ENV_RTEMSBSP - -RTEMS_PROJECT_ROOT - -RTEMS_PROG_CC_FOR_TARGET -AM_PROG_CC_C_O -RTEMS_CANONICALIZE_TOOLS -RTEMS_PROG_CCAS - -RTEMS_AMPOLISH3 - -# Explicitly list all Makefiles here -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/c/src/lib/libcpu/i386/cpuModel.S b/c/src/lib/libcpu/i386/cpuModel.S deleted file mode 100644 index b2e4ddce9e..0000000000 --- a/c/src/lib/libcpu/i386/cpuModel.S +++ /dev/null @@ -1,273 +0,0 @@ -/* cpuModel.S - * - * This file contains all assembly code for the Intel Cpu identification. - * It is based on linux cpu detection code. - * - * Intel also provides public similar code in the book - * called : - * - * Pentium Processor Family - * Developer Family - * Volume 3 : Architecture and Programming Manual - * - * At the following place : - * - * Chapter 5 : Feature determination - * Chapter 25: CPUID instruction - * - * COPYRIGHT (c) 1998 valette@crf.canon.fr - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -BEGIN_CODE - PUBLIC(checkCPUtypeSetCr0); -/* - * check Processor type: 386, 486, 6x86(L) or CPUID capable processor - */ - -SYM (checkCPUtypeSetCr0): - /* - * Assume 386 for now - */ - movl $3, SYM (x86) - /* - * Start using the EFLAGS AC bit determination method described in - * the book mentioned above page 5.1. If this bit can be set we - * have a 486 or above. - */ - pushfl /* save EFLAGS */ - - pushfl /* Get EFLAGS in EAX */ - popl eax - - movl eax,ecx /* save original EFLAGS in ECX */ - xorl $EFLAGS_ALIGN_CHECK,eax /* flip AC bit in EAX */ - pushl eax /* set EAX as EFLAGS */ - popfl - pushfl /* Get new EFLAGS in EAX */ - popl eax - - xorl ecx,eax /* check if AC bit changed */ - andl $EFLAGS_ALIGN_CHECK,eax - je is386 /* If not : we have a 386 */ - /* - * Assume 486 for now - */ - movl $4,SYM (x86) - movl ecx,eax /* Restore orig EFLAGS in EAX */ - xorl $EFLAGS_ID,eax /* flip ID flag */ - pushl eax /* set EAX as EFLAGS */ - popfl - pushfl /* Get new EFLAGS in EAX */ - popl eax - - xorl ecx,eax /* check if ID bit changed */ - andl $EFLAGS_ID,eax - - /* - * if we are on a straight 486DX, - * SX, or 487SX we can't change it - * OTOH 6x86MXs and MIIs check OK - * Also if we are on a Cyrix 6x86(L) - */ - je is486x - -isnew: - /* - * restore original EFLAGS - */ - popfl - incl SYM(have_cpuid) /* we have CPUID instruction */ - - /* - * Addressable Processor Ids - * - * CPUID.(EAX=4, ECX=0):EAX[31:26] + 1 = Y) - */ - movl $4, eax - movl $0, ecx - cpuid - movl eax,SYM(x86_capability_cores) - - /* use it to get : - * processor type, - * processor model, - * processor mask, - * by using it with EAX = 1 - */ - movl $1, eax - cpuid - movl ebx,SYM(x86_capability_ebx) /* store ebx feature info */ - movl ecx,SYM(x86_capability_x) /* store ecx feature flags */ - - movb al, cl /* save reg for future use */ - - andb $0x0f,ah /* mask processor family */ - movb ah,SYM (x86) /* put result in x86 var */ - - andb $0xf0, al /* get model */ - shrb $4, al - movb al,SYM (x86_model) /* store it in x86_model */ - - andb $0x0f, cl /* get mask revision */ - movb cl,SYM (x86_mask) /* store it in x86_mask */ - - movl edx,SYM(x86_capability) /* store feature flags in x86_capability */ - - /* get vendor info by using CPUID with EXA = 0 */ - xorl eax, eax - cpuid - - /* - * store results contained in ebx, edx, ecx in - * x86_vendor_id variable. - */ - movl ebx,SYM(x86_vendor_id) - movl edx,SYM(x86_vendor_id)+4 - movl ecx,SYM(x86_vendor_id)+8 - - movl cr0,eax /* 486+ */ - andl $(CR0_PAGING | CR0_PROTECTION_ENABLE | CR0_EXTENSION_TYPE), eax - orl $(CR0_ALIGMENT_MASK | CR0_WRITE_PROTECT | CR0_NUMERIC_ERROR | CR0_MONITOR_COPROC),eax - jmp 2f - -/* Now we test if we have a Cyrix 6x86(L). We didn't test before to avoid - * clobbering the new BX chipset used with the Pentium II, which has a register - * at the same addresses as those used to access the Cyrix special configuration - * registers (CCRs). - */ - /* - * A Cyrix/IBM 6x86(L) preserves flags after dividing 5 by 2 - * (and it _must_ be 5 divided by 2) while other CPUs change - * them in undefined ways. We need to know this since we may - * need to enable the CPUID instruction at least. - * We couldn't use this test before since the PPro and PII behave - * like Cyrix chips in this respect. - */ -is486x: xor ax,ax - sahf - movb $5,al - movb $2,bl - div bl - lahf - cmpb $2,ah - jne ncyrix - /* - * N.B. The pattern of accesses to 0x22 and 0x23 is *essential* - * so do not try to "optimize" it! For the same reason we - * do all this with interrupts off. - */ -#define setCx86(reg, val) \ - movb reg,al; \ - outb al,$0x22; \ - movb val,al; \ - outb al,$0x23 - -#define getCx86(reg) \ - movb reg,al; \ - outb al,$0x22; \ - inb $0x23,al - - cli - getCx86($0xc3) /* get CCR3 */ - movb al,cl /* Save old value */ - movb al,bl - andb $0x0f,bl /* Enable access to all config registers */ - orb $0x10,bl /* by setting bit 4 */ - setCx86($0xc3,bl) - - getCx86($0xe8) /* now we can get CCR4 */ - orb $0x80,al /* and set bit 7 (CPUIDEN) */ - movb al,bl /* to enable CPUID execution */ - setCx86($0xe8,bl) - - getCx86($0xfe) /* DIR0 : let's check this is a 6x86(L) */ - andb $0xf0,al /* should be 3xh */ - cmpb $0x30,al - jne n6x86 - getCx86($0xe9) /* CCR5 : we reset the SLOP bit */ - andb $0xfd,al /* so that udelay calculation */ - movb al,bl /* is correct on 6x86(L) CPUs */ - setCx86($0xe9,bl) - setCx86($0xc3,cl) /* Restore old CCR3 */ - sti - jmp isnew /* We enabled CPUID now */ - -n6x86: setCx86($0xc3,cl) /* Restore old CCR3 */ - sti -ncyrix: /* restore original EFLAGS */ - popfl - movl cr0,eax /* 486 */ - andl $(CR0_PAGING | CR0_EXTENSION_TYPE | CR0_PROTECTION_ENABLE),eax /* Save PG,PE,ET */ - orl $(CR0_ALIGMENT_MASK | CR0_WRITE_PROTECT | CR0_NUMERIC_ERROR | CR0_MONITOR_COPROC),eax /* set AM, WP, NE and MP */ - jmp 2f -is386: /* restore original EFLAGS */ - popfl - movl cr0,eax /* 386 */ - andl $(CR0_PAGING | CR0_EXTENSION_TYPE | CR0_PROTECTION_ENABLE),eax /* Save PG,PE,ET */ - orl $CR0_MONITOR_COPROC,eax /* set MP */ -2: movl eax,cr0 - call check_x87 - ret - - -/* - * We depend on ET to be correct. This checks for 287/387. - */ -check_x87: - movb $0,SYM(hard_math) - clts - fninit - fstsw ax - cmpb $0,al - je 1f - movl cr0,eax /* no coprocessor: have to set bits */ - xorl $4,eax /* set EM */ - movl eax,cr0 - ret - .align 16 -1: movb $1,SYM(hard_math) - .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ - ret - -END_CODE - -BEGIN_DATA - PUBLIC(x86) - PUBLIC(have_cpuid) - PUBLIC(x86_model) - PUBLIC(x86_mask) - PUBLIC(x86_capability) - PUBLIC(x86_capability_ebx) - PUBLIC(x86_capability_x) - PUBLIC(x86_capability_cores) - PUBLIC(x86_vendor_id) - PUBLIC(hard_math) - -SYM(x86): - .byte 0 -SYM(have_cpuid): - .long 0 -SYM(x86_model): - .byte 0 -SYM(x86_mask): - .byte 0 -SYM(x86_capability): - .long 0 -SYM(x86_capability_ebx): - .long 0 -SYM(x86_capability_x): - .long 0 -SYM(x86_capability_cores): - .long 0 -SYM(x86_vendor_id): - .zero 13 -SYM(hard_math): - .byte 0 -END_DATA diff --git a/c/src/lib/libcpu/i386/displayCpu.c b/c/src/lib/libcpu/i386/displayCpu.c deleted file mode 100644 index f451194d96..0000000000 --- a/c/src/lib/libcpu/i386/displayCpu.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * This file contains code for displaying the Intel Cpu identification - * that has been performed by checkCPUtypeSetCr0 function. - */ - -/* - * This file was updated by Joel Sherrill - * to define more capability bits, pick up more CPU model information, - * and add more model strings. --joel (April 2010) - * - * COPYRIGHT (c) 1998 valette@crf.canon.fr - * COPYRIGHT (c) 2010 OAR Corporation - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -/* - * Tell us the machine setup.. - */ -#include -#include -#include -#include -#include -#include - -unsigned char Cx86_step = 0; - -static const char *Cx86_type[] = { - "unknown", "1.3", "1.4", "1.5", "1.6", - "2.4", "2.5", "2.6", "2.7 or 3.7", "4.2" - }; - -static const char *i486model(unsigned int nr) -{ - static const char *model[] = { - "0","DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4","DX/4-WB", - "10","11","12","13","Am5x86-WT","Am5x86-WB" - }; - - if (nr < sizeof(model)/sizeof(char *)) - return model[nr]; - return NULL; -} - -static const char * i586model(unsigned int nr) -{ - static const char *model[] = { - "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83", - "Pentium MMX", NULL, NULL, "Mobile Pentium 75+", - "Mobile Pentium MMX" - }; - if (nr < sizeof(model)/sizeof(char *)) - return model[nr]; - return NULL; -} - -static const char *Cx86model(void) -{ - unsigned char nr6x86 = 0; - static const char *model[] = { - "unknown", "6x86", "6x86L", "6x86MX", "MII" - }; - - switch (x86) { - case 5: - /* cx8 flag only on 6x86L */ - nr6x86 = ((x86_capability & (1 << 8)) ? 2 : 1); - break; - case 6: - nr6x86 = 3; - break; - default: - nr6x86 = 0; - } - - /* We must get the stepping number by reading DIR1 */ - outport_byte(0x22,0xff); - inport_byte(0x23, x86_mask); - switch (x86_mask) { - case 0x03: - Cx86_step = 1; /* 6x86MX Rev 1.3 */ - break; - case 0x04: - Cx86_step = 2; /* 6x86MX Rev 1.4 */ - break; - case 0x05: - Cx86_step = 3; /* 6x86MX Rev 1.5 */ - break; - case 0x06: - Cx86_step = 4; /* 6x86MX Rev 1.6 */ - break; - case 0x14: - Cx86_step = 5; /* 6x86 Rev 2.4 */ - break; - case 0x15: - Cx86_step = 6; /* 6x86 Rev 2.5 */ - break; - case 0x16: - Cx86_step = 7; /* 6x86 Rev 2.6 */ - break; - case 0x17: - Cx86_step = 8; /* 6x86 Rev 2.7 or 3.7 */ - break; - case 0x22: - Cx86_step = 9; /* 6x86L Rev 4.2 */ - break; - default: - Cx86_step = 0; - } - return model[nr6x86]; -} - -static const char * i686model(unsigned int nr) -{ - static const char *model[] = { - "PPro A-step", - "Pentium Pro" - }; - if (nr < sizeof(model)/sizeof(char *)) - return model[nr]; - return NULL; -} - -struct cpu_model_info { - int x86; - char *model_names[16]; -}; - -static struct cpu_model_info amd_models[] = { - { 4, - { NULL, NULL, NULL, "DX/2", NULL, NULL, NULL, "DX/2-WB", "DX/4", - "DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT", "Am5x86-WB" }}, - { 5, - { "K5/SSA5 (PR-75, PR-90, PR-100)", "K5 (PR-120, PR-133)", - "K5 (PR-166)", "K5 (PR-200)", NULL, NULL, - "K6 (166 - 266)", "K6 (166 - 300)", "K6-2 (200 - 450)", - "K6-3D-Plus (200 - 450)", NULL, NULL, NULL, NULL, NULL, NULL }}, -}; - -static const char * AMDmodel(void) -{ - const char *p=NULL; - int i; - - if (x86_model < 16) - for (i=0; i - -BEGIN_CODE -/* - * C callable function enabling to get easilly usable info from - * the actual value of IDT register. - * -extern void i386_get_info_from_IDTR (interrupt_gate_descriptor** table, - unsigned* limit); - */ -PUBLIC (i386_get_info_from_IDTR) -PUBLIC (i386_set_IDTR) -PUBLIC (i386_get_info_from_GDTR) -PUBLIC (i386_set_GDTR) - -SYM (i386_get_info_from_IDTR): - movl 4(esp), ecx /* get location where table address */ - /* must be stored */ - movl 8(esp), edx /* get location table size must be stored */ - - subl $6, esp /* let room to prepare 48 bit IDTR */ - - sidt (esp) /* get 48 bit IDTR value */ - - movl 2(esp), eax /* get base */ - movl eax, (ecx) - - movzwl (esp), eax /* get limit */ - movl eax, (edx) - - addl $6, esp /* restore %esp */ - ret - -/* - * C callable function enabling to change the value of IDT register. Must be called - * with inmterrupt masked at processor level!!!. - * -extern void i386_set_IDTR (interrupt_gate_descriptor* table, - unsigned limit); - */ -SYM (i386_set_IDTR): - - leal 4(esp), edx /* load in edx address of input */ - /* parameter "table" */ - - movl (edx), eax /* load base into eax */ - movl 4(edx), ecx /* load limit into ecx */ - - movw cx, (edx) /* prepare 48 bit pointer */ - movl eax, 2(edx) - - lidt (edx) - - ret -/* - * - * C callable function enabling to get easilly usable info from - * the actual value of GDT register. -extern void i386_get_info_from_GDTR (segment_descriptors** table, - uint16_t* limit); - */ - -SYM (i386_get_info_from_GDTR): - movl 4(esp), ecx /* get location where table address */ - /* must be stored */ - movl 8(esp), edx /* get location table size must be stored */ - - subl $6, esp /* let room to prepare 48 bit GDTR */ - - sgdt (esp) /* get 48 bit GDTR value */ - - movl 2(esp), eax /* get base */ - movl eax, (ecx) - - movzwl (esp), eax /* get limit */ - movw ax, (edx) - - addl $6, esp /* restore %esp */ - ret - -/* - * C callable function enabling to change the value of GDT register. - * Must be called with interrupts masked at processor level!!!. - * extern void i386_set_GDTR (segment_descriptors*, uint16_t limit); - */ -SYM (i386_set_GDTR): - - leal 4(esp), edx /* load in edx address of input */ - /* parameter "table" */ - - movl (edx), eax /* load base into eax */ - movl 4(edx), ecx /* load limit into ecx */ - - movw cx, (edx) /* prepare 48 bit pointer */ - movl eax, 2(edx) - - lgdt (edx) - - ret - -END_CODE - -END diff --git a/c/src/lib/libcpu/i386/page.c b/c/src/lib/libcpu/i386/page.c deleted file mode 100644 index f05e145f51..0000000000 --- a/c/src/lib/libcpu/i386/page.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * page.c :- This file contains implementation of C function to - * Instanciate paging. More detailled information - * can be found on Intel site and more precisely in - * the following book : - * - * Pentium Processor familly - * Developper's Manual - * - * Volume 3 : Architecture and Programming Manual - * - * Copyright (C) 1999 Emmanuel Raguet (raguet@crf.canon.fr) - * Canon Centre Recherche France. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include - -#define MEMORY_SIZE 0x4000000 /* 64Mo */ - -static int directoryEntry=0; -static int tableEntry=0; -static page_directory *pageDirectory; - -extern uint32_t bsp_mem_size; - -/*************************************************************************/ -/************** IT IS A ONE-TO-ONE TRANSLATION ***************************/ -/*************************************************************************/ - - -/* - * Disable the paging - */ -void _CPU_disable_paging(void) -{ - unsigned int regCr0; - - rtems_cache_flush_entire_data(); - regCr0 = i386_get_cr0(); - regCr0 &= ~(CR0_PAGING); - i386_set_cr0( regCr0 ); -} - -/* - * Enable the paging - */ -void _CPU_enable_paging(void) -{ - unsigned int regCr0; - - regCr0 = i386_get_cr0(); - regCr0 |= CR0_PAGING; - i386_set_cr0( regCr0 ); - rtems_cache_flush_entire_data(); -} - - -/* - * Initialize the paging with 1-to-1 mapping - */ - -int init_paging(void) -{ - int nbPages; - int nbInitPages; - char *Tables; - unsigned int regCr3; - page_table *pageTable; - unsigned int physPage; - int nbTables=0; - - nbPages = ( (bsp_mem_size - 1) / PG_SIZE ) + 1; - nbTables = ( (bsp_mem_size - 1) / FOUR_MB ) + 2; - - /* allocate 1 page more to page alignement */ - Tables = (char *)malloc( (nbTables + 1)*sizeof(page_table) ); - if ( Tables == NULL ){ - return -1; /*unable to allocate memory */ - } - - /* 4K-page alignement */ - Tables += (PG_SIZE - (int)Tables) & 0xFFF; - - /* Reset Tables */ - memset( Tables, 0, nbTables*sizeof(page_table) ); - pageDirectory = (page_directory *) Tables; - pageTable = (page_table *)((int)Tables + PG_SIZE); - - nbInitPages = 0; - directoryEntry = 0; - tableEntry = 0; - physPage = 0; - - while ( nbInitPages != nbPages ){ - if ( tableEntry == 0 ){ - pageDirectory->pageDirEntry[directoryEntry].bits.page_frame_address = (unsigned int)pageTable >> 12; - pageDirectory->pageDirEntry[directoryEntry].bits.available = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.page_size = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.accessed = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.cache_disable = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.write_through = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.user = 1; - pageDirectory->pageDirEntry[directoryEntry].bits.writable = 1; - pageDirectory->pageDirEntry[directoryEntry].bits.present = 1; - } - pageTable->pageTableEntry[tableEntry].bits.page_frame_address = physPage; - pageTable->pageTableEntry[tableEntry].bits.available = 0; - pageTable->pageTableEntry[tableEntry].bits.dirty = 0; - pageTable->pageTableEntry[tableEntry].bits.accessed = 0; - pageTable->pageTableEntry[tableEntry].bits.cache_disable = 0; - pageTable->pageTableEntry[tableEntry].bits.write_through = 0; - pageTable->pageTableEntry[tableEntry].bits.user = 1; - pageTable->pageTableEntry[tableEntry].bits.writable = 1; - pageTable->pageTableEntry[tableEntry].bits.present = 1; - - physPage ++; - tableEntry ++; - - if (tableEntry >= MAX_ENTRY){ - tableEntry = 0; - directoryEntry ++; - pageTable ++; - } - - nbInitPages++; - } - - regCr3 &= ~(CR3_PAGE_WRITE_THROUGH); - regCr3 &= ~(CR3_PAGE_CACHE_DISABLE); - /*regCr3.cr3.page_directory_base = (unsigned int)pageDirectory >> 12;*/ - regCr3 = (unsigned int)pageDirectory & CR3_PAGE_DIRECTORY_MASK; - - i386_set_cr3( regCr3 ); - - _CPU_enable_cache(); - _CPU_enable_paging(); - - return 0; -} - -/* - * Is cache enable - */ -int _CPU_is_cache_enabled(void) -{ - unsigned int regCr0; - - regCr0 = i386_get_cr0(); - return( ~(regCr0 & CR0_PAGE_LEVEL_CACHE_DISABLE) ); -} - -/* - * Is paging enable - */ -int _CPU_is_paging_enabled(void) -{ - unsigned int regCr0; - - regCr0 = i386_get_cr0(); - return(regCr0 & CR0_PAGING); -} - - -/* - * Translate the physical address in the virtual space and return - * the translated address in mappedAddress - */ - -int _CPU_map_phys_address( - void **mappedAddress, - void *physAddress, - int size, - int flag -) -{ - page_table *localPageTable; - unsigned int lastAddress, countAddress; - char *Tables; - linear_address virtualAddress; - unsigned char pagingWasEnabled; - - pagingWasEnabled = 0; - - if (_CPU_is_paging_enabled()){ - pagingWasEnabled = 1; - _CPU_disable_paging(); - } - - countAddress = (unsigned int)physAddress; - lastAddress = (unsigned int)physAddress + (size - 1); - virtualAddress.address = 0; - - while (1) { - - if ((countAddress & ~MASK_OFFSET) > (lastAddress & ~MASK_OFFSET)) - break; - - /* Need to allocate a new page table */ - if (pageDirectory->pageDirEntry[directoryEntry].bits.page_frame_address == 0){ - /* We allocate 2 pages to perform 4k-page alignement */ - Tables = (char *)malloc(2*sizeof(page_table)); - if ( Tables == NULL ){ - if (pagingWasEnabled) - _CPU_enable_paging(); - return -1; /* unable to allocate memory */ - } - /* 4K-page alignement */ - Tables += (PG_SIZE - (int)Tables) & 0xFFF; - - /* Reset Table */ - memset( Tables, 0, sizeof(page_table) ); - pageDirectory->pageDirEntry[directoryEntry].bits.page_frame_address = - (unsigned int)Tables >> 12; - pageDirectory->pageDirEntry[directoryEntry].bits.available = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.page_size = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.accessed = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.cache_disable = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.write_through = 0; - pageDirectory->pageDirEntry[directoryEntry].bits.user = 1; - pageDirectory->pageDirEntry[directoryEntry].bits.writable = 1; - pageDirectory->pageDirEntry[directoryEntry].bits.present = 1; - } - - - localPageTable = (page_table *)(pageDirectory-> - pageDirEntry[directoryEntry].bits. - page_frame_address << 12); - - if (virtualAddress.address == 0){ - virtualAddress.bits.directory = directoryEntry; - virtualAddress.bits.page = tableEntry; - virtualAddress.bits.offset = (unsigned int)physAddress & MASK_OFFSET; - } - - localPageTable->pageTableEntry[tableEntry].bits.page_frame_address = - ((unsigned int)countAddress & ~MASK_OFFSET) >> 12; - localPageTable->pageTableEntry[tableEntry].bits.available = 0; - localPageTable->pageTableEntry[tableEntry].bits.dirty = 0; - localPageTable->pageTableEntry[tableEntry].bits.accessed = 0; - localPageTable->pageTableEntry[tableEntry].bits.cache_disable = 0; - localPageTable->pageTableEntry[tableEntry].bits.write_through = 0; - localPageTable->pageTableEntry[tableEntry].bits.user = 1; - localPageTable->pageTableEntry[tableEntry].bits.writable = 0; - localPageTable->pageTableEntry[tableEntry].bits.present = 1; - - localPageTable->pageTableEntry[tableEntry].table_entry |= flag ; - - countAddress += PG_SIZE; - tableEntry++; - if (tableEntry >= MAX_ENTRY){ - tableEntry = 0; - directoryEntry++; - } - } - - if (mappedAddress != 0) - *mappedAddress = (void *)(virtualAddress.address); - if (pagingWasEnabled) - _CPU_enable_paging(); - return 0; -} - -/* - * "Compress" the Directory and Page tables to avoid - * important loss of address range - */ -static void Paging_Table_Compress(void) -{ - unsigned int dirCount, pageCount; - page_table *localPageTable; - - if (tableEntry == 0){ - dirCount = directoryEntry - 1; - pageCount = MAX_ENTRY - 1; - } - else { - dirCount = directoryEntry; - pageCount = tableEntry - 1; - } - - while (1){ - - localPageTable = (page_table *)(pageDirectory-> - pageDirEntry[dirCount].bits. - page_frame_address << 12); - - if (localPageTable->pageTableEntry[pageCount].bits.present == 1){ - pageCount++; - if (pageCount >= MAX_ENTRY){ - pageCount = 0; - dirCount++; - } - break; - } - - - if (pageCount == 0) { - if (dirCount == 0){ - break; - } - else { - pageCount = MAX_ENTRY - 1; - dirCount-- ; - } - } - else - pageCount-- ; - } - - directoryEntry = dirCount; - tableEntry = pageCount; -} - - -/* - * Unmap the virtual address from the tables - * (we do not deallocate the table already allocated) - */ - -int _CPU_unmap_virt_address( - void *mappedAddress, - int size -) -{ - - linear_address linearAddr; - page_table *localPageTable; - unsigned int lastAddr ; - unsigned char pagingWasEnabled; - - pagingWasEnabled = 0; - - if (_CPU_is_paging_enabled()){ - pagingWasEnabled = 1; - _CPU_disable_paging(); - } - - linearAddr.address = (unsigned int)mappedAddress; - lastAddr = (unsigned int)mappedAddress + (size - 1); - - while (1){ - - if ((linearAddr.address & ~MASK_OFFSET) > (lastAddr & ~MASK_OFFSET)) - break; - - if (pageDirectory->pageDirEntry[linearAddr.bits.directory].bits.present == 0){ - if (pagingWasEnabled) - _CPU_enable_paging(); - return -1; - } - - localPageTable = (page_table *)(pageDirectory-> - pageDirEntry[linearAddr.bits.directory].bits. - page_frame_address << 12); - - if (localPageTable->pageTableEntry[linearAddr.bits.page].bits.present == 0){ - if (pagingWasEnabled) - _CPU_enable_paging(); - return -1; - } - - localPageTable->pageTableEntry[linearAddr.bits.page].bits.present = 0; - - linearAddr.address += PG_SIZE ; - } - Paging_Table_Compress(); - if (pagingWasEnabled) - _CPU_enable_paging(); - - return 0; -} - -/* - * Modify the flags PRESENT, WRITABLE, USER, WRITE_TROUGH, CACHE_DISABLE - * of the page's descriptor. - */ - -int _CPU_change_memory_mapping_attribute( - void **newAddress, - void *mappedAddress, - unsigned int size, - unsigned int flag -) -{ - - linear_address linearAddr; - page_table *localPageTable; - unsigned int lastAddr ; - unsigned char pagingWasEnabled; - - pagingWasEnabled = 0; - - if (_CPU_is_paging_enabled()){ - pagingWasEnabled = 1; - _CPU_disable_paging(); - } - - linearAddr.address = (unsigned int)mappedAddress; - lastAddr = (unsigned int)mappedAddress + (size - 1); - - while (1){ - - if ((linearAddr.address & ~MASK_OFFSET) > (lastAddr & ~MASK_OFFSET)) - break; - - if (pageDirectory->pageDirEntry[linearAddr.bits.directory].bits.present == 0){ - if (pagingWasEnabled) - _CPU_enable_paging(); - return -1; - } - localPageTable = (page_table *)(pageDirectory-> - pageDirEntry[linearAddr.bits.directory].bits. - page_frame_address << 12); - - if (localPageTable->pageTableEntry[linearAddr.bits.page].bits.present == 0){ - if (pagingWasEnabled) - _CPU_enable_paging(); - return -1; - } - - localPageTable->pageTableEntry[linearAddr.bits.page].table_entry &= ~MASK_FLAGS ; - localPageTable->pageTableEntry[linearAddr.bits.page].table_entry |= flag ; - - linearAddr.address += PG_SIZE ; - } - - if (newAddress != NULL) - *newAddress = mappedAddress ; - - if (pagingWasEnabled) - _CPU_enable_paging(); - - return 0; -} - -/* - * Display the page descriptor flags - * CACHE_DISABLE of the whole memory - */ - -#include - -int _CPU_display_memory_attribute(void) -{ - unsigned int dirCount, pageCount; - unsigned int regCr0; - page_table *localPageTable; - unsigned int prevCache; - unsigned int prevPresent; - unsigned int maxPage; - unsigned char pagingWasEnabled; - - regCr0 = i386_get_cr0(); - - printk("\n\n********* MEMORY CACHE CONFIGURATION *****\n"); - - printk("CR0 -> paging : %s\n",((regCr0 & CR0_PAGING) ? "ENABLE ":"DISABLE")); - printk(" page-level cache : %s\n\n",((regCr0 & CR0_PAGE_LEVEL_CACHE_DISABLE) ? "DISABLE":"ENABLE")); - - if ((regCr0 & CR0_PAGING) == 0) - return 0; - - prevPresent = 0; - prevCache = 1; - - pagingWasEnabled = 0; - - if (_CPU_is_paging_enabled()){ - pagingWasEnabled = 1; - _CPU_disable_paging(); - } - - for (dirCount = 0; dirCount < directoryEntry+1; dirCount++) { - - localPageTable = (page_table *)(pageDirectory-> - pageDirEntry[dirCount].bits. - page_frame_address << 12); - - maxPage = MAX_ENTRY; - /*if ( dirCount == (directoryEntry-1)) - maxPage = tableEntry;*/ - for (pageCount = 0; pageCount < maxPage; pageCount++) { - - if (localPageTable->pageTableEntry[pageCount].bits.present != 0){ - if (prevPresent == 0){ - prevPresent = 1; - printk ("present page from address %x \n", ((dirCount << 22)|(pageCount << 12))); - } - if (prevCache != localPageTable->pageTableEntry[pageCount].bits.cache_disable ) { - prevCache = localPageTable->pageTableEntry[pageCount]. - bits.cache_disable; - printk (" cache %s from %x \n", - (prevCache ? "DISABLE" : "ENABLE "), - ((dirCount << 22)|(pageCount << 12)), - localPageTable->pageTableEntry[pageCount].bits.page_frame_address << 12); - } - } - else { - if (prevPresent == 1){ - prevPresent = 0; - printk ("Absent from %x \n", ((dirCount << 22)|(pageCount << 12))); - } - } - } - } - if (pagingWasEnabled) - _CPU_enable_paging(); - - return 0; -} -- cgit v1.2.3