2018-09-28 20:35:51 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* COS2000 - Compatible Operating System - LGPL v3 - Hord<72> Nicolas */
|
|
|
|
|
/* */
|
2007-04-02 16:34:45 +02:00
|
|
|
|
#include "types.h"
|
2018-10-02 02:16:14 +02:00
|
|
|
|
#include "memory.h"
|
2018-11-16 15:57:34 +01:00
|
|
|
|
#include "multiboot2.h"
|
2018-10-02 02:16:14 +02:00
|
|
|
|
|
2018-11-16 15:57:34 +01:00
|
|
|
|
static u32 *pd0 = (u32 *) KERNEL_PGD_ADDR; /* page directory */
|
|
|
|
|
static u8 *pg0 = (u8 *) 0; /* page 0 */
|
|
|
|
|
static u8 *pg1 = (u8 *) (PAGESIZE*PAGENUMBER); /* page 1 */
|
|
|
|
|
static u8 bitmap[MAXMEMPAGE / 8];
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Retourne la taille de la m<>moire (selon grub) */
|
|
|
|
|
|
|
|
|
|
u64 getmemorysize()
|
|
|
|
|
{
|
|
|
|
|
u64 maxaddr=0;
|
|
|
|
|
struct multiboot_tag_mmap *tag=getgrubinfo_mem();
|
|
|
|
|
multiboot_memory_map_t *mmap;
|
|
|
|
|
for (mmap = ((struct multiboot_tag_mmap *) tag)->entries;(u8 *) mmap < (u8 *) tag + tag->size; mmap = (multiboot_memory_map_t *)
|
|
|
|
|
((unsigned long) mmap + ((struct multiboot_tag_mmap *) tag)->entry_size))
|
|
|
|
|
if (mmap->addr+mmap->len>maxaddr)
|
|
|
|
|
maxaddr=mmap->addr+mmap->len;
|
|
|
|
|
return maxaddr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Retourne que la page actuelle est occup<75>e */
|
|
|
|
|
|
|
|
|
|
void bitmap_page_use(page)
|
|
|
|
|
{
|
|
|
|
|
bitmap[((u32) page)/8] |= (1 << (((u32) page)%8));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Retourne que la page actuelle est libre */
|
|
|
|
|
|
|
|
|
|
void bitmap_page_free(page)
|
|
|
|
|
{
|
|
|
|
|
bitmap[((u32) page)/8] &= ~(1 << (((u32) page)%8));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Reserve un espace m<>moire dans le bitmap */
|
|
|
|
|
|
|
|
|
|
void bitmap_page_setused(u64 addr,u64 len)
|
|
|
|
|
{
|
|
|
|
|
u32 nbpage=TOPAGE(len);
|
|
|
|
|
u32 pagesrc=TOPAGE(addr);
|
|
|
|
|
if (len & 0b1111111111 > 0)
|
|
|
|
|
nbpage++;
|
2018-11-21 17:25:00 +01:00
|
|
|
|
if (addr>0xFFFFFFFF)
|
|
|
|
|
return;
|
|
|
|
|
if (len>0xFFFFFFFF)
|
|
|
|
|
len=0xFFFFFFFF;
|
2018-11-16 15:57:34 +01:00
|
|
|
|
for(u32 page=pagesrc;page<pagesrc+nbpage;page++)
|
|
|
|
|
bitmap_page_use(page);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Indique un espace m<>moire libre dans le bitmap */
|
|
|
|
|
|
|
|
|
|
void bitmap_page_setfree(u64 addr,u64 len)
|
|
|
|
|
{
|
|
|
|
|
u32 nbpage=TOPAGE(len);
|
|
|
|
|
u32 pagesrc=TOPAGE(addr);
|
|
|
|
|
if (len & 0b1111111111 > 0)
|
2018-11-21 17:25:00 +01:00
|
|
|
|
nbpage++;
|
|
|
|
|
if (addr>0xFFFFFFFF)
|
|
|
|
|
return;
|
|
|
|
|
if (len>0xFFFFFFFF)
|
|
|
|
|
len=0xFFFFFFFF;
|
2018-11-16 15:57:34 +01:00
|
|
|
|
for(u32 page=pagesrc;page<pagesrc+nbpage;page++)
|
|
|
|
|
bitmap_page_free(page);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Retourne une page libre */
|
|
|
|
|
|
|
|
|
|
u8* bitmap_page_getonefree(void)
|
|
|
|
|
{
|
|
|
|
|
u8 byte, bit;
|
|
|
|
|
u32 page = 0;
|
|
|
|
|
for (byte = 0; byte < sizeof(bitmap); byte++)
|
|
|
|
|
if (bitmap[byte] != 0xFF)
|
|
|
|
|
for (bit = 0; bit < 8; bit++)
|
|
|
|
|
if (!(bitmap[byte] & (1 << bit))) {
|
|
|
|
|
page = 8 * byte + bit;
|
|
|
|
|
bitmap_page_use(page);
|
|
|
|
|
return (u8 *) (page * PAGESIZE);
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Retourne l'espace libre */
|
|
|
|
|
|
|
|
|
|
u64 getmemoryfree(void)
|
|
|
|
|
{
|
|
|
|
|
u32 byte, bit;
|
|
|
|
|
u64 free = 0;
|
|
|
|
|
for (byte = 0; byte < sizeof(bitmap); byte++)
|
|
|
|
|
if (bitmap[byte] != 0xFF)
|
|
|
|
|
for (bit = 0; bit < 8; bit++)
|
|
|
|
|
if (!(bitmap[byte] & (1 << bit)))
|
|
|
|
|
free+=PAGESIZE;
|
|
|
|
|
return free;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Initialisation du bitmap */
|
|
|
|
|
|
|
|
|
|
void bitmap_init()
|
|
|
|
|
{
|
|
|
|
|
u64 page;
|
|
|
|
|
for (page=0; page < sizeof(bitmap); page++)
|
|
|
|
|
bitmap[page] = 0xFF;
|
|
|
|
|
struct multiboot_tag_mmap *tag=getgrubinfo_mem();
|
|
|
|
|
multiboot_memory_map_t *mmap;
|
|
|
|
|
for (mmap = ((struct multiboot_tag_mmap *) tag)->entries;(u8 *) mmap < (u8 *) tag + tag->size; mmap = (multiboot_memory_map_t *)
|
|
|
|
|
((unsigned long) mmap + ((struct multiboot_tag_mmap *) tag)->entry_size))
|
|
|
|
|
if (mmap->type==1)
|
|
|
|
|
bitmap_page_setfree(mmap->addr,mmap->len);
|
|
|
|
|
else
|
|
|
|
|
bitmap_page_setused(mmap->addr,mmap->len);
|
|
|
|
|
bitmap_page_setused(0x0,KERNELSIZE);
|
|
|
|
|
}
|
2018-10-02 02:16:14 +02:00
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Initialisation de la m<>moire pagin<69>e */
|
|
|
|
|
|
|
|
|
|
void initpaging(void)
|
|
|
|
|
{
|
|
|
|
|
u16 i;
|
|
|
|
|
pd0[0] = ((u32) pg0 | (PAGE_PRESENT | PAGE_WRITE | PAGE_4MB));
|
|
|
|
|
pd0[1] = ((u32) pg1 | (PAGE_PRESENT | PAGE_WRITE | PAGE_4MB));
|
|
|
|
|
for (i = 2; i < 1023; i++)
|
|
|
|
|
pd0[i] = ((u32) pg1 + PAGESIZE * i) | (PAGE_PRESENT | PAGE_WRITE);
|
|
|
|
|
|
|
|
|
|
pd0[1023] = ((u32) pd0 | (PAGE_PRESENT | PAGE_WRITE));
|
|
|
|
|
|
|
|
|
|
asm("mov %[pd0_addr], %%eax \n \
|
|
|
|
|
mov %%eax, %%cr3 \n \
|
|
|
|
|
mov %%cr4, %%eax \n \
|
|
|
|
|
or $0x00000010, %%eax \n \
|
|
|
|
|
mov %%eax, %%cr4 \n \
|
|
|
|
|
mov %%cr0, %%eax \n \
|
|
|
|
|
or $0x80000001, %%eax \n \
|
|
|
|
|
mov %%eax, %%cr0"::[pd0_addr]"m"(pd0));
|
|
|
|
|
}
|
2007-04-02 16:34:45 +02:00
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Copie un octet une ou plusieurs fois en m<>moire */
|
2018-09-28 20:35:51 +02:00
|
|
|
|
|
|
|
|
|
void memset(void *dst, u8 val, u32 count, u32 size)
|
|
|
|
|
{
|
2018-10-13 11:25:55 +02:00
|
|
|
|
u8 *d = (u8 *) dst;
|
|
|
|
|
if (size>0) size--;
|
|
|
|
|
for (; count != 0; count--) {
|
|
|
|
|
*(d++) = val;
|
|
|
|
|
d+=size;
|
|
|
|
|
}
|
2018-09-28 20:35:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* Copie une portion de m<>moire vers une autre */
|
2018-09-28 20:35:51 +02:00
|
|
|
|
|
|
|
|
|
void memcpy(void *src, void *dst, u32 count, u32 size)
|
|
|
|
|
{
|
2018-10-13 11:25:55 +02:00
|
|
|
|
u8 *s = (u8 *) src;
|
|
|
|
|
u8 *d = (u8 *) dst;
|
|
|
|
|
if (size>0) size--;
|
|
|
|
|
for (; count != 0; count--) {
|
|
|
|
|
*(d++) = *(s++);
|
|
|
|
|
d+=size;
|
|
|
|
|
}
|
2018-09-28 20:35:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/* Compare 2 portions de m<>moire */
|
2018-09-28 20:35:51 +02:00
|
|
|
|
|
|
|
|
|
u32 memcmp(void *src, void *dst, u32 count, u32 size)
|
|
|
|
|
{
|
2018-10-13 11:25:55 +02:00
|
|
|
|
u8 *s = (u8 *) src;
|
|
|
|
|
u8 *d = (u8 *) dst;
|
|
|
|
|
if (size>0) size--;
|
|
|
|
|
for (; count != 0; count--) {
|
|
|
|
|
if (*(s++) != *(d++))
|
|
|
|
|
return *d - *s;
|
|
|
|
|
s+= size;
|
|
|
|
|
d+= size;
|
2018-09-28 20:35:51 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-17 16:46:56 +02:00
|
|
|
|
/*******************************************************************************/
|