added an untested pmm for every machine except for PC
This commit is contained in:
parent
d0736af522
commit
8f9423b5cd
20 changed files with 384 additions and 30 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -16,3 +16,5 @@ latex/
|
||||||
int.s
|
int.s
|
||||||
regs.h
|
regs.h
|
||||||
out/
|
out/
|
||||||
|
*.mmap
|
||||||
|
*.mh
|
||||||
|
|
78
buildtools/mmapcomp.py
Executable file
78
buildtools/mmapcomp.py
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys,os
|
||||||
|
sf = sys.argv[1]
|
||||||
|
tf = os.path.splitext(sf)[0] + ".mmap"
|
||||||
|
hf = os.path.splitext(sf)[0] + ".mh"
|
||||||
|
with open(sf) as f:
|
||||||
|
code = [ x[:-1] for x in f.readlines()]
|
||||||
|
obj = []
|
||||||
|
endian='little'
|
||||||
|
bits=32
|
||||||
|
for line in code:
|
||||||
|
data = b''
|
||||||
|
a = line.split(' ')
|
||||||
|
if a[0] == "DEVICETYPE":
|
||||||
|
data+=b'\x00'
|
||||||
|
data+=b'\x01'
|
||||||
|
devicetypes={"PC":b'\x00', "CONSOLE":b'\x01', "EMBEDDED":b'\x02'}
|
||||||
|
data+=devicetypes[a[1]]
|
||||||
|
elif a[0] == "DEVICENAME":
|
||||||
|
data+=b'\x01'
|
||||||
|
data+=len(a[1]).to_bytes(1,'little')
|
||||||
|
data+=a[1].encode("UTF-8")
|
||||||
|
elif a[0] == "CPUARCH":
|
||||||
|
data+=b'\x02'
|
||||||
|
data+=b'\x01'
|
||||||
|
archs = {"X86":b'\x00', "X86_64":b'\x01', "ARM":b'\x02'}
|
||||||
|
data+=archs[a[1]]
|
||||||
|
elif a[0] == "ENDIAN":
|
||||||
|
data+=b'\x03'
|
||||||
|
data+=b'\x01'
|
||||||
|
if a[1] == "BIG":
|
||||||
|
data+=b'\x00'
|
||||||
|
endian='big'
|
||||||
|
else:
|
||||||
|
data+=b'\x01'
|
||||||
|
endian="little"
|
||||||
|
elif a[0] == "BITS":
|
||||||
|
data+=b'\x04'
|
||||||
|
data+=b'\x01'
|
||||||
|
if a[1] == "32":
|
||||||
|
data+=b'\x20'
|
||||||
|
bits=32
|
||||||
|
else:
|
||||||
|
data+=b'\x40'
|
||||||
|
bits=64
|
||||||
|
elif a[0] == "REGION":
|
||||||
|
data+=b'\x05'
|
||||||
|
data+=(bits//4+1).to_bytes(1,endian)
|
||||||
|
data+=int(a[1],16).to_bytes(bits//8,endian)
|
||||||
|
data+=int(a[2],16).to_bytes(bits//8,endian)
|
||||||
|
perms={
|
||||||
|
"NONE": 0,
|
||||||
|
"X": 1,
|
||||||
|
"W": 2,
|
||||||
|
"WX": 3,
|
||||||
|
"R": 4,
|
||||||
|
"RX": 5,
|
||||||
|
"RW": 6,
|
||||||
|
"RWX": 7
|
||||||
|
}
|
||||||
|
data+=perms[a[3]].to_bytes(1,endian)
|
||||||
|
elif a[0] == "":
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown command '"+a[0]+"'")
|
||||||
|
obj.append(data)
|
||||||
|
mmdata = b'MMAP' + bytes(4) + len(obj).to_bytes(4,'little')
|
||||||
|
for o in obj:
|
||||||
|
mmdata += o
|
||||||
|
with open(tf,"wb") as f:
|
||||||
|
f.write(mmdata)
|
||||||
|
with open(hf, "w") as f:
|
||||||
|
f.write("#pragma once\n")
|
||||||
|
f.write("#include <stdint.h>\n")
|
||||||
|
f.write("uint8_t mmap[] = {\n")
|
||||||
|
for b in mmdata:
|
||||||
|
f.write(hex(b)+", ")
|
||||||
|
f.write("\n};\n")
|
95
docs/mmap.md
Normal file
95
docs/mmap.md
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# Memory Map File Format
|
||||||
|
## .mc - Clear text Memory Map
|
||||||
|
| Identifier | Meaning |
|
||||||
|
|------------|----------------------------------------------------------|
|
||||||
|
|`DEVICETYPE`|Type of the device. One of `PC`, `CONSOLE` and `EMBEDDED` |
|
||||||
|
|`DEVICENAME`|Pascal strings containing the name of the device |
|
||||||
|
|`CPUARCH` | Architecture. Currently one of `X86`, `X86_64` and `ARM` |
|
||||||
|
|`ENDIAN` | `BIG` or `LITTLE` |
|
||||||
|
|`BITS` | `32` or `64` |
|
||||||
|
|`REGION` | A region of Memory. Arguments are `START_ADDR`, `END_ADDR`, and `PERMISSIONS` (`R`, `RW`, `RX`, `RWX`) Only memory with `RWX` permissions can be allocated. |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
DEVICETYPE CONSOLE
|
||||||
|
DEVICENAME 3DS9
|
||||||
|
CPUARCH ARM
|
||||||
|
ENDIAN LITTLE
|
||||||
|
BITS 32
|
||||||
|
REGION 0x00000000 0x00008000 RWX
|
||||||
|
REGION 0x08000000 0x08100000 RWX
|
||||||
|
REGION 0x10000000 0x18000000 RW
|
||||||
|
REGION 0x18000000 0x18600000 RW
|
||||||
|
REGION 0x1FF00000 0x1FF80000 RW
|
||||||
|
REGION 0x1FF80000 0x20000000 RW
|
||||||
|
REGION 0x20000000 0x28000000 RW
|
||||||
|
|
||||||
|
## .mmap - Compiled Memory Map
|
||||||
|
### Header
|
||||||
|
|
||||||
|
The header is always little-endian
|
||||||
|
|
||||||
|
| Offset | Width | Meaning |
|
||||||
|
|--------|-------|---------|
|
||||||
|
| `0x00` | 4 | Magic number `MMAP` |
|
||||||
|
| `0x04` | 4 | Version (Currently 0) |
|
||||||
|
| `0x08` | 4 | Tag count |
|
||||||
|
|
||||||
|
### Tag format
|
||||||
|
|
||||||
|
| Offset | Width | Meaning |
|
||||||
|
|--------|-------|---------|
|
||||||
|
| `0x00` | 1 | Tag type |
|
||||||
|
| `0x01` | 1 | Tag size |
|
||||||
|
| `0x02` | 2 | Paddding |
|
||||||
|
|
||||||
|
### Supported tags
|
||||||
|
| Tag Type | Size | Name |
|
||||||
|
|-|-|-|
|
||||||
|
| `0x00` | 1 | `DEVICETYPE` |
|
||||||
|
| `0x01` | variable | `DEVICENAME` |
|
||||||
|
| `0x02` | 1 | `CPUARCH` |
|
||||||
|
| `0x03` | 1 | `ENDIAN` |
|
||||||
|
| `0x04` | 1 | `BITS` |
|
||||||
|
| `0x05` | `BITS`/4 + 1 | `REGION` |
|
||||||
|
#### `DEVICETYPE`
|
||||||
|
| Value | Meaning |
|
||||||
|
|-|-|
|
||||||
|
| `0` | `PC` |
|
||||||
|
| `1` | `CONSOLE` |
|
||||||
|
| `2` | `EMBEDDED` |
|
||||||
|
|
||||||
|
#### `CPUARCH`
|
||||||
|
| Value | Meaning |
|
||||||
|
|-|-|
|
||||||
|
| 0 | `X86` |
|
||||||
|
| 1 | `X86_64` |
|
||||||
|
| 2 | `ARM` |
|
||||||
|
|
||||||
|
#### `ENDIAN`
|
||||||
|
| Value | Meaning |
|
||||||
|
|-|-|
|
||||||
|
| 0 | `BIG` |
|
||||||
|
| 1 | `LITTLE` |
|
||||||
|
|
||||||
|
#### `BITS`
|
||||||
|
This is a 8-bit integer
|
||||||
|
|
||||||
|
#### `REGION`
|
||||||
|
| Offset | Length | Meaning |
|
||||||
|
|-|-|-|
|
||||||
|
| 0 | `BITS`/8 | Start address |
|
||||||
|
| `BITS`/8 | `BITS`/8 | End address |
|
||||||
|
| `BITS`/4 | 1 | Permissions |
|
||||||
|
|
||||||
|
Permissions:
|
||||||
|
| Value | Meaning |
|
||||||
|
|-|-|
|
||||||
|
| `0` | No permission |
|
||||||
|
| `1` | `X` |
|
||||||
|
| `2` | `W` |
|
||||||
|
| `3` | `WX`|
|
||||||
|
| `4` | `R` |
|
||||||
|
| `5` | `RX` |
|
||||||
|
| `6` | `RW` |
|
||||||
|
| `7` | `RWX` |
|
|
@ -2,4 +2,6 @@ config["LOWEST_CPU"] = "arm11mpcore"
|
||||||
config["ENABLE_HARD"] = get_yes_no("Enable VFP ABI", True)
|
config["ENABLE_HARD"] = get_yes_no("Enable VFP ABI", True)
|
||||||
if not config["ENABLE_HARD"]:
|
if not config["ENABLE_HARD"]:
|
||||||
config["ENABLE_THUMB"] = get_yes_no("Enable Thumb")
|
config["ENABLE_THUMB"] = get_yes_no("Enable Thumb")
|
||||||
|
import sys
|
||||||
|
sys.argv=["","kernel/mmaps/3ds11.mc"]
|
||||||
|
from buildtools import mmapcomp
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "../../../hw/3ds11/vectorinit/vectorinit.hpp"
|
#include "../../../hw/3ds11/vectorinit/vectorinit.hpp"
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include "../../../mmaps/3ds11.mh"
|
||||||
|
|
||||||
PICAfb term;
|
PICAfb term;
|
||||||
void main();
|
void main();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
config["LOWEST_CPU"] = "arm946e-s"
|
config["LOWEST_CPU"] = "arm946e-s"
|
||||||
config["ENABLE_THUMB"] = get_yes_no("Enable Thumb", True)
|
config["ENABLE_THUMB"] = get_yes_no("Enable Thumb", True)
|
||||||
|
import sys
|
||||||
|
sys.argv=["","kernel/mmaps/3ds9.mc"]
|
||||||
|
from buildtools import mmapcomp
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "../../../hw/3ds9/vectorinit/vectorinit.hpp"
|
#include "../../../hw/3ds9/vectorinit/vectorinit.hpp"
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include "../../../mmaps/3ds9.mh"
|
||||||
|
|
||||||
PICAfb term;
|
PICAfb term;
|
||||||
void main();
|
void main();
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
config["LOWEST_CPU"] = "cortex-a7"
|
config["LOWEST_CPU"] = "cortex-a7"
|
||||||
|
import sys
|
||||||
|
sys.argv=["","kernel/mmaps/raspi2.mc"]
|
||||||
|
from buildtools import mmapcomp
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "../../../hw/raspi2/vector/vector.hpp"
|
#include "../../../hw/raspi2/vector/vector.hpp"
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include "../../../mmaps/raspi2.mh"
|
||||||
|
|
||||||
Serial term;
|
Serial term;
|
||||||
void main();
|
void main();
|
||||||
|
|
|
@ -8,6 +8,6 @@ if config["ENABLE_I2C"]:
|
||||||
add_driver(True, "framebuffer")
|
add_driver(True, "framebuffer")
|
||||||
add_driver(False, "picafb")
|
add_driver(False, "picafb")
|
||||||
add_driver(False, "vectorinit")
|
add_driver(False, "vectorinit")
|
||||||
add_driver(False, "pmm")
|
add_driver(True, "pmm")
|
||||||
print("Enable complete Unicode font: NO (because of the size)")
|
print("Enable complete Unicode font: NO (because of the size)")
|
||||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
||||||
|
|
|
@ -2,6 +2,6 @@ config["ENABLE_EXTRA_MEMORY"] = get_yes_no("Enable 512KB of memory on n3DS", Tru
|
||||||
add_driver(True, "framebuffer")
|
add_driver(True, "framebuffer")
|
||||||
add_driver(False, "picafb")
|
add_driver(False, "picafb")
|
||||||
add_driver(False, "vectorinit")
|
add_driver(False, "vectorinit")
|
||||||
add_driver(False, "pmm")
|
add_driver(True, "pmm")
|
||||||
print("Enable complete Unicode font: NO (because of the size)")
|
print("Enable complete Unicode font: NO (because of the size)")
|
||||||
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
config["ENABLE_FRAMEBUFFER_UNICODE"] = False
|
||||||
|
|
134
kernel/hw/pmm/pmm.cpp
Normal file
134
kernel/hw/pmm/pmm.cpp
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
#include "pmm.hpp"
|
||||||
|
#include <base.hpp>
|
||||||
|
enum class DEVICETYPE: uint8_t {
|
||||||
|
PC,
|
||||||
|
CONSOLE,
|
||||||
|
EMBEDDED
|
||||||
|
};
|
||||||
|
enum class CPUARCH: uint8_t {
|
||||||
|
X86,
|
||||||
|
X86_64,
|
||||||
|
ARM
|
||||||
|
};
|
||||||
|
enum class ENDIAN: uint8_t {
|
||||||
|
BIG,
|
||||||
|
LITTLE
|
||||||
|
};
|
||||||
|
enum class PERM: uint8_t {
|
||||||
|
NONE,
|
||||||
|
X,
|
||||||
|
W,
|
||||||
|
WX,
|
||||||
|
R,
|
||||||
|
RX,
|
||||||
|
RW,
|
||||||
|
RWX
|
||||||
|
};
|
||||||
|
struct MMAP {
|
||||||
|
char magic[4];
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t length;
|
||||||
|
}__attribute__((packed));
|
||||||
|
union MMAPTag {
|
||||||
|
struct {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t size;
|
||||||
|
}__attribute__((packed));
|
||||||
|
struct {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t size;
|
||||||
|
DEVICETYPE value;
|
||||||
|
}__attribute__((packed)) DEVICETYPE;
|
||||||
|
struct {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t size;
|
||||||
|
char value[1];
|
||||||
|
}__attribute__((packed)) DEVICENAME;
|
||||||
|
struct {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t size;
|
||||||
|
CPUARCH value;
|
||||||
|
}__attribute__((packed)) CPUARCH;
|
||||||
|
struct {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t size;
|
||||||
|
ENDIAN endian;
|
||||||
|
}__attribute__((packed)) ENDIAN;
|
||||||
|
struct {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t value;
|
||||||
|
}__attribute__((packed)) BITS;
|
||||||
|
struct {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t size;
|
||||||
|
phys_t start;
|
||||||
|
phys_t end;
|
||||||
|
PERM permission;
|
||||||
|
}__attribute__((packed)) REGION;
|
||||||
|
};
|
||||||
|
extern uint8_t mmap;
|
||||||
|
|
||||||
|
PMM_MMAP::PMM_MMAP(): PMM(0x1000) {
|
||||||
|
MMAP &header = *((MMAP*)&mmap);
|
||||||
|
if((header.magic[0] != 'M')||(header.magic[1] != 'M')||(header.magic[2] != 'A')||(header.magic[3] != 'P'))
|
||||||
|
for(;;); //This is not a mmap
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
header.length = __builtin_bswap32(header.length);
|
||||||
|
#endif
|
||||||
|
uint8_t *off=(uint8_t*)(&header+1);
|
||||||
|
for(uint32_t i=0;i<header.length;i++) {
|
||||||
|
MMAPTag &tag = *((MMAPTag*)off);
|
||||||
|
off+=tag.size;
|
||||||
|
switch(tag.id) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 5:
|
||||||
|
break; //Ignored for now
|
||||||
|
case 2: //CPUARCH
|
||||||
|
if(tag.CPUARCH.value !=
|
||||||
|
#ifdef __i386__
|
||||||
|
CPUARCH::X86
|
||||||
|
#else
|
||||||
|
#ifdef __x86_64__
|
||||||
|
CPUARCH::X86_64
|
||||||
|
#else
|
||||||
|
CPUARCH::ARM
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
for(;;);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
hostEndian = tag.ENDIAN.endian ==
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
ENDIAN::BIG
|
||||||
|
#else
|
||||||
|
ENDIAN::LITTLE
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
bits = tag.BITS.value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PMM_MMAP::~PMM_MMAP() {}
|
||||||
|
auto PMM_MMAP::isFree(phys_t addr) -> bool {
|
||||||
|
MMAP &header = *((MMAP*)&mmap);
|
||||||
|
uint8_t *off=(uint8_t*)(&header+1);
|
||||||
|
for(uint32_t i=0;i<header.length;i++) {
|
||||||
|
MMAPTag &tag = *((MMAPTag*)off);
|
||||||
|
off+=tag.size;
|
||||||
|
if(tag.id != 5)
|
||||||
|
continue;
|
||||||
|
if((tag.REGION.start > addr) || (tag.REGION.end < addr))
|
||||||
|
continue;
|
||||||
|
if(tag.REGION.permission == PERM::RWX)
|
||||||
|
return PMM::isFree(addr);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
11
kernel/hw/pmm/pmm.hpp
Normal file
11
kernel/hw/pmm/pmm.hpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
#include <pmm.hpp>
|
||||||
|
class PMM_MMAP: public PMM {
|
||||||
|
protected:
|
||||||
|
uint8_t bits;
|
||||||
|
bool hostEndian;
|
||||||
|
virtual auto isFree(phys_t addr) -> bool;
|
||||||
|
public:
|
||||||
|
PMM_MMAP();
|
||||||
|
virtual ~PMM_MMAP();
|
||||||
|
};
|
|
@ -1,3 +1,4 @@
|
||||||
add_driver(False, "uart")
|
add_driver(False, "uart")
|
||||||
add_driver(False, "serial")
|
add_driver(False, "serial")
|
||||||
add_driver(False, "vector")
|
add_driver(False, "vector")
|
||||||
|
add_driver(True, "pmm")
|
||||||
|
|
11
kernel/mmaps/3ds11.mc
Normal file
11
kernel/mmaps/3ds11.mc
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
DEVICETYPE CONSOLE
|
||||||
|
DEVICENAME 3DS11
|
||||||
|
CPUARCH ARM
|
||||||
|
ENDIAN LITTLE
|
||||||
|
BITS 32
|
||||||
|
REGION 0x00000000 0x00010000 RX
|
||||||
|
REGION 0x10000000 0x18000000 RW
|
||||||
|
REGION 0x18000000 0x18600000 RW
|
||||||
|
REGION 0x1FF00000 0x1FF80000 RW
|
||||||
|
REGION 0x1FF80000 0x20000000 RW
|
||||||
|
REGION 0x20000000 0x28000000 RWX
|
14
kernel/mmaps/3ds9.mc
Normal file
14
kernel/mmaps/3ds9.mc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
DEVICETYPE CONSOLE
|
||||||
|
DEVICENAME 3DS9
|
||||||
|
CPUARCH ARM
|
||||||
|
ENDIAN LITTLE
|
||||||
|
BITS 32
|
||||||
|
REGION 0x00000000 0x00008000 RW
|
||||||
|
REGION 0x08000000 0x08100000 RWX
|
||||||
|
REGION 0x10000000 0x18000000 RW
|
||||||
|
REGION 0x18000000 0x18600000 RW
|
||||||
|
REGION 0x1FF00000 0x1FF80000 RW
|
||||||
|
REGION 0x1FF80000 0x20000000 RW
|
||||||
|
REGION 0x20000000 0x28000000 RW
|
||||||
|
REGION 0xFFF00000 0xFFF04000 RW
|
||||||
|
REGION 0xFFFF0000 0x00000000 RX
|
6
kernel/mmaps/raspi2.mc
Normal file
6
kernel/mmaps/raspi2.mc
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
DEVICETYPE CONSOLE
|
||||||
|
DEVICENAME RASPI2
|
||||||
|
CPUARCH ARM
|
||||||
|
ENDIAN LITTLE
|
||||||
|
BITS 32
|
||||||
|
REGION 0x00000000 0x40000000 RWX
|
|
@ -11,3 +11,11 @@ void setMainTTY(TTY *obj);
|
||||||
* Halts the kernel due to a unresolvable error
|
* Halts the kernel due to a unresolvable error
|
||||||
*/
|
*/
|
||||||
extern "C" void panic(const char* s);
|
extern "C" void panic(const char* s);
|
||||||
|
|
||||||
|
#if !defined(__LITTLE_ENDIAN__) || !defined(__BIG_ENDIAN__)
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
#define __LITTLE_ENDIAN__
|
||||||
|
#else
|
||||||
|
#define __BIG_ENDIAN__
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
typedef uintptr_t phys_t; ///< Type used for physical addresses
|
typedef uintptr_t phys_t; ///< Type used for physical addresses
|
||||||
/**
|
/**
|
||||||
* A single entry in the PMM list
|
* A single entry in the PMM list
|
||||||
|
@ -7,13 +9,6 @@ struct PMM_ent {
|
||||||
PMM_ent* next; ///< Next element in the list
|
PMM_ent* next; ///< Next element in the list
|
||||||
phys_t val; ///< This for not having to cast in the code.
|
phys_t val; ///< This for not having to cast in the code.
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* Structure for a memory map
|
|
||||||
*/
|
|
||||||
struct mmap_ent {
|
|
||||||
phys_t start;
|
|
||||||
phys_t end;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Physical memory manager. It stores the free memory in a linked list
|
* Physical memory manager. It stores the free memory in a linked list
|
||||||
*/
|
*/
|
||||||
|
@ -23,12 +18,12 @@ class PMM {
|
||||||
virtual auto isFree(phys_t addr) -> bool; ///< Returns true if the provided page is free to use
|
virtual auto isFree(phys_t addr) -> bool; ///< Returns true if the provided page is free to use
|
||||||
phys_t page_size; ///< Contains the size of a single memory page, in bytes
|
phys_t page_size; ///< Contains the size of a single memory page, in bytes
|
||||||
public:
|
public:
|
||||||
PMM(phys_t page_size, mmap_ent *entries, int length);
|
PMM(phys_t page_size);
|
||||||
virtual ~PMM();
|
virtual ~PMM();
|
||||||
virtual auto operator<<(phys_t page) -> PMM &; ///< Frees a page. O(1)
|
virtual auto operator<<(phys_t page) -> PMM &; ///< Frees a page. O(1)
|
||||||
virtual auto operator>>(phys_t &page) -> PMM &; ///< Allocates a page. O(1)
|
virtual auto operator>>(phys_t &page) -> PMM &; ///< Allocates a page. O(1)
|
||||||
virtual auto operator,(size_t no_pages) -> phys_t; ///< Allocates multiple pages. O(n²)
|
virtual auto operator,(size_t no_pages) -> phys_t; ///< Allocates multiple pages. O(n²)
|
||||||
virtual auto operator(phys_t pages,size_t no_pages) -> void; ///< Deallocates multiple pages. O(n)
|
virtual auto operator()(phys_t pages,size_t no_pages) -> void; ///< Deallocates multiple pages. O(n)
|
||||||
virtual auto operator&&(phys_t page) -> bool; //Returns true if this page is free. O(n).
|
virtual auto operator&&(phys_t page) -> bool; //Returns true if this page is free. O(n).
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
@ -37,4 +32,3 @@ class PMM {
|
||||||
#define in and
|
#define in and
|
||||||
|
|
||||||
auto operator&&(phys_t a, PMM mm) -> bool; ///< Returns true when page is free. Used for syntax `page in pmm`
|
auto operator&&(phys_t a, PMM mm) -> bool; ///< Returns true when page is free. Used for syntax `page in pmm`
|
||||||
auto operator&&(phys_t a, PMM *mm) -> bool; ///< Returns true when page is free. Present in case that mm is a pointer.
|
|
||||||
|
|
|
@ -11,22 +11,16 @@ auto PMM::isFree(phys_t addr) -> bool {
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
PMM::PMM(phys_t page_size, mmap_ent *entries, int length): page_size(page_size), head(nullptr) {
|
PMM::PMM(phys_t page_size): page_size(page_size), head(nullptr) {
|
||||||
for(int i=0;i< length; i++) {
|
|
||||||
for(phys_t j=entries[i].start;j<entries[i].end;j+=page_size) {
|
|
||||||
if(isFree(j))
|
|
||||||
*this << j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PMM::~PMM() {}
|
PMM::~PMM() {}
|
||||||
|
|
||||||
auto PMM::operator<<(phys_t page) -> PMM & {
|
auto PMM::operator<<(phys_t page) -> PMM & {
|
||||||
*this(page,1);
|
(*this)(page,1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
auto PMM::operator>>(phys_t &page) -> PMM & {
|
auto PMM::operator>>(phys_t &page) -> PMM & {
|
||||||
page = *this, 1;
|
page = (*this, 1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +56,7 @@ auto PMM::operator,(size_t no_pages) -> phys_t {
|
||||||
}
|
}
|
||||||
panic("Not enough continuous free memory is available.");
|
panic("Not enough continuous free memory is available.");
|
||||||
}
|
}
|
||||||
auto PMM::operator(phys_t pages, size_t no_pages) -> void {
|
auto PMM::operator()(phys_t pages, size_t no_pages) -> void {
|
||||||
for(size_t i=0; i<no_pages; i++, pages+=page_size) {
|
for(size_t i=0; i<no_pages; i++, pages+=page_size) {
|
||||||
PMM_ent *curr=(PMM_ent *)pages;
|
PMM_ent *curr=(PMM_ent *)pages;
|
||||||
curr->next=head;
|
curr->next=head;
|
||||||
|
@ -70,10 +64,10 @@ auto PMM::operator(phys_t pages, size_t no_pages) -> void {
|
||||||
head=curr;
|
head=curr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual auto operator&&(phys_t page) -> bool {
|
auto PMM::operator&&(phys_t page) -> bool {
|
||||||
PMM_ent *curr = head;
|
PMM_ent *curr = head;
|
||||||
while(curr) {
|
while(curr) {
|
||||||
if(curr->value==page)
|
if(curr->val==page)
|
||||||
return true;
|
return true;
|
||||||
curr=curr->next;
|
curr=curr->next;
|
||||||
}
|
}
|
||||||
|
@ -82,6 +76,3 @@ virtual auto operator&&(phys_t page) -> bool {
|
||||||
auto operator&&(phys_t a, PMM mm) -> bool {
|
auto operator&&(phys_t a, PMM mm) -> bool {
|
||||||
return mm && a;
|
return mm && a;
|
||||||
}
|
}
|
||||||
auto operator&&(phys_t a, PMM *mm) -> bool {
|
|
||||||
return a in *mm;
|
|
||||||
}
|
|
Loading…
Reference in a new issue