OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_010 / chnos / memory.c
diff --git a/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/memory.c b/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/memory.c
new file mode 100644 (file)
index 0000000..16dd7b9
--- /dev/null
@@ -0,0 +1,315 @@
+\r
+#include "core.h"\r
+\r
+uint Memory_Test(uint start, uint end)\r
+{\r
+       uchar flg486 = 0;\r
+       uint i;\r
+       CPU_EFlags eflg;\r
+       CPU_ControlRegister0 cr0;\r
+\r
+       eflg.eflags = IO_Load_EFlags();\r
+       eflg.bit.AC = True;\r
+       IO_Store_EFlags(eflg.eflags);\r
+\r
+       eflg.eflags = IO_Load_EFlags();\r
+       if(eflg.bit.AC){\r
+               flg486 = 1;\r
+       }\r
+       eflg.bit.AC = False;\r
+       IO_Store_EFlags(eflg.eflags);\r
+\r
+       if(flg486 != 0){\r
+               cr0.cr0 = Load_CR0();\r
+               cr0.bit.NW = True;\r
+               cr0.bit.CD = True;\r
+               Store_CR0(cr0.cr0);\r
+       }\r
+       i = Memory_Test_Sub(start, end);\r
+       if(flg486 != 0){\r
+               cr0.cr0 = Load_CR0();\r
+               cr0.bit.NW = False;\r
+               cr0.bit.CD = False;\r
+               Store_CR0(cr0.cr0);\r
+       }\r
+       return i;\r
+}\r
+\r
+//Memory Control System\r
+//ctrl[0].addr = 0;\r
+//ctrl[0].size = tags;\r
+//Memory Control\94z\97ñ\82Í\81A\8aÇ\97\9d\91Î\8fÛ\82Ì\83\81\83\82\83\8a\82Ì\8fI\92[\82É\94z\92u\82³\82ê\82é\81B\r
+\r
+IO_MemoryControl Memory_Initialize_Control(void *start, uint size, uint tags)\r
+{\r
+       IO_MemoryControl ctrl;\r
+\r
+       start = (void *)(((uint)start + 7) & ~7);\r
+       size = (size + 7) & ~7;\r
+\r
+//Memory Control\94z\97ñ\82ª\93ü\82é\95ª\82æ\82è\91½\82­\81A\8aÇ\97\9d\91Î\8fÛ\82Ì\83\81\83\82\83\8a\82ð\97^\82¦\82ç\82ê\82Ä\82¢\82é\82©\83`\83F\83b\83N\81B\r
+       if((tags * sizeof(IO_MemoryControlTag)) > size){\r
+               return 0;\r
+       }\r
+\r
+//\8aÇ\97\9d\82Ì\93s\8d\87\8fã\81A3\83^\83O\88È\8fã\82È\82¢\82Æ\8aÇ\97\9d\82ª\90¬\97§\82µ\82È\82¢\82Ì\82Å\81A\82»\82Ì\83`\83F\83b\83N\81B\r
+       if(tags < 3){\r
+               return 0;\r
+       }\r
+\r
+//\8aÇ\97\9d\91Î\8fÛ\83\81\83\82\83\8a\94Í\88Í\82Ì\8dÅ\8cã\82©\82ç\81AMemory Control\94z\97ñ\82Ì\91å\82«\82³\95ª\82¾\82¯\82³\82©\82Ì\82Ú\82Á\82½\92n\93_\82ðMemoryControl\94z\97ñ\82Ì\90æ\93ª\82Æ\82·\82é\81B\r
+       ctrl = (IO_MemoryControl)(start + (size - (tags * sizeof(IO_MemoryControlTag))));\r
+       ctrl[0].addr = 0;\r
+       ctrl[0].size = tags;\r
+\r
+       ctrl[1].addr = start;\r
+       ctrl[1].size = size - (tags * sizeof(IO_MemoryControlTag));\r
+\r
+       ctrl[2].addr = 0;\r
+       ctrl[2].size = 0xffffffff;\r
+\r
+       return ctrl;\r
+}\r
+\r
+void Memory_Free(IO_MemoryControl ctrl, void *addr, uint size)\r
+{\r
+       uint i, j, k, minsize;\r
+       uint eflags;\r
+\r
+       size = (size + 7) & ~7;\r
+\r
+#ifdef CHNOSPROJECT_DEBUG_MEMORY\r
+       debug("DEBUG:MemoryFree:Start ctrl:0x%08X addr:0x%08X size 0x%08X\n", ctrl, addr, size);\r
+#endif\r
+\r
+       if(size == 0){\r
+               return;\r
+       }\r
+\r
+       eflags = IO_Load_EFlags();\r
+\r
+       IO_CLI();\r
+\r
+       j = 0;\r
+       k = 0;\r
+       minsize = 0xffffffff;\r
+       for(i = 1; i < ctrl[0].size; i++){\r
+               if(ctrl[i].size == 0xffffffff){ /*\8fI\92[*/\r
+                       break;\r
+               }\r
+               if(ctrl[i].size < minsize){     /*\8dÅ\8f¬\8bó\82«\83\81\83\82\83\8a\82Ì\8c\9f\8dõ*/\r
+                       k = i;\r
+               }\r
+               if(addr + size <= ctrl[i].addr){        /*\89ð\95ú\82µ\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\8bó\82«\83\81\83\82\83\8a\82Ì\8e\9f\82É\97\88\82é\82×\82«\8bó\82«\83\81\83\82\83\8a*/\r
+#ifdef CHNOSPROJECT_DEBUG_MEMORY\r
+       debug("DEBUG:MemoryFree:Found NextTagIndex:%d\n", i);\r
+#endif\r
+                       j = i;\r
+                       break;\r
+               }\r
+       }\r
+       for(i--; i < ctrl[0].size; i++){\r
+               if(ctrl[i].size == 0xffffffff){ /*\8fI\92[*/\r
+                       break;\r
+               }\r
+               if(ctrl[i].size < minsize){     /*\8dÅ\8f¬\8bó\82«\83\81\83\82\83\8a\82Ì\8c\9f\8dõ*/\r
+                       k = i;\r
+               }\r
+       }\r
+#ifdef CHNOSPROJECT_DEBUG_MEMORY\r
+       debug("DEBUG:MemoryFree:Loop EndTagIndex:%d\n", i);\r
+#endif\r
+       if(j == 0){     /*\8e©\95ª\82æ\82è\82à\83A\83h\83\8c\83X\82Ì\8f¬\82³\82È\8bó\82«\8fî\95ñ\82ª\8c©\82Â\82©\82ç\82È\82©\82Á\82½*/\r
+               j = i;\r
+       }\r
+       if(i == ctrl[0].size){  /*\8bó\82«\83\81\83\82\83\8a\94z\97ñ\82ª\96\9e\94t*/\r
+               Error_Report(ERROR_NO_MORE_FREE_TAG, ctrl);     /*\96{\93\96\82Í\82±\82±\82Å\81Actrl[0].addr\82ð\97\98\97p\82µ\82Ä\81A\95Ð\95û\8cü\83\8a\83X\83g\82É\93o\98^\82µ\82È\82¯\82ê\82Î\82¢\82¯\82È\82¢\81B*/\r
+               if(ctrl[k].size >= size){       /*\8dÅ\8f¬\82Ì\8bó\82«\83\81\83\82\83\8a\82Í\81A\89ð\95ú\82µ\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\8bó\82«\83\81\83\82\83\8a\82¾\82Á\82½\82Ì\82Å\81A\93o\98^\92\86\8e~*/\r
+                       IO_Store_EFlags(eflags);\r
+                       return;\r
+               } else if(j <= k){      /*\8dÅ\8f¬\82Ì\8bó\82«\83\81\83\82\83\8a\82Í\81A\89ð\95ú\82µ\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\8bó\82«\83\81\83\82\83\8a\82Ì\91}\93ü\88Ê\92u\82æ\82è\82à\8cã\82É\82 \82é*/\r
+                       for(; k > j; k--){\r
+                               ctrl[k] = ctrl[k - 1];\r
+                       }\r
+               } else if(j > k){       /*\8dÅ\8f¬\82Ì\8bó\82«\83\81\83\82\83\8a\82Í\81A\89ð\95ú\82µ\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\8bó\82«\83\81\83\82\83\8a\82Ì\91}\93ü\88Ê\92u\82æ\82è\82à\91O\82É\82 \82é*/\r
+                       for(; k < j - 1; k++){\r
+                               ctrl[k] = ctrl[k + 1];\r
+                       }\r
+                       j--;\r
+               }\r
+       } else{ /*\8bó\82«\82Í\8f\\95ª\82 \82é\82Ì\82Å\82¸\82ç\82·*/\r
+               if(i + 1 != ctrl[0].size - 1){\r
+                       ctrl[i + 1].addr = 0;\r
+                       ctrl[i + 1].size = 0xffffffff;\r
+               }\r
+               for(; i > j; i--){\r
+                       ctrl[i] = ctrl[i - 1];\r
+               }\r
+       }\r
+       ctrl[j].addr = addr;\r
+       ctrl[j].size = size;\r
+\r
+       Memory_Free_Sub(ctrl, j);\r
+\r
+       IO_Store_EFlags(eflags);\r
+\r
+       #ifdef CHNOSPROJECT_DEBUG_MEMORY_ALLOCATE_AND_FREE\r
+               debug("Memory_Free:ctrl:[0x%X] addr:[0x%X] size:0x%X\n", ctrl, addr, size);\r
+       #endif\r
+\r
+       return;\r
+}\r
+\r
+void Memory_Free_Sub(IO_MemoryControl ctrl, uint tagno)\r
+{\r
+       uint i, j, k;\r
+       uint eflags;\r
+\r
+       eflags = IO_Load_EFlags();\r
+\r
+       IO_CLI();\r
+\r
+       if(1 < tagno && tagno < ctrl[0].size - 1){\r
+               i = tagno - 1;\r
+               j = tagno + 1;\r
+       } else if(tagno == 1){\r
+               i = 1;\r
+               j = 2;\r
+       } else if(tagno == ctrl[0].size - 1){\r
+               i = ctrl[0].size - 2;\r
+               j = ctrl[0].size - 1;\r
+       } else{\r
+               Error_Report(ERROR_INVALID_FREE_MEMORY_INDEX, ctrl, tagno);\r
+               IO_Store_EFlags(eflags);\r
+               return;\r
+       }\r
+\r
+       for(; i < j; i++){\r
+               if(ctrl[i].addr + ctrl[i].size >= ctrl[i + 1].addr){    /*ctrl[i]\82Ì\8cã\82ë\82É\81Actrl[i + 1]\82ª\82Â\82È\82ª\82é*/\r
+                       if(ctrl[i].addr + ctrl[i].size > ctrl[i + 1].addr){     /*\94Í\88Í\82ª\8fd\82È\82Á\82Ä\82¢\82é*/\r
+                               Error_Report(ERROR_MEMORY_FREE_RANGE_OVERLAPPED, ctrl, i);\r
+                               ctrl[i].size = (uint)ctrl[i + 1].addr - (uint)ctrl[i].addr;\r
+                       }\r
+                       ctrl[i].size += ctrl[i + 1].size;\r
+                       for(k = i + 1; k < ctrl[0].size - 1; k++){\r
+                               if(ctrl[k].size == 0xffffffff){\r
+                                       break;\r
+                               }\r
+                               ctrl[k] = ctrl[k + 1];\r
+                       }\r
+                       if(k != ctrl[0].size - 1){\r
+                               ctrl[k].addr = 0;\r
+                               ctrl[k].size = 0xffffffff;\r
+                       }\r
+                       i -= 2;\r
+                       j--;\r
+               }\r
+       }\r
+       IO_Store_EFlags(eflags);\r
+       return;\r
+}\r
+\r
+void *Memory_Allocate(IO_MemoryControl ctrl, uint size)\r
+{\r
+       uint i;\r
+       void *addr;\r
+       uint eflags;\r
+\r
+       size = (size + 7) & ~7;\r
+\r
+#ifdef CHNOSPROJECT_DEBUG_MEMORY\r
+       debug("DEBUG:MemoryAllocate:Start ctrl:0x%08X size 0x%08X\n", ctrl, size);\r
+#endif\r
+\r
+       eflags = IO_Load_EFlags();\r
+\r
+       IO_CLI();\r
+\r
+       for(i = 1; i < ctrl[0].size; i++){\r
+               if(ctrl[i].size == 0xffffffff){ /*\8fI\92[*/\r
+                       break;\r
+               }\r
+               if(ctrl[i].size >= size){       /*\8f\\95ª\82È\8bó\82«\82ð\94­\8c©*/\r
+#ifdef CHNOSPROJECT_DEBUG_MEMORY\r
+       debug("DEBUG:MemoryAllocate:Found index:%d\n", i);\r
+#endif\r
+                       addr = ctrl[i].addr;\r
+                       if(ctrl[i].size == size){       /*\82Ò\82Á\82½\82è\82¾\82Á\82½\82Ì\82Å\8bó\82«\8fî\95ñ\82ð\94j\8aü*/\r
+                               for(; i < ctrl[0].size - 1; i++){\r
+                                       //\8fI\92[\82ð\94­\8c©\82µ\82½\82çBreak.\r
+                                       if(ctrl[i].size == 0xffffffff){\r
+                                               break;\r
+                                       }\r
+                                       //\83^\83O\82ð\83R\83s\81[\82µ\82Ä\91O\82É\8bl\82ß\82é\81B\r
+                                       ctrl[i] = ctrl[i + 1];\r
+                               }\r
+                               //\8bl\82ß\82½\8c\8b\89Ê\81A\8fI\92[\83^\83O\82ª\95K\97v\82¾\82Á\82½\82ç\92Ç\89Á\82·\82é\81i\82»\82ñ\82È\82±\82Æ\82È\82¢\82Í\82¸\82¾\82æ\82Ë\81H\81c\81j\r
+                               //if(i != ctrl[0].size){\r
+                               //      ctrl[i].addr = 0;\r
+                               //      ctrl[i].size = 0xffffffff;\r
+                               //}\r
+                       } else{ /*\82Ü\82¾\8ec\82Á\82Ä\82¢\82é\82Ì\82Å\8bó\82«\8fî\95ñ\82ð\92²\90®*/\r
+                               ctrl[i].addr += size;\r
+                               ctrl[i].size -= size;\r
+                       }\r
+                       IO_Store_EFlags(eflags);\r
+                       //\83\81\83\82\83\8a\82ð\83[\83\8d\83N\83\8a\83A\81B\r
+                       MOVSD_ZeroFill(addr, size);\r
+\r
+                       #ifdef CHNOSPROJECT_DEBUG_MEMORY_ALLOCATE_AND_FREE\r
+                                               debug("Memory_Alloc:ctrl:[0x%X] addr:[0x%X] size:0x%X\n", ctrl, addr, size);\r
+                       #endif\r
+\r
+                       return addr;\r
+               }\r
+       }\r
+\r
+       Error_Report(ERROR_NOT_ENOUGH_FREE_MEMORY, ctrl, size);\r
+\r
+       IO_Store_EFlags(eflags);\r
+\r
+       return 0;\r
+}\r
+\r
+void *Memory_Allocate_Aligned(IO_MemoryControl ctrl, uint size, uint align)\r
+/*align\82Í2\82Ì\99p\8fæ\94{\82Æ\82µ\82Ä\89ð\8eß\82·\82é\81B2\82Ì\99p\8fæ\94{\82Å\82È\82¢\8fê\8d\87\82Í\81A\8dÅ\91å\82Ì\83Z\83b\83g\82³\82ê\82Ä\82¢\82é\83r\83b\83g\82É\91Î\89\9e\82·\82é\92l\82Å\83A\83\89\83C\83\93\82³\82ê\82é*/\r
+{\r
+       uint i;\r
+       void *notaligned;\r
+       void *aligned;\r
+\r
+       if(align != 0){\r
+               for(i = 0; i < 32; i++){\r
+                       align = align >> 1;\r
+                       if(align == 0){\r
+                               break;\r
+                       }\r
+               }\r
+               notaligned = Memory_Allocate(ctrl, size + (1 << i) - 1);\r
+               aligned = (void *)((((uint)notaligned + (1 << i) - 1) >> i) << i);\r
+               Memory_Free(ctrl, notaligned, (uint)aligned - (uint)notaligned);\r
+               Memory_Free(ctrl, aligned + size, ((uint)notaligned + size + (1 << i) - 1) - ((uint)aligned + size));\r
+       } else{\r
+               aligned = Memory_Allocate(ctrl, size);\r
+       }\r
+\r
+       return aligned;\r
+}\r
+\r
+uint Memory_Get_FreeSize(IO_MemoryControl ctrl)\r
+{\r
+       uint i, size;\r
+\r
+       size = 0;\r
+       for(i = 1; i < ctrl[0].size; i++){\r
+               if(ctrl[i].size == 0xffffffff){\r
+                       break;\r
+               }\r
+               size += ctrl[i].size;\r
+       }\r
+\r
+       return size;\r
+}\r
+\r
+\r
+\r