Skip to content

Commit

Permalink
Added some utilities.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Oct 31, 2022
1 parent 226b2f6 commit b49ce78
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 35 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct HandoverRecord
uint64_t start;
uint64_t size;
uint64_t more;
} ;
};
```

# Machine State
Expand Down Expand Up @@ -112,4 +112,4 @@ End marker

# Definitions

- **C** - [handover.h](includes/handover.h)
- **C** - [handover.h](handover.h)
2 changes: 1 addition & 1 deletion exemple/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ LDFLAGS ?=
# Internal C flags that should not be changed by the user.
override INTERNALCFLAGS := \
-I. \
-I../includes \
-I.. \
-std=gnu11 \
-ffreestanding \
-fno-stack-protector \
Expand Down
158 changes: 158 additions & 0 deletions handover.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#define HANDOVER_INCLUDE_UTILITES

#include "handover.h"

char const *handover_tag_name(HandoverTag tag)
{
switch (tag)
{
#define TAG(NAME, VALUE) \
case HANDOVER_##NAME: \
return #NAME;
HANDOVER_TAGS(TAG)
#undef TAG
}
return "UNKNOWN";
}

bool handover_mergeable(uint32_t tag)
{
switch (tag)
{
case HANDOVER_FREE:
case HANDOVER_LOADER:
case HANDOVER_KERNEL:
case HANDOVER_RESERVED:
return true;

default:
return false;
}
}

bool handover_overlap(HandoverRecord lhs, HandoverRecord rhs)
{
return lhs.start < rhs.start + rhs.size && rhs.start < lhs.start + lhs.size;
}

bool handover_just_before(HandoverRecord lhs, HandoverRecord rhs)
{
return lhs.start + lhs.size == rhs.start;
}

bool handover_just_after(HandoverRecord lhs, HandoverRecord rhs)
{
return lhs.start == rhs.start + rhs.size;
}

HandoverRecord handover_half_under(HandoverRecord self, HandoverRecord other)
{
if (handover_overlap(self, other) &&
self.start < other.start)
{
return {
.tag = self.tag,
.flags = 0,
.start = self.start,
.size = other.start - self.start,
};
}

return {};
}

HandoverRecord handover_half_over(HandoverRecord self, HandoverRecord other)
{
if (handover_overlap(self, other) &&
self.start + self.size > other.start + other.size)
{
return {
.tag = self.tag,
.flags = 0,
.start = other.start + other.size,
.size = self.start + self.size - other.start - other.size,
};
}

return {};
}

void handover_insert(HandoverPayload *payload, size_t index, HandoverRecord record)
{
for (size_t i = payload->count; i > index; i--)
{
payload->records[i] = payload->records[i - 1];
}

payload->records[index] = record;
payload->count++;
}

void handover_remove(HandoverPayload *payload, size_t index)
{
for (size_t i = index; i < payload->count - 1; i++)
{
payload->records[i] = payload->records[i + 1];
}

payload->count--;
}

void handover_append(HandoverPayload *payload, HandoverRecord record)
{
if (record.size == 0)
return;

for (size_t i = 0; i < payload->count; i++)
{
HandoverRecord *other = &payload->records[i];

if (record.tag == other->tag &&
handover_just_after(record, *other) &&
handover_mergeable(record.tag))
{
other->size += record.size;
return;
}

if (record.tag == other->tag &&
handover_just_before(record, *other) &&
handover_mergeable(record.tag))
{
other->start -= record.size;
other->size += record.size;
return;
}

if (handover_overlap(record, *other))
{
if (!handover_mergeable(record.tag))
{
HandoverRecord tmp = record;
record = *other;
*other = tmp;
}

HandoverRecord half_under = handover_half_under(record, *other);
HandoverRecord half_over = handover_half_over(record, *other);

handover_remove(payload, i);

if (half_under.size)
handover_insert(payload, i, half_under);

if (half_over.size)
handover_insert(payload, i, half_over);

return;
}

if (record.start < other->start)
{
handover_insert(payload, i, record);
return;
}
}

payload->records[payload->count++] = record;
}
86 changes: 54 additions & 32 deletions includes/handover.h → handover.h
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
#ifndef HANDOVER_H_INCLUDED
#define HANDOVER_H_INCLUDED

#include <stddef.h>
#include <stdint.h>

#define HANDOVER_KERNEL_BASE = 0xffffffff80000000;
#define HANDOVER_UPPER_HALF = 0xffff800000000000;
#define HANDOVER_KERNEL_BASE 0xffffffff80000000
#define HANDOVER_UPPER_HALF 0xffff800000000000

#define HANDOVER_COOLBOOT 0xc001b001
#define HANDOVER_SECTION ".handover"

#define HANDOVER_FOREACH_TAGS(TAG) \
TAG(FREE, 0x00000000) \
TAG(MAGIC, HANDOVER_COOLBOOT) \
TAG(SELF, 0xa24f988d) \
TAG(STACK, 0xf65b391b) \
TAG(KERNEL, 0xbfc71b20) \
TAG(LOADER, 0xf1f80c26) \
TAG(FILE, 0xcbc36d3b) \
TAG(RSDP, 0x8ef29c18) \
TAG(FDT, 0xb628bbc1) \
TAG(FB, 0xe2d55685) \
TAG(CMDLINE, 0x435140c4) \
#define HANDOVER_TAGS(TAG) \
TAG(FREE, 0x00000000) \
TAG(MAGIC, HANDOVER_COOLBOOT) \
TAG(SELF, 0xa24f988d) \
TAG(STACK, 0xf65b391b) \
TAG(KERNEL, 0xbfc71b20) \
TAG(LOADER, 0xf1f80c26) \
TAG(FILE, 0xcbc36d3b) \
TAG(RSDP, 0x8ef29c18) \
TAG(FDT, 0xb628bbc1) \
TAG(FB, 0xe2d55685) \
TAG(CMDLINE, 0x435140c4) \
TAG(RESERVED, 0xb8841d2d) \
TAG(END, 0xffffffff)

typedef enum
{
#define TAG(NAME, VALUE) HANDOVER_##NAME = VALUE,
HANDOVER_FOREACH_TAGS(TAG)
HANDOVER_TAGS(TAG)
#undef TAG
} HandoverTag;

Expand All @@ -36,14 +38,27 @@ typedef struct
uint32_t flags;
uint64_t start;
uint64_t size;

union
{
uint64_t more;
struct
{
uint32_t car;
uint32_t cdr;
};
uint16_t width;
uint16_t height;
uint16_t pitch;

#define HANDOVER_RGBX8888 0x7451
#define HANDOVER_BGRX8888 0xd040
uint16_t format;
} fb;

struct
{
uint32_t name;
uint32_t meta;
} file;

uint64_t more;
};
} HandoverRecord;

Expand All @@ -67,6 +82,7 @@ typedef void HandoverEntry(
/* --- Header Utilities ----------------------------------------------------- */

#ifdef HANDOVER_INCLUDE_MACROS

# define HANDOVER_REQ_START \
{ \
.tag = HANDOVER_MAGIC \
Expand Down Expand Up @@ -102,7 +118,6 @@ typedef void HandoverEntry(
.tag = HANDOVER_CMDLINE \
}


# define HANDOVER(...) \
__attribute__((section(HANDOVER_SECTION), \
used)) static HandoverRequest handover_header[] = { \
Expand All @@ -116,18 +131,25 @@ typedef void HandoverEntry(

#ifdef HANDOVER_INCLUDE_UTILITES

static inline char const *handover_tag_name(HandoverTag tag)
{
switch (tag)
{
# define TAG(NAME, VALUE) \
case HANDOVER_##NAME: \
return #NAME;
HANDOVER_FOREACH_TAGS(TAG)
# undef TAG
}
return "UNKNOWN";
}
char const *handover_tag_name(HandoverTag tag);

bool handover_mergeable(uint32_t tag);

bool handover_overlap(HandoverRecord lhs, HandoverRecord rhs);

bool handover_just_before(HandoverRecord lhs, HandoverRecord rhs);

bool handover_just_after(HandoverRecord lhs, HandoverRecord rhs);

HandoverRecord handover_half_under(HandoverRecord self, HandoverRecord other);

HandoverRecord handover_half_over(HandoverRecord self, HandoverRecord other);

void handover_insert(HandoverPayload *payload, size_t index, HandoverRecord record);

void handover_remove(HandoverPayload *payload, size_t index);

void handover_append(HandoverPayload *payload, HandoverRecord record);

#endif

Expand Down
5 changes: 5 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "handover",
"type": "lib",
"description": "A simple and extensible boot protocol"
}

0 comments on commit b49ce78

Please sign in to comment.