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 (memphys_stackptr
==memphys_stackend
) {
64 // use pushed page as stackpage
65 if (paging_map(memphys_stackend
,addr
,0,1)<0) panic("Error while mapping stackpage: 0x%x",memphys_stackend
);
66 memphys_stackend
+= PAGE_SIZE
/sizeof(void*);
69 // just push page on stack
70 *memphys_stackptr
= addr
;
76 * Pops an address from stack
77 * @return Address popped from stack
78 * @todo Check whether address is already used for DMA
82 if (memphys_stackptr
>memphys_stackbase
) {
83 if (memphys_stackptr
-memphys_stackend
>PAGE_SIZE
) {
84 // free stackpage and return it
85 memphys_stackend
-= PAGE_SIZE
;
86 paging_unmap(memphys_stackend
);
87 page
= memphys_stackend
;
90 // just get page from stack
92 page
= *memphys_stackptr
;
95 else panic("Ran out of memory\n");
100 * Returns the amount of remaining memory
101 * @return Amount of remaining memory in bytes
103 size_t memphys_memleft() {
104 return (((size_t)memphys_stackptr
)-((size_t)memphys_stackbase
))*PAGE_SIZE
/4;
108 * Initializes DMA management
111 int memphys_dma_init() {
112 memphys_dma_bitmap_size
= MEMPHYS_DMALIMIT
/(PAGE_SIZE
*8);
113 memphys_dma_bitmap
= malloc(memphys_dma_bitmap_size
);
114 // memory until free memory (BDA, Kernel Code, Stack)
115 memset(memphys_dma_bitmap
,0xFF,FREEPHYS_ADDRESS
/(PAGE_SIZE
*8));
117 memset(((void*)memphys_dma_bitmap
)+FREEPHYS_ADDRESS
/(PAGE_SIZE
*8),0,memphys_dma_bitmap_size
-FREEPHYS_ADDRESS
/(PAGE_SIZE
*8));
122 * Gets free DMA pages
123 * @param pages Amount of requested pages
124 * @return Address of first page
126 void *memphys_dma_alloc(size_t pages
) {
129 for (i
=0;i
<MEMPHYS_DMALIMIT
/PAGE_SIZE
;i
++) {
130 if (!(memphys_dma_bitmap
[i
/(8*sizeof(int))]&(1<<(i
%(8*sizeof(int)))))) found
++;
134 for (j
=i
-(found
-1);j
<=i
;j
++) memphys_dma_bitmap
[j
/(8*sizeof(int))] |= 1<<(j
%(8*sizeof(int)));
135 return (void*)((i
-(found
-1))*PAGE_SIZE
);
143 * @param addr Address of DMA page
145 void memphys_dma_free(void *addr
) {
146 size_t i
= ((size_t)addr
)/PAGE_SIZE
;
147 memphys_dma_bitmap
[i
/(8*sizeof(int))] &= ~(1<<(i
%(8*sizeof(int))));