1 Star 0 Fork 0

lwsh.95/system

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
memory.c 6.24 KB
一键复制 编辑 原始数据 按行查看 历史
liwensheng 提交于 2021-03-31 10:11 . 13.3 benchamrk
/* ""表示该头文件与源文件位于同一个文件夹里,< >则表示该头文件位于编译器的文件夹里。*/
#include "bootpack.h"
#include <stdio.h>
#define EFLAGS_AC_BIT 0x00040000
#define CR0_CACHE_DISABLE 0x60000000
struct FIFO32 *mousefifo;
int mousedata0;
/*内存检查时,要往内存里随便写入一个值,然后马上读取,来检查读取的值与写入的值是否相等。
如果内存连接正常,则写入的值能够记在内存里。如果没连接上,则读出的值肯定是乱七八糟的。但是CPU加上了缓存写入和读出的不是内存,而是缓存。
结果,所有的内存都“正常”,检查处理不能完成。所以就是先查查CPU是不是在486以上,如果是,就将缓存设为OFF
*/
unsigned int memtest(unsigned int start, unsigned int end)
{
char flg486 = 0;
unsigned int eflg, cr0, i;
/* 如果是486以上,EFLAGS寄存器的第18位应该是所谓的AC标志位;如果CPU是386,那么就没有这个标志位,第18位一直是0。
把1写入到这一位,然后再读出EFLAGS的值,继而检查AC标志位是否仍为1。最后,将AC标志位重置为0。 */
eflg = io_load_eflags();
eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */
io_store_eflags(eflg);
eflg = io_load_eflags();
if ((eflg & EFLAGS_AC_BIT) != 0) { /* 如果为386,即使设定AC=1,AC的值还会自动回到0 */
flg486 = 1;
}
// 将所有的位都反转的意思。所以,~EFLAGS_AC_BIT与0xfffbffff一样。
eflg &= ~EFLAGS_AC_BIT; /* AC-bit = 0 */
io_store_eflags(eflg);
if (flg486 != 0) {
cr0 = load_cr0();
cr0 |= CR0_CACHE_DISABLE; /* 禁止缓存 */
store_cr0(cr0);
}
i = memtest_sub(start, end);
if (flg486 != 0) {
cr0 = load_cr0();
cr0 &= ~CR0_CACHE_DISABLE; /* 允许缓存 */
store_cr0(cr0);
}
return i;
}
/*从start地址到end地址的范围内,能够使用的内存的末尾地址。使用p将原值保存下来(变量old)。
接着试写0xaa55aa55,在内存里反转该值,检查结果是否正确。如果正确,就再次反转它,检查一下是否能回复到初始值。
最后,使用old变量,将内存的值恢复回去。如果在某个环节没能恢复成预想的值,那么就在那个环节终止调查,并报告终止时的地址。
*/
/*
unsigned int memtest_sub(unsigned int start, unsigned int end)
{
unsigned int i, *p, old, pat0 = 0xaa55aa55, pat1 = 0x55aa55aa;
//for语句中i的增值部分以及p的赋值部分。每次增加0x1000,相当于4KB,这样一来速度就提高了1000倍。
//p的赋值计算式也变了,这是因为,如果不进行任何改变仍写作“p=i; ”的话,程序就会只检查4KB最开头的4个字节。
//所以要改为“p=i + 0xffc; ”,让它只检查末尾的4个字节。
//
for (i = start; i <= end; i += 0x1000) {
p = (unsigned int *) (i + 0xffc);
old = *p; // 先记住修改前的值
*p = pat0; // 试写
*p ^= 0xffffffff; // 反写
if (*p != pat1) { // 检测反转结果
not_memory:
*p = old;
break;
}
*p ^= 0xffffffff; // 再次反转
if (*p != pat0) { // 检查值是否恢复
goto not_memory;
}
*p = old; // 恢复修改前的值
}
return i;
}
*/
void memman_init(struct MEMMAN *man)
{
man->frees=0; //可用信息数目
man->maxfrees=0; //用于观察可用状况:frees最大值
man->lostsize=0; //释放失败的内存的大小总和
man->losts=0; //释放失败次数
return;
}
/*报告空余内存大小的合计
*/
unsigned int memman_total(struct MEMMAN *man)
{
unsigned int i, t = 0;
for (i = 0; i < man->frees; i++) {
t += man->free[i].size;
}
return t;
}
unsigned int memman_alloc(struct MEMMAN *man,unsigned int size)
{
unsigned int i, a;
for (i = 0; i < man->frees; i++) {
if (man->free[i].size >= size) {
// 找到足够的内存
a = man->free[i].addr;
man->free[i].addr += size;
man->free[i].size -= size;
if (man->free[i].size == 0) {
// 如果free[i]变成0,就减掉一条可用信息
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1];
}
}
return a;
}
}
return 0; //没有可用空间
}
int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size)
{
int i, j;
/* 为便于归纳内存,将free[]按照addr的顺序排序 */
for (i = 0; i < man->frees; i++) {
if (man->free[i].addr > addr) {
break;
}
}
/* free[i - 1].addr < addr < free[i].addr */
if (i > 0) {
/* 前面有可用内存 */
if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
/* 与前面的内存归纳到一起 */
man->free[i - 1].size += size;
if (i < man->frees) {
/* 后面也有 */
if (addr + size == man->free[i].addr) {
/* 也可以与后面的内存归纳到一起 */
man->free[i - 1].size += man->free[i].size;
/* man->free[i]删除 */
/* free[i]变成0后归纳到前面去 */
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1]; /* 结构体赋值 */
}
}
}
return 0; /* 成功完成 */
}
}
/* 不能与前面可用空间归纳到一起 */
if (i < man->frees) {
/* 后面还有 */
if (addr + size == man->free[i].addr) {
/* 可以与后面的内容归纳到一起 */
man->free[i].addr = addr;
man->free[i].size += size;
return 0; /* 成功完成 */
}
}
/* 不能与前后可用空间归纳到一起 */
if (man->frees < MEMMAN_FREES) {
/* free[i]之后的向后移动,腾出可用空间 */
for (j = man->frees; j > i; j--) {
man->free[j] = man->free[j - 1];
}
man->frees++;
if (man->maxfrees < man->frees) {
man->maxfrees = man->frees; /* 更新最大值 */
}
man->free[i].addr = addr;
man->free[i].size = size;
return 0; /* 成功完成 */
}
/* 不能往后移动 */
man->losts++;
man->lostsize += size;
return -1; /* 失败 */
}
// 以0x1000即4096字节进行内存分配和释放,不足时向上取整
unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size)
{
unsigned int a;
// 等价于i=(i&0xfffff000) + 0x1000
size = (size + 0xfff) & 0xfffff000;
a = memman_alloc(man, size);
return a;
}
int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size)
{
int i;
size = (size + 0xfff) & 0xfffff000;
i = memman_free(man, addr, size);
return i;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/lwsh95/system.git
[email protected]:lwsh95/system.git
lwsh95
system
system
master

搜索帮助