Compare commits

...

3 Commits

22 changed files with 172 additions and 170 deletions

View File

@ -14,6 +14,9 @@ override CFLAGS += \
-pipe \ -pipe \
-Wall \ -Wall \
-Wextra \ -Wextra \
-Wshadow \
-Wstrict-aliasing \
-pedantic \
-std=c99 \ -std=c99 \
-ffreestanding \ -ffreestanding \
-fno-stack-protector \ -fno-stack-protector \

View File

@ -24,7 +24,7 @@
#include <string.h> #include <string.h>
#include <fb.h> #include <fb.h>
// The buffer must be 16-byte aligned as only the upper 28 bits of the address can be passed via the mailbox /* The buffer must be 16-byte aligned as only the upper 28 bits of the address can be passed via the mailbox */
volatile unsigned int __attribute__((aligned(16))) mbox[36]; volatile unsigned int __attribute__((aligned(16))) mbox[36];
unsigned int width, height, pitch, bpp, rgb; unsigned int width, height, pitch, bpp, rgb;
@ -37,17 +37,17 @@ void pixel_draw(int x, int y, int r, int g, int b) {
} }
unsigned int mbox_call(unsigned char ch) { unsigned int mbox_call(unsigned char ch) {
unsigned int m = ((unsigned int)((long) &mbox) &~ 0xF) | (ch & 0xF); // 28-bit address (MSB), 4-bit value (LSB) unsigned int m = ((unsigned int)((long) &mbox) &~ 0xF) | (ch & 0xF); /* 28-bit address (MSB), 4-bit value (LSB) */
while (1) if(!(mmio_read(MBOX_STATUS) & MBOX_FULL)) break; while (1) if(!(mmio_read(MBOX_STATUS) & MBOX_FULL)) break;
mmio_write(MBOX_WRITE, m); mmio_write(MBOX_WRITE, m);
while (1) { while (1) {
while (1) if(!(mmio_read(MBOX_STATUS) & MBOX_EMPTY)) break; // Wait for a reply while (1) if(!(mmio_read(MBOX_STATUS) & MBOX_EMPTY)) break; /* Wait for a reply */
if (m == mmio_read(MBOX_READ)) { // Look for a message on MBOX_READ if (m == mmio_read(MBOX_READ)) { /* Look for a message on MBOX_READ */
if(mbox[1]==MBOX_RESPONSE) return 1; // Success! if(mbox[1]==MBOX_RESPONSE) return 1; /* Success! */
else return 0; else return 0;
} }
} }
@ -66,14 +66,14 @@ void fb_init() {
MBOX_CONFIG = (MBOX_BASE + 0x1C); MBOX_CONFIG = (MBOX_BASE + 0x1C);
MBOX_WRITE = (MBOX_BASE + 0x20); MBOX_WRITE = (MBOX_BASE + 0x20);
mbox[0] = 35 * 4; // Length of message in bytes mbox[0] = 35 * 4; /* Length of message in bytes */
mbox[1] = MBOX_REQUEST; mbox[1] = MBOX_REQUEST;
mbox[2] = MBOX_TAG_SETPHYWH; mbox[2] = MBOX_TAG_SETPHYWH;
mbox[3] = 8; // Value size in bytes mbox[3] = 8; /* Value size in bytes */
mbox[4] = 0; mbox[4] = 0;
mbox[5] = 640; // Width, hardcoded for now mbox[5] = 640; /* Width, hardcoded for now */
mbox[6] = 480; // Height, hardcoded for now mbox[6] = 480; /* Height, hardcoded for now */
mbox[7] = MBOX_TAG_SETVIRTWH; mbox[7] = MBOX_TAG_SETVIRTWH;
mbox[8] = 8; mbox[8] = 8;
@ -84,38 +84,39 @@ void fb_init() {
mbox[12] = MBOX_TAG_SETVIRTOFF; mbox[12] = MBOX_TAG_SETVIRTOFF;
mbox[13] = 8; mbox[13] = 8;
mbox[14] = 8; mbox[14] = 8;
mbox[15] = 0; // X coordinate mbox[15] = 0; /* X coordinate */
mbox[16] = 0; // Y coordinate mbox[16] = 0; /* Y coordinate */
mbox[17] = MBOX_TAG_SETDEPTH; mbox[17] = MBOX_TAG_SETDEPTH;
mbox[18] = 4; mbox[18] = 4;
mbox[19] = 4; mbox[19] = 4;
mbox[20] = 32; // Bits per pixel mbox[20] = 32; /* Bits per pixel */
mbox[21] = MBOX_TAG_SETPXLORDR; mbox[21] = MBOX_TAG_SETPXLORDR;
mbox[22] = 4; mbox[22] = 4;
mbox[23] = 4; mbox[23] = 4;
mbox[24] = 1; // RGB mbox[24] = 1; /* RGB */
mbox[25] = MBOX_TAG_GETFB; mbox[25] = MBOX_TAG_GETFB;
mbox[26] = 8; mbox[26] = 8;
mbox[27] = 8; mbox[27] = 8;
mbox[28] = 4096; // FrameBufferInfo.pointer mbox[28] = 4096; /* FrameBufferInfo.pointer */
mbox[29] = 0; // FrameBufferInfo.size mbox[29] = 0; /* FrameBufferInfo.size */
mbox[30] = MBOX_TAG_GETPITCH; mbox[30] = MBOX_TAG_GETPITCH;
mbox[31] = 4; mbox[31] = 4;
mbox[32] = 4; mbox[32] = 4;
mbox[33] = 0; // Bytes per line mbox[33] = 0; /* Bytes per line */
mbox[34] = MBOX_TAG_LAST; mbox[34] = MBOX_TAG_LAST;
if (mbox_call(MBOX_CH_PROP) && mbox[20] == 32 && mbox[28] != 0) { // Check if mailbox says we're good and that the depth is what we asked for and that it gave us a pointer /* Check if mailbox says we're good and that the depth is what we asked for and that it gave us a pointer */
mbox[28] &= 0x3FFFFFFF; // Convert GPU address to ARM address if (mbox_call(MBOX_CH_PROP) && mbox[20] == 32 && mbox[28] != 0) {
width = mbox[10]; // Actual physical width mbox[28] &= 0x3FFFFFFF; /* Convert GPU address to ARM address */
height = mbox[11]; // Actual physical height width = mbox[10]; /* Actual physical width */
pitch = mbox[33]; // Number of bytes per line height = mbox[11]; /* Actual physical height */
rgb = mbox[24]; // Pixel order pitch = mbox[33]; /* Number of bytes per line */
rgb = mbox[24]; /* Pixel order */
fb = (unsigned char *)((long)mbox[28]); fb = (unsigned char *)((long)mbox[28]);
bpp = pitch / width; bpp = pitch / width;
printf("Initialized framebuffer.\n"); printf("Initialized framebuffer.\n");

View File

@ -36,8 +36,8 @@ fdt_prop fdt_get_prop(uint32_t* addr) {
} }
uint32_t* fdt_get_addr(const char* path) { uint32_t* fdt_get_addr(const char* path) {
const char* fdt_strings = (void*)fdt + SWAP_UINT32(fdt->off_dt_strings); const char* fdt_strings = (char*)fdt + SWAP_UINT32(fdt->off_dt_strings);
uint32_t* fdt_struct = (void*)fdt + SWAP_UINT32(fdt->off_dt_struct); uint32_t* fdt_struct = (uint32_t*)fdt + SWAP_UINT32(fdt->off_dt_struct);
const uint32_t struct_size = SWAP_UINT32(fdt->size_dt_struct); const uint32_t struct_size = SWAP_UINT32(fdt->size_dt_struct);
uint32_t* struct_ptr = fdt_struct; uint32_t* struct_ptr = fdt_struct;
@ -51,59 +51,59 @@ uint32_t* fdt_get_addr(const char* path) {
char* name = strtok(path_copy, "/"); char* name = strtok(path_copy, "/");
while(name && struct_ptr < fdt_struct + struct_size) { while(name && struct_ptr < fdt_struct + struct_size) {
// Read token /* Read token */
const uint32_t token = SWAP_UINT32(*struct_ptr); const uint32_t token = SWAP_UINT32(*struct_ptr);
switch(token) { switch(token) {
// The beginning node is followed immediately by its name /* The beginning node is followed immediately by its name */
case FDT_BEGIN_NODE: case FDT_BEGIN_NODE:
// Advance pointer /* Advance pointer */
struct_ptr++; struct_ptr++;
// check if we are in the token we want /* check if we are in the token we want */
if(!strcmp((char*)struct_ptr, name)) { if(!strcmp((char*)struct_ptr, name)) {
name = strtok(0, "/"); name = strtok(0, "/");
lastaddr = struct_ptr; lastaddr = struct_ptr;
} }
// Calculate the size of the node name /* Calculate the size of the node name */
name_length = strlen((char*)struct_ptr); name_length = strlen((char*)struct_ptr);
// Advance pointer by size of node name aligned to 4 bytes /* Advance pointer by size of node name aligned to 4 bytes */
struct_ptr += name_length / 4; struct_ptr += name_length / 4;
break; break;
// Property /* Property */
case FDT_PROP: case FDT_PROP:
// Advance pointer /* Advance pointer */
prop_length = *++struct_ptr; prop_length = *++struct_ptr;
prop_name_off = *++struct_ptr; prop_name_off = *++struct_ptr;
// check if we are in the token we want /* check if we are in the token we want */
if(!strcmp(fdt_strings + SWAP_UINT32(prop_name_off), name)) { if(!strcmp(fdt_strings + SWAP_UINT32(prop_name_off), name)) {
return struct_ptr-1; return struct_ptr-1;
} }
// Advance pointer /* Advance pointer */
struct_ptr += SWAP_UINT32(prop_length) / 4; struct_ptr += SWAP_UINT32(prop_length) / 4;
break; break;
// End is followed immediately by next token /* End is followed immediately by next token */
case FDT_END_NODE: case FDT_END_NODE:
case FDT_NOP: case FDT_NOP:
break; break;
// There can be only one FDT_END which marks the /* There can be only one FDT_END which marks the
// end of FDT end of FDT */
case FDT_END: case FDT_END:
return 0; return 0;
} }
// Advance pointer /* Advance pointer */
struct_ptr++; struct_ptr++;
} }
return lastaddr; return lastaddr;
} }
void print_fdt() { void print_fdt() {
const char* fdt_strings = (void*)fdt + SWAP_UINT32(fdt->off_dt_strings); const char* fdt_strings = (char*)fdt + SWAP_UINT32(fdt->off_dt_strings);
uint32_t* fdt_struct = (void*)fdt + SWAP_UINT32(fdt->off_dt_struct); uint32_t* fdt_struct = (uint32_t*)fdt + SWAP_UINT32(fdt->off_dt_struct);
const uint32_t struct_size = SWAP_UINT32(fdt->size_dt_struct); const uint32_t struct_size = SWAP_UINT32(fdt->size_dt_struct);
uint32_t* struct_ptr = fdt_struct; uint32_t* struct_ptr = fdt_struct;
@ -115,23 +115,23 @@ void print_fdt() {
uint8_t first_elem = 0; uint8_t first_elem = 0;
while(struct_ptr < fdt_struct + struct_size) { while(struct_ptr < fdt_struct + struct_size) {
// Read token /* Read token */
const uint32_t token = SWAP_UINT32(*struct_ptr); const uint32_t token = SWAP_UINT32(*struct_ptr);
switch(token) { switch(token) {
// The beginning node is followed immediately by its name /* The beginning node is followed immediately by its name */
case FDT_BEGIN_NODE: case FDT_BEGIN_NODE:
// Advance pointer /* Advance pointer */
struct_ptr++; struct_ptr++;
// print tabs /* print tabs */
for(int i = 0; i < tab_count; ++i) uart_puts(" "); for(int i = 0; i < tab_count; ++i) uart_puts(" ");
// increment tab count /* increment tab count */
tab_count++; tab_count++;
// Calculate the size of the node name /* Calculate the size of the node name */
name_length = strlen((char*)struct_ptr); name_length = strlen((char*)struct_ptr);
// Print node name /* Print node name */
if(!name_length) { if(!name_length) {
uart_puts("/:"); uart_puts("/:");
} else { } else {
@ -140,33 +140,33 @@ void print_fdt() {
} }
uart_putc('\n'); uart_putc('\n');
// Advance pointer by size of node name aligned to 4 bytes /* Advance pointer by size of node name aligned to 4 bytes */
struct_ptr += name_length / 4; struct_ptr += name_length / 4;
break; break;
// Property /* Property */
case FDT_PROP: case FDT_PROP:
// Advance pointer /* Advance pointer */
prop_length = *++struct_ptr; prop_length = *++struct_ptr;
prop_name_off = *++struct_ptr; prop_name_off = *++struct_ptr;
// print tabs /* print tabs */
for(int i = 0; i < tab_count+1; ++i) uart_puts(" "); for(int i = 0; i < tab_count+1; ++i) uart_puts(" ");
// Print prop name and value /* Print prop name and value */
uart_puts(fdt_strings + SWAP_UINT32(prop_name_off)); uart_puts(fdt_strings + SWAP_UINT32(prop_name_off));
// Value can be empty /* Value can be empty */
if(prop_length) { if(prop_length) {
uart_puts(": "); uart_puts(": ");
// Dirty hack to see if the value is a string or a number(s) /* Dirty hack to see if the value is a string or a number(s)
// If the first byte of the 4 byte chunk does not fall If the first byte of the 4 byte chunk does not fall
// under acceptable ASCII character values, print its under acceptable ASCII character values, print its
// digits one by one, else just call puts on it since digits one by one, else just call puts on it since
// it is ***probably*** a string. it is ***probably*** a string. */
first_elem = (uint8_t)(SWAP_UINT32(*(struct_ptr+1))); first_elem = (uint8_t)(SWAP_UINT32(*(struct_ptr+1)));
// It is probably a number or an array of numbers /* It is probably a number or an array of numbers
// Divide length of the property by 4 to get Divide length of the property by 4 to get
// the amount of numbers and iterate over them the amount of numbers and iterate over them */
if(first_elem < 0x20 || first_elem > 0x7A || !strcmp("reg", fdt_strings + SWAP_UINT32(prop_name_off))) { if(first_elem < 0x20 || first_elem > 0x7A || !strcmp("reg", fdt_strings + SWAP_UINT32(prop_name_off))) {
for(uint32_t i = 0; i < SWAP_UINT32(prop_length) >> 2; ++i) { for(uint32_t i = 0; i < SWAP_UINT32(prop_length) >> 2; ++i) {
uint32_t hex = SWAP_UINT32(*(struct_ptr + 1 + i)); uint32_t hex = SWAP_UINT32(*(struct_ptr + 1 + i));
@ -175,7 +175,7 @@ void print_fdt() {
uart_putc(' '); uart_putc(' ');
} }
} else { } else {
// Its a good old string /* Its a good old string */
uart_puts((char*)(struct_ptr + 1)); uart_puts((char*)(struct_ptr + 1));
} }
} }
@ -183,18 +183,17 @@ void print_fdt() {
struct_ptr += SWAP_UINT32(prop_length) >> 2; struct_ptr += SWAP_UINT32(prop_length) >> 2;
break; break;
// End is followed immediately by next token /* End is followed immediately by next token */
case FDT_END_NODE: case FDT_END_NODE:
--tab_count; --tab_count;
case FDT_NOP: case FDT_NOP:
break; break;
// There can be only one FDT_END which marks the /* There can be only one FDT_END which marks the end of FDT */
// end of FDT
case FDT_END: case FDT_END:
return; return;
} }
// Advance pointer /* Advance pointer */
struct_ptr++; struct_ptr++;
} }
} }

View File

@ -27,16 +27,16 @@
#include <bits/alltypes.h> #include <bits/alltypes.h>
typedef struct fdt_header { typedef struct fdt_header {
uint32_t magic; // Magic value identifying FDT uint32_t magic; /* Magic value identifying FDT */
uint32_t totalsize; // Total size of FDT including the header uint32_t totalsize; /* Total size of FDT including the header */
uint32_t off_dt_struct; // Offset from beginning of the FDT to the structure block uint32_t off_dt_struct; /* Offset from beginning of the FDT to the structure block */
uint32_t off_dt_strings; // Offset from beginning of the FDT to the strings block uint32_t off_dt_strings; /* Offset from beginning of the FDT to the strings block */
uint32_t off_mem_rsvmap; // Offset from beginning of the FDT to the memory reservation map uint32_t off_mem_rsvmap; /* Offset from beginning of the FDT to the memory reservation map */
uint32_t version; // FDT version uint32_t version; /* FDT version */
uint32_t last_comp_version; // Last compatible version uint32_t last_comp_version; /* Last compatible version */
uint32_t boot_cpuid_phys; // Boot CPU ID uint32_t boot_cpuid_phys; /* Boot CPU ID */
uint32_t size_dt_strings; // Size of the strings block uint32_t size_dt_strings; /* Size of the strings block */
uint32_t size_dt_struct; // Size of the structure block uint32_t size_dt_struct; /* Size of the structure block */
} fdt_header; } fdt_header;
typedef struct fdt_prop { typedef struct fdt_prop {
@ -50,7 +50,7 @@ enum {
FDT_END_NODE = 0x2, FDT_END_NODE = 0x2,
FDT_PROP = 0x3, FDT_PROP = 0x3,
FDT_NOP = 0x4, FDT_NOP = 0x4,
FDT_END = 0x9, FDT_END = 0x9
}; };
fdt_prop fdt_get_prop(uint32_t*); fdt_prop fdt_get_prop(uint32_t*);

View File

@ -24,7 +24,7 @@
#include <uart.h> #include <uart.h>
void uart_init() { void uart_init() {
// Get MMIO, UART and MBOX addresses from FDT /* Get MMIO, UART and MBOX addresses from FDT */
fdt_prop ranges = fdt_get_prop(fdt_get_addr("/soc/ranges")); fdt_prop ranges = fdt_get_prop(fdt_get_addr("/soc/ranges"));
MMIO_BASE = SWAP_UINT32(*ranges.data) - SWAP_UINT32(*(ranges.data+1)); MMIO_BASE = SWAP_UINT32(*ranges.data) - SWAP_UINT32(*(ranges.data+1));
@ -48,41 +48,41 @@ void uart_init() {
UART_IMSC = UART_BASE + 0x38; UART_IMSC = UART_BASE + 0x38;
UART_ICR = UART_BASE + 0x44; UART_ICR = UART_BASE + 0x44;
// Disable UART0. /* Disable UART0. */
mmio_write(UART_CR, 0); mmio_write(UART_CR, 0);
// Setup the GPIO pin 14 && 15. /* Setup the GPIO pin 14 && 15.
// Disable pull up/down for all GPIO pins & delay for 150 cycles. Disable pull up/down for all GPIO pins & delay for 150 cycles. */
mmio_write(GPPUD, 0); mmio_write(GPPUD, 0);
delay(150); delay(150);
// Disable pull up/down for pin 14,15 & delay for 150 cycles. /* Disable pull up/down for pin 14,15 & delay for 150 cycles. */
mmio_write(GPPUDCLK0, (1<<14)|(1<<15)); mmio_write(GPPUDCLK0, (1<<14)|(1<<15));
delay(150); delay(150);
// Write 0 to GPPUDCLK0 to make it take effect. /* Write 0 to GPPUDCLK0 to make it take effect. */
mmio_write(GPPUDCLK0, 0); mmio_write(GPPUDCLK0, 0);
// Clear pending interrupts. /* Clear pending interrupts. */
mmio_write(UART_ICR, 0x7FF); mmio_write(UART_ICR, 0x7FF);
// Set integer & fractional part of baud rate. /* Set integer & fractional part of baud rate.
// Divider = UART_CLOCK/(16 * Baud) Divider = UART_CLOCK/(16 * Baud) */
mmio_write(UART_IBRD, 1); mmio_write(UART_IBRD, 1);
// Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40. /* Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40. */
mmio_write(UART_FBRD, 40); mmio_write(UART_FBRD, 40);
// Enable FIFO & 8 bit data transmission (1 stop bit, no parity). /* Enable FIFO & 8 bit data transmission (1 stop bit, no parity). */
mmio_write(UART_LCRH, (1<<4)|(1<<5)|(1<<6)); mmio_write(UART_LCRH, (1<<4)|(1<<5)|(1<<6));
// Mask all interrupts. /* Mask all interrupts. */
mmio_write(UART_IMSC, (1<<1)|(1<<4)|(1<<5)|(1<<6) mmio_write(UART_IMSC, (1<<1)|(1<<4)|(1<<5)|(1<<6)
|(1<<7)|(1<<8)|(1<<9)|(1<<10)); |(1<<7)|(1<<8)|(1<<9)|(1<<10));
// Enable UART0, receive & transfer part of UART. /* Enable UART0, receive & transfer part of UART. */
mmio_write(UART_CR, 1|(1<<8)|(1<<9)); mmio_write(UART_CR, 1|(1<<8)|(1<<9));
} }
void uart_putc(unsigned char c) { void uart_putc(unsigned char c) {
// Wait for UART to become ready to transmit. /* Wait for UART to become ready to transmit. */
while(mmio_read(UART_FR) & (1<<5)); while(mmio_read(UART_FR) & (1<<5));
mmio_write(UART_DR, c); mmio_write(UART_DR, c);
} }
unsigned char uart_getc() { unsigned char uart_getc() {
// Wait for UART to have received something. /* Wait for UART to have received something. */
while (mmio_read(UART_FR) & (1<<4)); while (mmio_read(UART_FR) & (1<<4));
return mmio_read(UART_DR); return mmio_read(UART_DR);
} }

View File

@ -22,15 +22,15 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
#include <stddef.h> #include <stddef.h>
char* stpcpy(char* restrict, const char* restrict); char* stpcpy(char* restrict, const char*);
char* strcpy(char* restrict, const char* restrict); char* strcpy(char* restrict, const char*);
char* strcat(char* restrict, const char* restrict); char* strcat(char* restrict, const char*);
char* strtok(char* restrict, const char* restrict); char* strtok(char* restrict, const char*);
int strcmp(const char* restrict, const char* restrict); int strcmp(const char* restrict, const char*);
char* strchr(const char* restrict, int c); char* strchr(const char* restrict, int c);
int memcmp(const void*, const void*, size_t); int memcmp(const void*, const void*, size_t);
void* memcpy(void* restrict, const void* restrict, size_t); void* memcpy(void* restrict, const void*, size_t);
void* memmove(void*, const void*, size_t); void* memmove(void*, const void*, size_t);
void* memset(void*, int, size_t); void* memset(void*, int, size_t);
size_t strlen(const char*); size_t strlen(const char*);

View File

@ -50,7 +50,7 @@ int printf(const char* restrict format, ...) {
amount++; amount++;
} }
if (maxrem < amount) { if (maxrem < amount) {
// EOVERFLOW. /* EOVERFLOW */
return -1; return -1;
} }
if (!print(format, amount)) { if (!print(format, amount)) {
@ -71,7 +71,7 @@ int printf(const char* restrict format, ...) {
format++; format++;
char c = (char)va_arg(params, int); char c = (char)va_arg(params, int);
if (!maxrem) { if (!maxrem) {
// EOVERFLOW /* EOVERFLOW */
return -1; return -1;
} }
if (!print(&c, sizeof(c))) { if (!print(&c, sizeof(c))) {
@ -85,7 +85,7 @@ int printf(const char* restrict format, ...) {
const char* str = va_arg(params, const char*); const char* str = va_arg(params, const char*);
len = strlen(str); len = strlen(str);
if (maxrem < len) { if (maxrem < len) {
// TODO: EOVERFLOW /* TODO: EOVERFLOW */
return -1; return -1;
} }
if (!print(str, len)) { if (!print(str, len)) {
@ -100,7 +100,7 @@ int printf(const char* restrict format, ...) {
itoa(num, buf, 10); itoa(num, buf, 10);
len = strlen(buf); len = strlen(buf);
if(maxrem < len) { if(maxrem < len) {
// EOVERFLOW /* EOVERFLOW */
return -1; return -1;
} }
if(!print(buf, len)) { if(!print(buf, len)) {
@ -115,7 +115,7 @@ int printf(const char* restrict format, ...) {
uitoa(unum, buf, 16); uitoa(unum, buf, 16);
len = strlen(buf); len = strlen(buf);
if(maxrem < len) { if(maxrem < len) {
// EOVERFLOW /* EOVERFLOW */
return -1; return -1;
} }
if(!print(buf, len)) { if(!print(buf, len)) {
@ -128,7 +128,7 @@ int printf(const char* restrict format, ...) {
format = format_begun_at; format = format_begun_at;
len = strlen(format); len = strlen(format);
if (maxrem < len) { if (maxrem < len) {
// EOVERFLOW /* EOVERFLOW */
return -1; return -1;
} }
if (!print(format, len)) { if (!print(format, len)) {

View File

@ -23,25 +23,25 @@
#if _ARCH_AARCH64 #if _ARCH_AARCH64
#include <uart.h> #include <uart.h>
#else #else
// TODO: other arch implementation /* TODO: AMD64 implementation */
#endif #endif
#else #else
// TODO: Userspace implementation /* TODO: Userspace implementation */
#endif #endif
int putchar(int ic) { int putchar(int ic) {
// aarch64 print function /* aarch64 print function */
#ifdef _IS_YUKARI #ifdef _IS_YUKARI
#if _ARCH_AARCH64 #if _ARCH_AARCH64
uart_putc((char)ic); uart_putc((char)ic);
#else #else
// TODO: other arch implementation /* TODO: AMD64 implementation */
#endif #endif
#else #else
// TODO: Userspace implementation /* TODO: Userspace implementation */
#endif #endif
return ic; return ic;

View File

@ -19,7 +19,7 @@
#ifdef _IS_YUKARI #ifdef _IS_YUKARI
#include <hal.h> #include <hal.h>
#else #else
// TODO: Userspace abort implementation /* TODO: Userspace abort implementation */
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -29,7 +29,7 @@ void abort() {
printf("kernel panic!!\n"); printf("kernel panic!!\n");
hcf(); hcf();
#else #else
// TODO: Abnormally terminate the process as if by SIGABRT. /* TODO: Abnormally terminate the process as if by SIGABRT. */
printf("abort!!\n"); printf("abort!!\n");
#endif #endif
for(;;); for(;;);

View File

@ -30,14 +30,14 @@ char* itoa(int value, char* buffer, int base) {
uint8_t negative = 0; uint8_t negative = 0;
uint8_t digit = 0; uint8_t digit = 0;
// Handle negative numbers /* Handle negative numbers */
if (value < 0) { if (value < 0) {
negative = 1; negative = 1;
value = abs(value); value = abs(value);
} }
// Put base remainder of value into the buffer /* Put base remainder of value into the buffer
// while dividing value by base while dividing value by base */
do { do {
digit = value % base; digit = value % base;
buffer[index] = digits[digit]; buffer[index] = digits[digit];
@ -45,14 +45,14 @@ char* itoa(int value, char* buffer, int base) {
value /= base; value /= base;
} while (value); } while (value);
// Put negative character in the end /* Put negative character in the end */
if(negative) { if(negative) {
buffer[index++] = '-'; buffer[index++] = '-';
} }
// Null terminate /* Null terminate */
buffer[index] = 0; buffer[index] = 0;
// Reverse the buffer /* Reverse the buffer */
uint8_t len = index; uint8_t len = index;
char temp = 0; char temp = 0;
for(uint8_t i = 0; i < len >> 1; ++i) { for(uint8_t i = 0; i < len >> 1; ++i) {

View File

@ -28,8 +28,8 @@ char* uitoa(uint32_t value, char* buffer, int base) {
uint8_t index = 0; uint8_t index = 0;
uint8_t digit = 0; uint8_t digit = 0;
// Put base remainder of value into the buffer /* Put base remainder of value into the buffer
// while dividing value by base while dividing value by base */
do { do {
digit = value % base; digit = value % base;
buffer[index] = digits[digit]; buffer[index] = digits[digit];
@ -37,10 +37,10 @@ char* uitoa(uint32_t value, char* buffer, int base) {
value /= base; value /= base;
} while (value); } while (value);
// Null terminate /* Null terminate */
buffer[index] = 0; buffer[index] = 0;
// Reverse the buffer /* Reverse the buffer */
uint8_t len = index; uint8_t len = index;
char temp = 0; char temp = 0;
for(uint8_t i = 0; i < len >> 1; ++i) { for(uint8_t i = 0; i < len >> 1; ++i) {

View File

@ -18,7 +18,7 @@
#include <string.h> #include <string.h>
void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) { void* memcpy(void* restrict dstptr, const void* srcptr, size_t size) {
unsigned char* dst = (unsigned char*) dstptr; unsigned char* dst = (unsigned char*) dstptr;
const unsigned char* src = (const unsigned char*) srcptr; const unsigned char* src = (const unsigned char*) srcptr;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {

View File

@ -20,7 +20,7 @@
#include <stdint.h> #include <stdint.h>
#include <limits.h> #include <limits.h>
char* stpcpy(char* restrict d, const char* restrict s){ char* stpcpy(char* restrict d, const char* s){
for(;(*d=*s); s++, d++); for(;(*d=*s); s++, d++);
return d; return d;
} }

View File

@ -18,7 +18,7 @@
#include <string.h> #include <string.h>
char* strcat(char* restrict dest, const char* restrict src) { char* strcat(char* restrict dest, const char* src) {
strcpy(dest + strlen(dest), src); strcpy(dest + strlen(dest), src);
return dest; return dest;
} }

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
int strcmp(const char* restrict str1, const char* restrict str2) { int strcmp(const char* restrict str1, const char* str2) {
while(*str1 || *str2) { while(*str1 || *str2) {
if(*str1 != *str2) return *str1 - *str2; if(*str1 != *str2) return *str1 - *str2;
str1++; str1++;

View File

@ -18,7 +18,7 @@
#include <string.h> #include <string.h>
char* strcpy(char* restrict dest, const char* restrict src) { char* strcpy(char* restrict dest, const char* src) {
stpcpy(dest, src); stpcpy(dest, src);
return dest; return dest;
} }

View File

@ -18,7 +18,7 @@
#include <string.h> #include <string.h>
char* strtok(char* restrict str, const char* restrict delim) { char* strtok(char* restrict str, const char* delim) {
static char* lastToken = 0; static char* lastToken = 0;
if(str) { if(str) {

View File

@ -18,17 +18,16 @@
#include <shinobu.h> #include <shinobu.h>
EFI_FILE_PROTOCOL* EFIAPI EFI_FILE_PROTOCOL* EFIAPI
OpenFile(CHAR16 *path) { OpenFile(CHAR16 *path) {
EFI_STATUS status; EFI_STATUS status;
// Locate handle supporting SFSP /* Locate handle supporting SFSP */
EFI_HANDLE *handles; EFI_HANDLE *handles;
UINTN handleCnt; UINTN handleCnt;
EFI_GUID sfspGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_GUID sfspGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
status = uefi_call_wrapper(BS->LocateHandleBuffer, 5, status = uefi_call_wrapper(*(void**)&BS->LocateHandleBuffer, 5,
ByProtocol, ByProtocol,
&sfspGuid, &sfspGuid,
NULL, NULL,
@ -37,27 +36,27 @@ OpenFile(CHAR16 *path) {
); );
PRINT_ERR(status); PRINT_ERR(status);
// TODO: Might need to iterate on all handles if /* TODO: Might need to iterate on all handles if
// multiple FAT32 images are connected multiple FAT32 images are connected
// Open Filesystem Open Filesystem */
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fs = NULL; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fs = NULL;
status = uefi_call_wrapper(BS->HandleProtocol, 3, status = uefi_call_wrapper(*(void**)&BS->HandleProtocol, 3,
handles[0], handles[0],
&sfspGuid, &sfspGuid,
(VOID**)&fs (VOID**)&fs
); );
PRINT_ERR(status); PRINT_ERR(status);
// Open ROOTDIR /* Open ROOTDIR */
EFI_FILE_PROTOCOL *root = NULL; EFI_FILE_PROTOCOL *root = NULL;
status = uefi_call_wrapper(fs->OpenVolume, 2, status = uefi_call_wrapper(*(void**)&fs->OpenVolume, 2,
fs, fs,
&root &root
); );
PRINT_ERR(status); PRINT_ERR(status);
// Open file /* Open file */
status = uefi_call_wrapper(root->Open, 5, status = uefi_call_wrapper(*(void**)&root->Open, 5,
root, root,
&root, &root,
path, path,
@ -71,15 +70,15 @@ OpenFile(CHAR16 *path) {
EFI_STATUS EFIAPI EFI_STATUS EFIAPI
SetPos(EFI_FILE_PROTOCOL *file, UINTN pos) { SetPos(EFI_FILE_PROTOCOL *file, UINTN pos) {
return uefi_call_wrapper(file->SetPosition, 2, file, pos); return uefi_call_wrapper(*(void**)&file->SetPosition, 2, file, pos);
} }
EFI_STATUS EFIAPI EFI_STATUS EFIAPI
Read(EFI_FILE_PROTOCOL *file, UINTN *size, VOID *dest) { Read(EFI_FILE_PROTOCOL *file, UINTN *size, VOID *dest) {
return uefi_call_wrapper(file->Read, 3, file, size, dest); return uefi_call_wrapper(*(void**)&file->Read, 3, file, size, dest);
} }
EFI_STATUS EFIAPI EFI_STATUS EFIAPI
Close(EFI_FILE_PROTOCOL *file) { Close(EFI_FILE_PROTOCOL *file) {
return uefi_call_wrapper(file->Close, 1, file); return uefi_call_wrapper(*(void**)&file->Close, 1, file);
} }

View File

@ -45,7 +45,7 @@ EFI_STATUS EFIAPI SetPos(EFI_FILE_PROTOCOL*, UINTN);
EFI_STATUS EFIAPI Read(EFI_FILE_PROTOCOL*, UINTN*, VOID*); EFI_STATUS EFIAPI Read(EFI_FILE_PROTOCOL*, UINTN*, VOID*);
EFI_STATUS EFIAPI Close(EFI_FILE_PROTOCOL*); EFI_STATUS EFIAPI Close(EFI_FILE_PROTOCOL*);
// elf.h /* elf.h */
#define EI_NIDENT (16) #define EI_NIDENT (16)
typedef uint16_t Elf64_Half; typedef uint16_t Elf64_Half;
typedef uint32_t Elf64_Word; typedef uint32_t Elf64_Word;

View File

@ -20,16 +20,16 @@
EFI_STATUS EFIAPI EFI_STATUS EFIAPI
SetMemoryMap(UEFIMemoryMap *map) { SetMemoryMap(UEFIMemoryMap *map) {
// Set a size for memory map /* Set a size for memory map */
EFI_STATUS status; EFI_STATUS status;
map->memoryMapSize = sizeof(EFI_MEMORY_DESCRIPTOR) * 64; map->memoryMapSize = sizeof(EFI_MEMORY_DESCRIPTOR) * 64;
// Loop until we correctly get a memory map or come across /* Loop until we correctly get a memory map or come across
// an error an error */
for(;;) { for(;;) {
// Try allocating and getting memory map /* Try allocating and getting memory map */
map->memoryMap = AllocatePool(map->memoryMapSize); map->memoryMap = AllocatePool(map->memoryMapSize);
status = uefi_call_wrapper(BS->GetMemoryMap, 5, status = uefi_call_wrapper(*(void**)&BS->GetMemoryMap, 5,
&map->memoryMapSize, &map->memoryMapSize,
map->memoryMap, map->memoryMap,
&map->mapKey, &map->mapKey,
@ -37,8 +37,8 @@ SetMemoryMap(UEFIMemoryMap *map) {
&map->descriptorVersion &map->descriptorVersion
); );
// If allocated buffer is too small, free buffer and /* If allocated buffer is too small, free buffer and
// increase its size increase its size */
if (status == EFI_BUFFER_TOO_SMALL) { if (status == EFI_BUFFER_TOO_SMALL) {
FreePool(map->memoryMap); FreePool(map->memoryMap);
map->memoryMapSize += sizeof(EFI_MEMORY_DESCRIPTOR) * 16; map->memoryMapSize += sizeof(EFI_MEMORY_DESCRIPTOR) * 16;

View File

@ -22,21 +22,21 @@ EFI_STATUS EFIAPI
efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
EFI_STATUS status; EFI_STATUS status;
// Initialize UEFI library /* Initialize UEFI library */
InitializeLib(ImageHandle, SystemTable); InitializeLib(ImageHandle, SystemTable);
// Store SystemTable and BootServices /* Store SystemTable and BootServices */
ST = SystemTable; ST = SystemTable;
BS = ST->BootServices; BS = ST->BootServices;
// Clear Screen /* Clear Screen */
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); uefi_call_wrapper(*(void**)&ST->ConOut->ClearScreen, 1, ST->ConOut);
Print(L"Shinobu Bootloader Alpha\n"); Print(L"Shinobu Bootloader Alpha\n");
// Open ELF64 Kernel /* Open ELF64 Kernel */
EFI_FILE_PROTOCOL *kernelFile = OpenFile(L"yukari"); EFI_FILE_PROTOCOL *kernelFile = OpenFile(L"yukari");
// Read ELF Header /* Read ELF Header */
UINTN EHeaderSize = sizeof(Elf64_Ehdr); UINTN EHeaderSize = sizeof(Elf64_Ehdr);
Elf64_Ehdr *kernelElfHeader = AllocatePool(EHeaderSize); Elf64_Ehdr *kernelElfHeader = AllocatePool(EHeaderSize);
@ -45,7 +45,7 @@ efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
PRINT_ERR(status); PRINT_ERR(status);
Print(L"ELF Header Loc: 0x%x\n", kernelElfHeader); Print(L"ELF Header Loc: 0x%x\n", kernelElfHeader);
// Read ELF Prog Header /* Read ELF Prog Header */
UINTN PHeaderSize = kernelElfHeader->e_phnum * kernelElfHeader->e_phentsize; UINTN PHeaderSize = kernelElfHeader->e_phnum * kernelElfHeader->e_phentsize;
Elf64_Phdr* kernelProgHeader = AllocatePool(PHeaderSize); Elf64_Phdr* kernelProgHeader = AllocatePool(PHeaderSize);
@ -54,22 +54,22 @@ efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
PRINT_ERR(status); PRINT_ERR(status);
Print(L"ELF Prog Header Loc: 0x%x\n", kernelProgHeader); Print(L"ELF Prog Header Loc: 0x%x\n", kernelProgHeader);
// Load Program Segments /* Load Program Segments */
for(UINT16 i = 0; i < kernelElfHeader->e_phnum; ++i) { for(UINT16 i = 0; i < kernelElfHeader->e_phnum; ++i) {
if(kernelProgHeader[i].p_type == 1) { if(kernelProgHeader[i].p_type == 1) {
// Get count of pages needed /* Get count of pages needed */
int pages = (kernelProgHeader[i].p_memsz + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE; int pages = (kernelProgHeader[i].p_memsz + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE;
// Get segment address /* Get segment address */
Elf64_Addr segment = kernelProgHeader[i].p_paddr; Elf64_Addr segment = kernelProgHeader[i].p_paddr;
// Allocate pages to the segment address /* Allocate pages to the segment address */
status = uefi_call_wrapper(BS->AllocatePages, 4, status = uefi_call_wrapper(*(void**)&BS->AllocatePages, 4,
AllocateAddress, AllocateAddress,
EfiLoaderData, EfiLoaderData,
pages, pages,
&segment &segment
); );
PRINT_ERR(status); PRINT_ERR(status);
// Write program segment to the allocated address /* Write program segment to the allocated address */
UINTN fileSize = kernelProgHeader[i].p_filesz; UINTN fileSize = kernelProgHeader[i].p_filesz;
SetPos(kernelFile, kernelProgHeader[i].p_offset); SetPos(kernelFile, kernelProgHeader[i].p_offset);
status = Read(kernelFile, &fileSize, (VOID*)segment); status = Read(kernelFile, &fileSize, (VOID*)segment);
@ -78,21 +78,21 @@ efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
} }
Print(L"Finished reading kernel\nKernel Entry: 0x%x\n", kernelElfHeader->e_entry); Print(L"Finished reading kernel\nKernel Entry: 0x%x\n", kernelElfHeader->e_entry);
// Close the kernel file /* Close the kernel file */
Close(kernelFile); Close(kernelFile);
// Set Memory Map and exit boot services /* Set Memory Map and exit boot services */
UEFIMemoryMap map; UEFIMemoryMap map;
status = SetMemoryMap(&map); status = SetMemoryMap(&map);
uefi_call_wrapper(BS->ExitBootServices, 2, uefi_call_wrapper(*(void**)&BS->ExitBootServices, 2,
ImageHandle, ImageHandle,
map.mapKey map.mapKey
); );
// Jump to kernel /* Jump to kernel */
VOID (*_start)(VOID) = (VOID (*)(VOID))kernelElfHeader->e_entry; VOID (*_start)(VOID) = (VOID (*)(VOID))kernelElfHeader->e_entry;
_start(); _start();
// Should be unreachable /* Should be unreachable */
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
} }

View File

@ -23,7 +23,7 @@
#include <fb.h> #include <fb.h>
#else #else
//
#endif #endif
#include <hal.h> #include <hal.h>