2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
22 #include <multiboot.h>
27 #include <memkernel.h>
31 * Initializes physical memory management
32 * @return -1=Success; 0=Failure
35 memphys_memory
= (multiboot_get_memlower()+multiboot_get_memlower());
37 memphys_stackbase
= (void*)STACKDATA_ADDRESS
;
38 memphys_stackend
= memphys_stackbase
;
39 memphys_stackptr
= memphys_stackbase
;
41 // push free memory on stack
45 multiboot_mmap_type_t type
;
46 while (multiboot_get_mmap(i
++,&addr
,&size
,&type
)==0) {
47 if (type
==MULTIBOOT_FREE
) {
49 for (j
=0;j
<size
/PAGE_SIZE
;j
++) {
50 if (addr
+j
*PAGE_SIZE
>=(void*)FREEPHYS_ADDRESS
) memphys_push(addr
+j
*PAGE_SIZE
);
59 * Pushs an address on stack
60 * @param addr Address to push on stack
62 void memphys_push(void *addr
) {
63 if (addr
==NULL
) return;
64 if (memphys_stackptr
==memphys_stackend
) {
65 // use pushed page as stackpage
66 if (paging_map(memphys_stackend
,addr
,0,1)<0) panic("Error while mapping stackpage: 0x%x",memphys_stackend
);
67 memphys_stackend
+= PAGE_SIZE
/sizeof(void*);
70 // just push page on stack
71 *memphys_stackptr
= addr
;
77 * Pops an address from stack
78 * @return Address popped from stack
79 * @todo Check whether address is already used for DMA
83 if (memphys_stackptr
>memphys_stackbase
) {
84 if (memphys_stackptr
-memphys_stackend
>PAGE_SIZE
) {
85 // free stackpage and return it
86 memphys_stackend
-= PAGE_SIZE
;
87 paging_unmap(memphys_stackend
);
88 page
= memphys_stackend
;
91 // just get page from stack
93 page
= *memphys_stackptr
;
96 else panic("Ran out of memory\n");
101 * Returns the amount of remaining memory
102 * @return Amount of remaining memory in bytes
104 size_t memphys_memleft() {
105 return (((size_t)memphys_stackptr
)-((size_t)memphys_stackbase
))*PAGE_SIZE
/4;
109 * Initializes DMA management
112 int memphys_dma_init() {
113 memphys_dma_bitmap_size
= MEMPHYS_DMALIMIT
/(PAGE_SIZE
*8);
114 memphys_dma_bitmap
= malloc(memphys_dma_bitmap_size
);
115 // memory until free memory (BDA, Kernel Code, Stack)
116 memset(memphys_dma_bitmap
,0xFF,FREEPHYS_ADDRESS
/(PAGE_SIZE
*8));
118 memset(((void*)memphys_dma_bitmap
)+FREEPHYS_ADDRESS
/(PAGE_SIZE
*8),0,memphys_dma_bitmap_size
-FREEPHYS_ADDRESS
/(PAGE_SIZE
*8));
123 * Gets free DMA pages
124 * @param pages Amount of requested pages
125 * @return Address of first page
127 void *memphys_dma_alloc(size_t pages
) {
130 for (i
=0;i
<MEMPHYS_DMALIMIT
/PAGE_SIZE
;i
++) {
131 if (!(memphys_dma_bitmap
[i
/(8*sizeof(int))]&(1<<(i
%(8*sizeof(int)))))) found
++;
135 for (j
=i
-(found
-1);j
<=i
;j
++) memphys_dma_bitmap
[j
/(8*sizeof(int))] |= 1<<(j
%(8*sizeof(int)));
136 return (void*)((i
-(found
-1))*PAGE_SIZE
);
144 * @param addr Address of DMA page
146 void memphys_dma_free(void *addr
) {
147 size_t i
= ((size_t)addr
)/PAGE_SIZE
;
148 memphys_dma_bitmap
[i
/(8*sizeof(int))] &= ~(1<<(i
%(8*sizeof(int))));