189 lines
5.7 KiB
C
189 lines
5.7 KiB
C
/* lib.h - Defines for useful library functions
|
|
* vim:ts=4 noexpandtab
|
|
*/
|
|
|
|
#ifndef _LIB_H
|
|
#define _LIB_H
|
|
|
|
#include "types.h"
|
|
|
|
#define SUCCESS 0
|
|
#define PASS 0
|
|
#define FAIL -1
|
|
|
|
#define VIDEO 0xB8000
|
|
#define NUM_COLS 80
|
|
#define NUM_ROWS 25
|
|
#define ATTRIB 0x7
|
|
#define BACKSPACE 0x8
|
|
#define NULL_CHAR 0
|
|
|
|
#define TERMINAL_DIRECT_ADDR 0xb7000
|
|
|
|
extern char* video_mem;
|
|
|
|
void infinite_loop();
|
|
void wait_interrupt();
|
|
int32_t printf(int8_t *format, ...);
|
|
void putc(uint8_t c);
|
|
void roll_up();
|
|
int32_t puts(int8_t *s);
|
|
int8_t *itoa(uint32_t value, int8_t* buf, int32_t radix);
|
|
int8_t *strrev(int8_t* s);
|
|
uint32_t strlen(const int8_t* s);
|
|
void clear(void);
|
|
|
|
void* memset(void* s, int32_t c, uint32_t n);
|
|
void* memset_word(void* s, int32_t c, uint32_t n);
|
|
void* memset_dword(void* s, int32_t c, uint32_t n);
|
|
void* memcpy(void* dest, const void* src, uint32_t n);
|
|
void* memmove(void* dest, const void* src, uint32_t n);
|
|
int32_t strncmp(const int8_t* s1, const int8_t* s2, uint32_t n);
|
|
int8_t* strcpy(int8_t* dest, const int8_t*src);
|
|
int8_t* strncpy(int8_t* dest, const int8_t*src, uint32_t n);
|
|
|
|
/* Userspace address-check functions */
|
|
int32_t bad_userspace_addr(const void* addr, int32_t len);
|
|
int32_t safe_strncpy(int8_t* dest, const int8_t* src, int32_t n);
|
|
|
|
/* Port read functions */
|
|
/* Inb reads a byte and returns its value as a zero-extended 32-bit
|
|
* unsigned int */
|
|
static inline uint32_t inb(port) {
|
|
uint32_t val;
|
|
asm volatile (" \n\
|
|
xorl %0, %0 \n\
|
|
inb (%w1), %b0 \n\
|
|
"
|
|
: "=a"(val)
|
|
: "d"(port)
|
|
: "memory"
|
|
);
|
|
return val;
|
|
}
|
|
|
|
/* Reads two bytes from two consecutive ports, starting at "port",
|
|
* concatenates them little-endian style, and returns them zero-extended
|
|
* */
|
|
static inline uint32_t inw(port) {
|
|
uint32_t val;
|
|
asm volatile (" \n\
|
|
xorl %0, %0 \n\
|
|
inw (%w1), %w0 \n\
|
|
"
|
|
: "=a"(val)
|
|
: "d"(port)
|
|
: "memory"
|
|
);
|
|
return val;
|
|
}
|
|
|
|
/* Reads four bytes from four consecutive ports, starting at "port",
|
|
* concatenates them little-endian style, and returns them */
|
|
static inline uint32_t inl(port) {
|
|
uint32_t val;
|
|
asm volatile ("inl (%w1), %0"
|
|
: "=a"(val)
|
|
: "d"(port)
|
|
: "memory"
|
|
);
|
|
return val;
|
|
}
|
|
|
|
/* Writes a byte to a port */
|
|
#define outb(data, port) \
|
|
do { \
|
|
asm volatile ("outb %b1, (%w0)" \
|
|
: \
|
|
: "d"(port), "a"(data) \
|
|
: "memory", "cc" \
|
|
); \
|
|
} while (0)
|
|
|
|
/* Writes two bytes to two consecutive ports */
|
|
#define outw(data, port) \
|
|
do { \
|
|
asm volatile ("outw %w1, (%w0)" \
|
|
: \
|
|
: "d"(port), "a"(data) \
|
|
: "memory", "cc" \
|
|
); \
|
|
} while (0)
|
|
|
|
/* Writes four bytes to four consecutive ports */
|
|
#define outl(data, port) \
|
|
do { \
|
|
asm volatile ("outl %1, (%w0)" \
|
|
: \
|
|
: "d"(port), "a"(data) \
|
|
: "memory", "cc" \
|
|
); \
|
|
} while (0)
|
|
|
|
extern uint8_t is_clied;
|
|
|
|
/* Clear interrupt flag - disables interrupts on this processor */
|
|
#define cli() \
|
|
do { \
|
|
asm volatile ("cli" \
|
|
: \
|
|
: \
|
|
: "memory", "cc" \
|
|
); \
|
|
is_clied = 1; \
|
|
} while (0)
|
|
|
|
/* Save flags and then clear interrupt flag
|
|
* Saves the EFLAGS register into the variable "flags", and then
|
|
* disables interrupts on this processor */
|
|
#define cli_and_save(flags) \
|
|
do { \
|
|
asm volatile (" \n\
|
|
pushfl \n\
|
|
popl %0 \n\
|
|
cli \n\
|
|
" \
|
|
: "=r"(flags) \
|
|
: \
|
|
: "memory", "cc" \
|
|
); \
|
|
is_clied = 1; \
|
|
} while (0)
|
|
|
|
/* Set interrupt flag - enable interrupts on this processor */
|
|
#define sti() \
|
|
do { \
|
|
is_clied = 0; \
|
|
asm volatile ("sti" \
|
|
: \
|
|
: \
|
|
: "memory", "cc" \
|
|
); \
|
|
} while (0)
|
|
|
|
// Show if the system is CLIed
|
|
#define iscli() { \
|
|
if(is_clied) { \
|
|
putc('C'); \
|
|
} else { \
|
|
putc('S'); \
|
|
} \
|
|
}
|
|
|
|
/* Restore flags
|
|
* Puts the value in "flags" into the EFLAGS register. Most often used
|
|
* after a cli_and_save_flags(flags) */
|
|
#define restore_flags(flags) \
|
|
do { \
|
|
asm volatile (" \n\
|
|
pushl %0 \n\
|
|
popfl \n\
|
|
" \
|
|
: \
|
|
: "r"(flags) \
|
|
: "memory", "cc" \
|
|
); \
|
|
} while (0)
|
|
|
|
#endif /* _LIB_H */
|