Skip to content
Open
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ports/x86/build/*
*.swp
*.o
tags
*.iso
123 changes: 123 additions & 0 deletions ports/x86/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
############
# Settings #
############

# Build all test applications:
# make
#
# Run all tests communicating via UART
# make tests

# Location of build tools and atomthreads sources
KERNEL_DIR=../../kernel
TESTS_DIR=../../tests
PORT_DIR=.
CC=i686-elf-gcc
OBJCOPY=i686-elf-objcopy
ARCHIVE=i686-elf-ar

# Folder delete command (OS-specific)
ifeq ($(OS),Windows_NT)
RMDIR=rd /s /q
else
RMDIR=rm -rf
endif

# Enable stack-checking.
#STACK_CHECK=true

# Directory for built objects
BUILD_DIR=build
PLAT_DIR=plat
PORT_UTIL_DIR=utils
# Platform-specific object files
PLAT_OBJECTS = irq_handlers.o pic.o pit.o terminal.o

# Port-specific object files
PORT_OBJECTS = atomport.o c_traps.o main.o gdt.o
PORT_ASM_OBJECTS = atomport-asm.o boot.o traps.o
PORT_UTIL_OBJECTS = string.o printf.o

# Kernel object files
KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o

# Collection of built objects (excluding test applications)
ALL_OBJECTS = $(PLAT_OBJECTS) $(PLAT_ASM_OBJECTS) $(PORT_OBJECTS) $(PORT_ASM_OBJECTS) $(PORT_UTIL_OBJECTS) $(KERNEL_OBJECTS)
BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS))

# Test object files (dealt with separately as only one per application build)
TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c)))
TEST_ALL = $(patsubst %.o,%,$(TEST_OBJECTS))

# Search build/output directory for dependencies
vpath %.o ./$(BUILD_DIR)

# GCC flags
CFLAGS=-c -s -ffreestanding -std=gnu99 -Wall -Wextra -Werror \
-Wno-unused-parameter \
-Wno-unused-but-set-variable \
-Wno-unused-variable \
-Wno-sign-compare
#-O2

AFLAGS=$(CFLAGS) -x assembler-with-cpp
LFLAGS=-Tlinker.ld -Wall -ffreestanding -nostdlib

# Enable stack-checking options (disable if not required)
ifeq ($(STACK_CHECK),true)
CFLAGS += -DATOM_STACK_CHECKING
endif
ifeq ($(TESTS_LOG_STACK),true)
CFLAGS += -DTESTS_LOG_STACK_USAGE -I$(PORT_UTIL_DIR)
endif


#################
# Build targets #
#################

main: $(BUILD_DIR) $(TEST_ALL)

$(TEST_ALL): $(TEST_OBJECTS) $(BUILD_DIR) $(ALL_OBJECTS)
$(CC) $(LFLAGS) $(BUILT_OBJECTS) $(BUILD_DIR)/$(notdir $@.o) --output $(BUILD_DIR)/$@.bin

# Build archive for linking with external application
libatomthreads.a: $(BUILD_DIR) $(ALL_OBJECTS) Makefile
$(ARCHIVE) cr $(BUILD_DIR)/$@ $(BUILT_OBJECTS)

# Make build/output directory
$(BUILD_DIR):
mkdir $(BUILD_DIR)

# Kernel objects builder
$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c
$(CC) -c $(CFLAGS) -I. -I$(PORT_DIR) $< -o $(BUILD_DIR)/$(notdir $@)

# Test objects builder
$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c
$(CC) -c $(CFLAGS) -I. -I$(PORT_DIR) -I$(PORT_UTIL_DIR) -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@)

# Platform C objects builder
$(PLAT_OBJECTS): %.o: $(PLAT_DIR)/%.c
$(CC) -c $(CFLAGS) -I. -I$(PORT_DIR) -I$(KERNEL_DIR) -I$(PORT_UTIL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@)

# Platform asm objects builder
$(PLAT_ASM_OBJECTS): %.o: $(PLAT_DIR)/%.s
$(CC) -c $(AFLAGS) -I. -I$(PORT_DIR) -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@)

# Port C objects builder
$(PORT_OBJECTS): %.o: $(PORT_DIR)/%.c
$(CC) -c $(CFLAGS) -I. -Imachine/ -I$(PORT_DIR) -I$(KERNEL_DIR) -I$(PORT_UTIL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@)

# Port asm objects builder
$(PORT_ASM_OBJECTS): %.o: $(PORT_DIR)/%.s
$(CC) -c $(AFLAGS) -I. -I$(PORT_DIR) -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@)

# Port C objects builder
$(PORT_UTIL_OBJECTS): %.o: $(PORT_UTIL_DIR)/%.c
$(CC) -c $(CFLAGS) -I../ -I$(PORT_DIR) -I$(KERNEL_DIR) -I$(PORT_UTIL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@)

# Clean
clean:
$(RMDIR) build/*

45 changes: 45 additions & 0 deletions ports/x86/atomport-asm.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* AtomThreads project - Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Please refer to the README file for further details and License information.
*
* x86 port by: ido@mm.st
*/

.section .text

.global archContextSwitch
.type archContextSwitch, @function
archContextSwitch:
pushl %ebp
movl %esp,%ebp

pushf
pusha

movl 8(%ebp),%eax
movl 12(%ebp),%ebx

movl %esp,(%eax)
movl (%ebx),%esp

popa
popf

popl %ebp

sti
ret

.global archFirstThreadRestore
.type archFirstThreadRestore, @function
archFirstThreadRestore:
movl 4(%esp),%eax
movl (%eax),%esp

addl $32,%esp
popf
popl %ebp
sti
ret

36 changes: 36 additions & 0 deletions ports/x86/atomport-tests.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* AtomThreads project - Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Please refer to the README file for further details and License information.
*
* x86 port by: ido@mm.st
*/

#ifndef __ATOM_PORT_TESTS_H
#define __ATOM_PORT_TESTS_H

/* Include Atomthreads kernel API */
#include "atom.h"
#include "plat.h"
#include "print.h"

/* Logger macro for viewing test results */

#define ATOMLOG kprintf
/*
* String location macro: for platforms which need to place strings in
* alternative locations, e.g. on avr-gcc strings can be placed in
* program space, saving SRAM. On most platforms this can expand to
* empty.
*/
#define _STR(x) x

/* Default thread stack size (in bytes). Allow plenty for printf(). */
#define TEST_THREAD_STACK_SIZE 1024*16 // 16K

/* Uncomment to enable logging of stack usage to UART */
/* #define TESTS_LOG_STACK_USAGE */


#endif /* __ATOM_PORT_TESTS_H */

50 changes: 50 additions & 0 deletions ports/x86/atomport.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* AtomThreads project - Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Please refer to the README file for further details and License information.
*
* x86 port by: ido@mm.st
*/

#include "atom.h"
#include "atomport.h"
#include "x86.h"
#include "plat.h"

static void thread_init(uint32_t entry_param)
{
ATOM_TCB* tcb;
entry_param = entry_param;

tcb = atomCurrentContext();

x86_enable_int();
if( tcb && tcb->entry_point)
tcb->entry_point(tcb->entry_param);

tcb->terminated = TRUE;
atomSched(TRUE);
}

void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(uint32_t), uint32_t entry_param)
{
uint32_t *stack_ptr = stack_top;

*--stack_ptr = (uint32_t) thread_init;

stack_ptr -= 9;
(uint16_t*) stack_ptr--;

tcb_ptr->sp_save_ptr = stack_ptr;
}

inline uint32_t contextEnterCritical (void){
uint32_t flags = x86_get_eflags();
x86_disable_int();

return flags;
}

inline void contextExitCritical(uint32_t flags) {
x86_set_eflags(flags);
}
39 changes: 39 additions & 0 deletions ports/x86/atomport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* AtomThreads project - Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Please refer to the README file for further details and License information.
*
* x86 port by: ido@mm.st
*/

#ifndef __ATOM_PORT_H
#define __ATOM_PORT_H

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


/* Required number of system ticks per second (normally 100 for 10ms tick) */
#define SYSTEM_TICKS_PER_SEC 100

/* Size of each stack entry / stack alignment size (32 bits on this platform) */
#define STACK_ALIGN_SIZE sizeof(uint32_t)

/**
* Architecture-specific types.
* Most of these are available from stdint.h on this platform, which is
* included above.
*/
#define POINTER void *

extern uint32_t contextEnterCritical (void) ;
extern void contextExitCritical (uint32_t posture) ;

#define CRITICAL_STORE uint32_t __atom_critical
#define CRITICAL_START() __atom_critical = contextEnterCritical()
#define CRITICAL_END() contextExitCritical(__atom_critical)

/* Uncomment to enable stack-checking */
/* #define ATOM_STACK_CHECKING */

#endif /* __ATOM_PORT_H */
62 changes: 62 additions & 0 deletions ports/x86/boot.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* AtomThreads project - Copyright (c) 2010, Kelvin Lawson. All rights reserved.
*
* Please refer to the README file for further details and License information.
*
* x86 port by: ido@mm.st
*/

# multiboot header

.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot

.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM

.section .bss
.skip 16384 # 16K stack
sys_stack_top:

.section .text

.global _start
.type _start, @function
_start:

cli
movl $sys_stack_top, %esp

call kernel_main

cli
hlt
.Lhang:
jmp .Lhang

.global gdt_flush
.extern gdt_p

gdt_flush:
lgdt gdt_p
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
ljmp $0x08, $1f

1: ret

# Set the size of the _start symbol to the current location '.' minus its start.
# This is useful when debugging or when you implement call tracing.
.size _start, . - _start


Loading