114 lines
2.9 KiB
C
114 lines
2.9 KiB
C
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
typedef int _PDCLIB_fd_t;
|
|
|
|
static inline int32_t inline_syscall(uint32_t num, uint32_t arg1, uint32_t arg2, uint32_t arg3) {
|
|
int32_t ret;
|
|
asm volatile (
|
|
"int $0x80"
|
|
: "=a" (ret)
|
|
: "a" (num), "b" (arg1), "c" (arg2), "d" (arg3)
|
|
: "memory"
|
|
);
|
|
return ret;
|
|
}
|
|
|
|
void _exit(int status) {
|
|
inline_syscall(1, (uint32_t)status, 0, 0);
|
|
while(1) { asm volatile("hlt"); }
|
|
}
|
|
|
|
void _PDCLIB_exit(int status) {
|
|
_exit(status);
|
|
}
|
|
|
|
int _PDCLIB_read(_PDCLIB_fd_t fd, void *buf, size_t count) {
|
|
int32_t ret = inline_syscall(3, (uint32_t)fd, (uint32_t)buf, (uint32_t)count);
|
|
if (ret < 0) {
|
|
return 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int _PDCLIB_write(_PDCLIB_fd_t fd, const void *buf, size_t count) {
|
|
int32_t ret = inline_syscall(4, (uint32_t)fd, (uint32_t)buf, (uint32_t)count);
|
|
if (ret < 0) {
|
|
return 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
_PDCLIB_fd_t _PDCLIB_open(const char *filename, unsigned int mode) {
|
|
_PDCLIB_fd_t fd;
|
|
fd = inline_syscall(5, (uint32_t)filename, (uint32_t)mode, 0);
|
|
return fd;
|
|
}
|
|
|
|
int _PDCLIB_close(_PDCLIB_fd_t fd) {
|
|
return inline_syscall(6, (uint32_t)fd, 0, 0);
|
|
}
|
|
|
|
void * _PDCLIB_allocpages( size_t n ) {
|
|
// 1. Get the current page break
|
|
uint32_t current_break = inline_syscall(12, 0, 0, 0);
|
|
if (current_break == (uint32_t)-1) {
|
|
return NULL;
|
|
}
|
|
|
|
// 2. PDCLib requests memory in multiples of PAGES (typically 4096 bytes)
|
|
uint32_t new_break = current_break + (n * 4096);
|
|
|
|
// 3. Request kernel to move the break
|
|
uint32_t result = inline_syscall(12, new_break, 0, 0);
|
|
if (result != new_break) {
|
|
return NULL; // Allocation failed
|
|
}
|
|
|
|
// Return the start of the newly allocated region
|
|
return (void *)current_break;
|
|
}
|
|
|
|
int _PDCLIB_remove(const char *filename) { return -1; }
|
|
int _PDCLIB_rename(const char *old, const char *new) { return -1; }
|
|
long _PDCLIB_lseek(_PDCLIB_fd_t fd, long offset, int whence) { return -1; }
|
|
|
|
int open(const char *pathname, int flags, ...) {
|
|
_PDCLIB_fd_t fd = _PDCLIB_open(pathname, (unsigned int)flags);
|
|
return fd;
|
|
}
|
|
|
|
int read(int fd, void *buf, size_t count) {
|
|
_PDCLIB_fd_t file_desc = fd;
|
|
return _PDCLIB_read(file_desc, buf, count);
|
|
}
|
|
|
|
int write(int fd, const void *buf, size_t count) {
|
|
return _PDCLIB_write(fd, buf, count);
|
|
}
|
|
|
|
int close(int fd) {
|
|
_PDCLIB_fd_t file_desc = fd;
|
|
return _PDCLIB_close(file_desc);
|
|
}
|
|
|
|
void * sbrk(intptr_t increment) {
|
|
uint32_t current_break = inline_syscall(12, 0, 0, 0);
|
|
if (current_break == (uint32_t)-1) {
|
|
return (void *)-1;
|
|
}
|
|
|
|
if (increment == 0) {
|
|
return (void *)current_break;
|
|
}
|
|
|
|
uint32_t new_break = (uint32_t)((intptr_t)current_break + increment);
|
|
|
|
uint32_t result = inline_syscall(12, new_break, 0, 0);
|
|
|
|
if (result == new_break) {
|
|
return (void *)current_break;
|
|
}
|
|
|
|
return (void *)-1;
|
|
} |