Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 451 → Rev 452

/SPARTAN/trunk/clean.ia64
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/clean.amd64
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/clean.sparc64
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/clean.mips32
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/clean.ppc32
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/build.ia64
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/build.amd64
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/build.sparc64
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/build.mips32
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/build.ppc32
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/clean.ia32
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/SPARTAN/trunk/Makefile.config
1,47 → 1,27
#ARCH=ia32
#ARCH=mips32
#ARCH=ia64
#ARCH=ppc32
#ARCH=amd64
#ARCH=sparc64
## General configuration directives
#
# CONFIG_SMP (n/y)
# Support for symetric multiprocessors
#
# CONFIG_HT (n/y)
# Improved support for hyperthreading
#
# CONFIG_FPU_LAZY (n/y)
# Lazy context switching
#
 
# If this is yes, then the native compiler will be used instead of cross compiler
NATIVE_COMPILER=no
CONFIG_SMP = y
CONFIG_HT = y
CONFIG_FPU_LAZY = y
 
# If this is yes, strong CPU ordering is assumed
STRONG_ORDERING=no
## Debugging configuration directives
#
# CONFIG_DEBUG (n/y)
# General debuging and assert checking
#
# CONFIG_DEBUG_SPINLOCK (n/y)
# Deadlock detection support for spinlocks
#
 
# Support for symetric multiprocessors
SMP=__SMP__
 
# Improved support for hyperthreading
HT=__HT__
 
# General debuging and assert checking disable
#NDEBUG=__NDEBUG__
 
# Deadlock detection support for spinlocks.
DEBUG_SPINLOCK=DEBUG_SPINLOCK
 
# Uncomment if you want to compile in userspace support
#USERSPACE=__USERSPACE__
 
# Uncomment if you want to run in the test mode
#TEST=__TEST__
 
TEST_FILE=test.c
 
# Select what test do you want to run
#TEST_DIR=synch/rwlock1/
#TEST_DIR=synch/rwlock2/
#TEST_DIR=synch/rwlock3/
#TEST_DIR=synch/rwlock4/
#TEST_DIR=synch/rwlock5/
#TEST_DIR=synch/semaphore1/
#TEST_DIR=synch/semaphore2/
#TEST_DIR=fpu/fpu1/
#TEST_DIR=fpu/sse1/
#TEST_DIR=fpu/mips1/
#TEST_DIR=print/print1/
#TEST_DIR=thread/thread1/
#TEST_DIR=mm/mapping1/
CONFIG_DEBUG = n
CONFIG_DEBUG_SPINLOCK = y
/SPARTAN/trunk/clean
0,0 → 1,3
#! /bin/sh
 
make clean
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/SPARTAN/trunk/genarch/include/firmware/acpi/madt.h
File deleted
/SPARTAN/trunk/genarch/include/firmware/acpi/acpi.h
File deleted
/SPARTAN/trunk/genarch/include/acpi/acpi.h
0,0 → 1,85
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __ACPI_H__
#define __ACPI_H__
 
#include <arch/types.h>
 
/* Root System Description Pointer */
struct acpi_rsdp {
__u8 signature[8];
__u8 checksum;
__u8 oemid[6];
__u8 revision;
__u32 rsdt_address;
__u32 length;
__u64 xsdt_address;
__u32 ext_checksum;
__u8 reserved[3];
} __attribute__ ((packed));
 
/* System Description Table Header */
struct acpi_sdt_header {
__u8 signature[4];
__u32 length;
__u8 revision;
__u8 checksum;
__u8 oemid[6];
__u8 oem_table_id[8];
__u32 oem_revision;
__u32 creator_id;
__u32 creator_revision;
} __attribute__ ((packed));;
 
struct acpi_signature_map {
__u8 *signature;
struct acpi_sdt_header **sdt_ptr;
char *description;
};
 
/* Root System Description Table */
struct acpi_rsdt {
struct acpi_sdt_header header;
__u32 entry[];
} __attribute__ ((packed));;
 
/* Extended System Description Table */
struct acpi_xsdt {
struct acpi_sdt_header header;
__u64 entry[];
} __attribute__ ((packed));;
 
extern struct acpi_rsdp *acpi_rsdp;
extern struct acpi_rsdt *acpi_rsdt;
extern struct acpi_xsdt *acpi_xsdt;
 
extern void acpi_init(void);
extern int acpi_sdt_check(__u8 *sdt);
 
#endif /* __ACPI_H__ */
/SPARTAN/trunk/genarch/include/acpi/madt.h
0,0 → 1,140
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __MADT_H__
#define __MADT_H__
 
#include <genarch/acpi/acpi.h>
#include <arch/smp/apic.h>
#include <arch/smp/smp.h>
 
#define MADT_L_APIC 0
#define MADT_IO_APIC 1
#define MADT_INTR_SRC_OVRD 2
#define MADT_NMI_SRC 3
#define MADT_L_APIC_NMI 4
#define MADT_L_APIC_ADDR_OVRD 5
#define MADT_IO_SAPIC 6
#define MADT_L_SAPIC 7
#define MADT_PLATFORM_INTR_SRC 8
#define MADT_RESERVED_SKIP_BEGIN 9
#define MADT_RESERVED_SKIP_END 127
#define MADT_RESERVED_OEM_BEGIN 128
 
struct madt_apic_header {
__u8 type;
__u8 length;
} __attribute__ ((packed));
 
 
/* Multiple APIC Description Table */
struct acpi_madt {
struct acpi_sdt_header header;
__u32 l_apic_address;
__u32 flags;
struct madt_apic_header apic_header[];
} __attribute__ ((packed));
 
struct madt_l_apic {
struct madt_apic_header header;
__u8 acpi_id;
__u8 apic_id;
__u32 flags;
} __attribute__ ((packed));
 
struct madt_io_apic {
struct madt_apic_header header;
__u8 io_apic_id;
__u8 reserved;
__u32 io_apic_address;
__u32 global_intr_base;
} __attribute__ ((packed));
 
struct madt_intr_src_ovrd {
struct madt_apic_header header;
__u8 bus;
__u8 source;
__u32 global_intr;
__u16 flags;
} __attribute__ ((packed));
 
struct madt_nmi_src {
struct madt_apic_header header;
__u16 flags;
__u32 global_intr;
} __attribute__ ((packed));
 
struct madt_l_apic_nmi {
struct madt_apic_header header;
__u8 acpi_id;
__u16 flags;
__u8 l_apic_lint;
} __attribute__ ((packed));
 
struct madt_l_apic_addr_ovrd {
struct madt_apic_header header;
__u16 reserved;
__u64 l_apic_address;
} __attribute__ ((packed));
 
struct madt_io_sapic {
struct madt_apic_header header;
__u8 io_apic_id;
__u8 reserved;
__u32 global_intr_base;
__u64 io_apic_address;
} __attribute__ ((packed));
 
struct madt_l_sapic {
struct madt_apic_header header;
__u8 acpi_id;
__u8 sapic_id;
__u8 sapic_eid;
__u8 reserved[3];
__u32 flags;
__u32 acpi_processor_uid_value;
__u8 acpi_processor_uid_str[1];
} __attribute__ ((packed));
 
struct madt_platform_intr_src {
struct madt_apic_header header;
__u16 flags;
__u8 intr_type;
__u8 processor_id;
__u8 processor_eid;
__u8 io_sapic_vector;
__u32 global_intr;
__u32 platform_intr_src_flags;
} __attribute__ ((packed));
 
extern struct acpi_madt *acpi_madt;
extern struct smp_config_operations madt_config_operations;
 
extern void acpi_madt_parse(void);
 
#endif /* __MADT_H__ */
/SPARTAN/trunk/genarch/Makefile.inc
1,39 → 1,39
# Copyright (C) 2005 Martin Decky
# All rights reserved.
#
# Open Firmware
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
OFW=no
 
ifeq ($(ARCH),ppc32)
OFW=yes
endif
 
ifeq ($(ARCH),sparc64)
OFW=yes
endif
 
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# Advanced Configuration and Power Interface (ACPI)
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
ACPI=no
 
ifeq ($(ARCH),ia32)
ACPI=yes
endif
## Accepted configuration directives
#
 
ifeq ($(ARCH),amd64)
ACPI=yes
ifeq ($(CONFIG_OFW),y)
GENARCH_SOURCES += \
genarch/src/firmware/ofw/ofw.c
endif
 
ifeq ($(ARCH),ia64)
#ACPI=yes
ifeq ($(CONFIG_ACPI),y)
GENARCH_SOURCES += \
genarch/src/acpi/acpi.c \
genarch/src/acpi/matd.c
endif
 
 
ifeq ($(OFW),yes)
genarch_sources+=generic/src/genarch/firmware/ofw/ofw.c
endif
 
ifeq ($(ACPI),yes)
genarch_sources+=generic/src/genarch/firmware/acpi/acpi.c \
generic/src/genarch/firmware/acpi/madt.c
endif
/SPARTAN/trunk/genarch/src/firmware/acpi/acpi.c
File deleted
/SPARTAN/trunk/genarch/src/firmware/acpi/madt.c
File deleted
/SPARTAN/trunk/genarch/src/acpi/matd.c
0,0 → 1,213
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <arch/types.h>
#include <typedefs.h>
#include <genarch/acpi/acpi.h>
#include <genarch/acpi/madt.h>
#include <arch/smp/apic.h>
#include <arch/smp/smp.h>
#include <panic.h>
#include <debug.h>
#include <config.h>
#include <print.h>
#include <mm/heap.h>
#include <memstr.h>
#include <sort.h>
 
struct acpi_madt *acpi_madt = NULL;
 
#ifdef __SMP__
 
static void madt_l_apic_entry(struct madt_l_apic *la, __u32 index);
static void madt_io_apic_entry(struct madt_io_apic *ioa, __u32 index);
static int madt_cmp(void * a, void * b);
 
struct madt_l_apic *madt_l_apic_entries = NULL;
struct madt_io_apic *madt_io_apic_entries = NULL;
 
index_t madt_l_apic_entry_index = 0;
index_t madt_io_apic_entry_index = 0;
count_t madt_l_apic_entry_cnt = 0;
count_t madt_io_apic_entry_cnt = 0;
count_t cpu_count = 0;
 
struct madt_apic_header * * madt_entries_index = NULL;
int madt_entries_index_cnt = 0;
 
char *entry[] = {
"L_APIC",
"IO_APIC",
"INTR_SRC_OVRD",
"NMI_SRC",
"L_APIC_NMI",
"L_APIC_ADDR_OVRD",
"IO_SAPIC",
"L_SAPIC",
"PLATFORM_INTR_SRC"
};
 
/*
* ACPI MADT Implementation of SMP configuration interface.
*/
static count_t madt_cpu_count(void);
static bool madt_cpu_enabled(index_t i);
static bool madt_cpu_bootstrap(index_t i);
static __u8 madt_cpu_apic_id(index_t i);
 
struct smp_config_operations madt_config_operations = {
.cpu_count = madt_cpu_count,
.cpu_enabled = madt_cpu_enabled,
.cpu_bootstrap = madt_cpu_bootstrap,
.cpu_apic_id = madt_cpu_apic_id
};
 
static count_t madt_cpu_count(void)
{
return madt_l_apic_entry_cnt;
}
 
static bool madt_cpu_enabled(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
 
}
 
static bool madt_cpu_bootstrap(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id();
}
 
static __u8 madt_cpu_apic_id(index_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
}
 
int madt_cmp(void * a, void * b)
{
return
(((struct madt_apic_header *) a)->type > ((struct madt_apic_header *) b)->type) ?
1 :
((((struct madt_apic_header *) a)->type < ((struct madt_apic_header *) b)->type) ? -1 : 0);
}
void acpi_madt_parse(void)
{
struct madt_apic_header *end = (struct madt_apic_header *) (((__u8 *) acpi_madt) + acpi_madt->header.length);
struct madt_apic_header *h;
l_apic = (__u32 *) (__native) acpi_madt->l_apic_address;
 
/* calculate madt entries */
for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((__u8 *) h) + h->length)) {
madt_entries_index_cnt++;
}
 
/* create madt apic entries index array */
madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *));
 
__u32 index = 0;
 
for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((__u8 *) h) + h->length)) {
madt_entries_index[index++] = h;
}
 
/* Quicksort MADT index structure */
qsort(madt_entries_index, madt_entries_index_cnt, sizeof(__address), &madt_cmp);
 
/* Parse MADT entries */
for (index = 0; index < madt_entries_index_cnt - 1; index++) {
h = madt_entries_index[index];
switch (h->type) {
case MADT_L_APIC:
madt_l_apic_entry((struct madt_l_apic *) h, index);
break;
case MADT_IO_APIC:
madt_io_apic_entry((struct madt_io_apic *) h, index);
break;
case MADT_INTR_SRC_OVRD:
case MADT_NMI_SRC:
case MADT_L_APIC_NMI:
case MADT_L_APIC_ADDR_OVRD:
case MADT_IO_SAPIC:
case MADT_L_SAPIC:
case MADT_PLATFORM_INTR_SRC:
printf("MADT: skipping %s entry (type=%d)\n", entry[h->type], h->type);
break;
 
default:
if (h->type >= MADT_RESERVED_SKIP_BEGIN && h->type <= MADT_RESERVED_SKIP_END) {
printf("MADT: skipping reserved entry (type=%d)\n", h->type);
}
if (h->type >= MADT_RESERVED_OEM_BEGIN) {
printf("MADT: skipping OEM entry (type=%d)\n", h->type);
}
break;
}
}
 
if (cpu_count)
config.cpu_count = cpu_count;
}
 
void madt_l_apic_entry(struct madt_l_apic *la, __u32 index)
{
if (!madt_l_apic_entry_cnt++) {
madt_l_apic_entry_index = index;
}
if (!(la->flags & 0x1)) {
/* Processor is unusable, skip it. */
return;
}
cpu_count++;
apic_id_mask |= 1<<la->apic_id;
}
 
void madt_io_apic_entry(struct madt_io_apic *ioa, __u32 index)
{
if (!madt_io_apic_entry_cnt++) {
/* remember index of the first io apic entry */
madt_io_apic_entry_index = index;
io_apic = (__u32 *) (__native) ioa->io_apic_address;
} else {
/* currently not supported */
return;
}
}
 
 
#endif /* __SMP__ */
/SPARTAN/trunk/genarch/src/acpi/acpi.c
0,0 → 1,175
/*
* Copyright (C) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <genarch/acpi/acpi.h>
#include <genarch/acpi/madt.h>
#include <arch/bios/bios.h>
 
#include <mm/page.h>
#include <print.h>
 
#define RSDP_SIGNATURE "RSD PTR "
#define RSDP_REVISION_OFFS 15
 
struct acpi_rsdp *acpi_rsdp = NULL;
struct acpi_rsdt *acpi_rsdt = NULL;
struct acpi_xsdt *acpi_xsdt = NULL;
 
struct acpi_signature_map signature_map[] = {
{ (__u8 *)"APIC", (struct acpi_sdt_header **) &acpi_madt, "Multiple APIC Description Table" }
};
 
static int rsdp_check(__u8 *rsdp) {
struct acpi_rsdp *r = (struct acpi_rsdp *) rsdp;
__u8 sum = 0;
int i;
for (i=0; i<20; i++)
sum += rsdp[i];
if (sum)
return 0; /* bad checksum */
 
if (r->revision == 0)
return 1; /* ACPI 1.0 */
for (; i<r->length; i++)
sum += rsdp[i];
return !sum;
}
 
int acpi_sdt_check(__u8 *sdt)
{
struct acpi_sdt_header *h = (struct acpi_sdt_header *) sdt;
__u8 sum = 0;
int i;
 
for (i=0; i<h->length; i++)
sum += sdt[i];
return !sum;
}
 
static void map_sdt(struct acpi_sdt_header *sdt)
{
map_page_to_frame((__address) sdt, (__address) sdt, PAGE_NOT_CACHEABLE, 0);
map_structure((__address) sdt, sdt->length);
}
 
static void configure_via_rsdt(void)
{
int i, j, cnt = (acpi_rsdt->header.length - sizeof(struct acpi_sdt_header))/sizeof(__u32);
for (i=0; i<cnt; i++) {
for (j=0; j<sizeof(signature_map)/sizeof(struct acpi_signature_map); j++) {
struct acpi_sdt_header *h = (struct acpi_sdt_header *) (__native) acpi_rsdt->entry[i];
map_sdt(h);
if (*((__u32 *) &h->signature[0])==*((__u32 *) &signature_map[j].signature[0])) {
if (!acpi_sdt_check((__u8 *) h))
goto next;
*signature_map[j].sdt_ptr = h;
printf("%P: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
}
}
next:
;
}
}
 
static void configure_via_xsdt(void)
{
int i, j, cnt = (acpi_xsdt->header.length - sizeof(struct acpi_sdt_header))/sizeof(__u64);
for (i=0; i<cnt; i++) {
for (j=0; j<sizeof(signature_map)/sizeof(struct acpi_signature_map); j++) {
struct acpi_sdt_header *h = (struct acpi_sdt_header *) ((__address) acpi_rsdt->entry[i]);
 
map_sdt(h);
if (*((__u32 *) &h->signature[0])==*((__u32 *) &signature_map[j].signature[0])) {
if (!acpi_sdt_check((__u8 *) h))
goto next;
*signature_map[j].sdt_ptr = h;
printf("%P: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
}
}
next:
;
}
 
}
 
void acpi_init(void)
{
__u8 *addr[2] = { NULL, (__u8 *) PA2KA(0xe0000) };
int i, j, length[2] = { 1024, 128*1024 };
__u64 *sig = (__u64 *) RSDP_SIGNATURE;
 
/*
* Find Root System Description Pointer
* 1. search first 1K of EBDA
* 2. search 128K starting at 0xe0000
*/
 
addr[0] = (__u8 *) PA2KA(ebda);
for (i = (ebda ? 0 : 1); i < 2; i++) {
for (j = 0; j < length[i]; j += 16) {
if (*((__u64 *) &addr[i][j]) == *sig && rsdp_check(&addr[i][j])) {
acpi_rsdp = (struct acpi_rsdp *) &addr[i][j];
goto rsdp_found;
}
}
}
 
return;
 
rsdp_found:
printf("%P: ACPI Root System Description Pointer\n", acpi_rsdp);
 
acpi_rsdt = (struct acpi_rsdt *) (__native) acpi_rsdp->rsdt_address;
if (acpi_rsdp->revision) acpi_xsdt = (struct acpi_xsdt *) ((__address) acpi_rsdp->xsdt_address);
 
if (acpi_rsdt) map_sdt((struct acpi_sdt_header *) acpi_rsdt);
if (acpi_xsdt) map_sdt((struct acpi_sdt_header *) acpi_xsdt);
 
if (acpi_rsdt && !acpi_sdt_check((__u8 *) acpi_rsdt)) {
printf("RSDT: %s\n", "bad checksum");
return;
}
if (acpi_xsdt && !acpi_sdt_check((__u8 *) acpi_xsdt)) {
printf("XSDT: %s\n", "bad checksum");
return;
}
 
if (acpi_xsdt) configure_via_xsdt();
else if (acpi_rsdt) configure_via_rsdt();
 
}
 
/SPARTAN/trunk/generic/include/print.h
36,11 → 36,6
#define INT32 4
#define INT64 8
 
static void print_double(double num, __u8 modifier, __u16 precision) ;
static void print_str(const char *str);
static void print_fixed_hex(const __u64 num, const int width);
static void print_number(const __native num, const unsigned int base);
 
extern void putchar(const char c);
extern void printf(const char *fmt, ...);
 
/SPARTAN/trunk/generic/include/proc/scheduler.h
44,11 → 44,6
};
 
extern volatile count_t nrdy;
 
static thread_t *find_best_thread(void);
static void relink_rq(int start);
static void scheduler_separated_stack(void);
 
extern void scheduler_init(void);
 
extern void scheduler_fpu_lazy_request(void);
/SPARTAN/trunk/generic/include/proc/thread.h
112,8 → 112,6
extern spinlock_t threads_lock; /**< Lock protecting threads_head list. */
extern link_t threads_head; /**< List of all threads in the system. */
 
static void cushion(void);
 
extern void thread_init(void);
extern thread_t *thread_create(void (* func)(void *), void *arg, task_t *task, int flags);
extern void thread_ready(thread_t *t);
/SPARTAN/trunk/generic/src/proc/scheduler.c
116,7 → 116,7
* @return Thread to be scheduled.
*
*/
struct thread *find_best_thread(void)
static struct thread *find_best_thread(void)
{
thread_t *t;
runq_t *r;
222,7 → 222,7
* @param start Threshold priority.
*
*/
void relink_rq(int start)
static void relink_rq(int start)
{
link_t head;
runq_t *r;
254,71 → 254,6
}
 
 
/** The scheduler
*
* The thread scheduling procedure.
*
*/
void scheduler(void)
{
volatile ipl_t ipl;
 
ASSERT(CPU != NULL);
 
ipl = interrupts_disable();
 
if (haltstate)
halt();
 
if (THREAD) {
spinlock_lock(&THREAD->lock);
#ifndef FPU_LAZY
fpu_context_save(&(THREAD->saved_fpu_context));
#endif
if (!context_save(&THREAD->saved_context)) {
/*
* This is the place where threads leave scheduler();
*/
before_thread_runs();
spinlock_unlock(&THREAD->lock);
interrupts_restore(THREAD->saved_context.ipl);
return;
}
 
/*
* Interrupt priority level of preempted thread is recorded here
* to facilitate scheduler() invocations from interrupts_disable()'d
* code (e.g. waitq_sleep_timeout()).
*/
THREAD->saved_context.ipl = ipl;
}
 
/*
* Through the 'THE' structure, we keep track of THREAD, TASK, CPU
* and preemption counter. At this point THE could be coming either
* from THREAD's or CPU's stack.
*/
the_copy(THE, (the_t *) CPU->stack);
 
/*
* We may not keep the old stack.
* Reason: If we kept the old stack and got blocked, for instance, in
* find_best_thread(), the old thread could get rescheduled by another
* CPU and overwrite the part of its own stack that was also used by
* the scheduler on this CPU.
*
* Moreover, we have to bypass the compiler-generated POP sequence
* which is fooled by SP being set to the very top of the stack.
* Therefore the scheduler() function continues in
* scheduler_separated_stack().
*/
context_save(&CPU->saved_context);
context_set(&CPU->saved_context, FADDR(scheduler_separated_stack), (__address) CPU->stack, CPU_STACK_SIZE);
context_restore(&CPU->saved_context);
/* not reached */
}
 
 
/** Scheduler stack switch wrapper
*
* Second part of the scheduler() function
326,7 → 261,7
* switch to a new thread.
*
*/
void scheduler_separated_stack(void)
static void scheduler_separated_stack(void)
{
int priority;
 
459,6 → 394,74
}
 
 
/** The scheduler
*
* The thread scheduling procedure.
*
*/
void scheduler(void)
{
volatile ipl_t ipl;
 
ASSERT(CPU != NULL);
 
ipl = interrupts_disable();
 
if (haltstate)
halt();
 
if (THREAD) {
spinlock_lock(&THREAD->lock);
#ifndef FPU_LAZY
fpu_context_save(&(THREAD->saved_fpu_context));
#endif
if (!context_save(&THREAD->saved_context)) {
/*
* This is the place where threads leave scheduler();
*/
before_thread_runs();
spinlock_unlock(&THREAD->lock);
interrupts_restore(THREAD->saved_context.ipl);
return;
}
 
/*
* Interrupt priority level of preempted thread is recorded here
* to facilitate scheduler() invocations from interrupts_disable()'d
* code (e.g. waitq_sleep_timeout()).
*/
THREAD->saved_context.ipl = ipl;
}
 
/*
* Through the 'THE' structure, we keep track of THREAD, TASK, CPU
* and preemption counter. At this point THE could be coming either
* from THREAD's or CPU's stack.
*/
the_copy(THE, (the_t *) CPU->stack);
 
/*
* We may not keep the old stack.
* Reason: If we kept the old stack and got blocked, for instance, in
* find_best_thread(), the old thread could get rescheduled by another
* CPU and overwrite the part of its own stack that was also used by
* the scheduler on this CPU.
*
* Moreover, we have to bypass the compiler-generated POP sequence
* which is fooled by SP being set to the very top of the stack.
* Therefore the scheduler() function continues in
* scheduler_separated_stack().
*/
context_save(&CPU->saved_context);
context_set(&CPU->saved_context, FADDR(scheduler_separated_stack), (__address) CPU->stack, CPU_STACK_SIZE);
context_restore(&CPU->saved_context);
/* not reached */
}
 
 
 
 
 
#ifdef __SMP__
/** Load balancing thread
*
/SPARTAN/trunk/generic/src/proc/thread.c
70,7 → 70,7
* interrupts_disable() is assumed.
*
*/
void cushion(void)
static void cushion(void)
{
void (*f)(void *) = THREAD->thread_code;
void *arg = THREAD->thread_arg;
/SPARTAN/trunk/generic/src/main/kinit.c
122,17 → 122,21
* Create the first user task.
*/
m = vm_create(NULL);
if (!m) panic("vm_create");
if (!m)
panic("vm_create");
u = task_create(m);
if (!u) panic("task_create");
if (!u)
panic("task_create");
t = thread_create(uinit, NULL, u, THREAD_USER_STACK);
if (!t) panic("thread_create");
if (!t)
panic("thread_create");
 
/*
* Create the text vm_area and copy the userspace code there.
*/
a = vm_area_create(m, VMA_TEXT, 1, UTEXT_ADDRESS);
if (!a) panic("vm_area_create: vm_text");
if (!a)
panic("vm_area_create: vm_text");
vm_area_map(a, m);
memcpy((void *) PA2KA(a->mapping[0]), (void *) utext, utext_size < PAGE_SIZE ? utext_size : PAGE_SIZE);
 
140,7 → 144,8
* Create the data vm_area.
*/
a = vm_area_create(m, VMA_STACK, 1, USTACK_ADDRESS);
if (!a) panic("vm_area_create: vm_stack");
if (!a)
panic("vm_area_create: vm_stack");
vm_area_map(a, m);
thread_ready(t);
/SPARTAN/trunk/generic/src/debug/print.c
41,8 → 41,72
#define DEFAULT_DOUBLE_PRECISION 16
#define DEFAULT_DOUBLE_BUFFER_SIZE 128
 
void print_double(double num, __u8 modifier, __u16 precision)
 
/** Print NULL terminated string
*
* Print characters from str using putchar() until
* \\0 character is reached.
*
* @param str Characters to print.
*
*/
static void print_str(const char *str)
{
int i = 0;
char c;
while (c = str[i++])
putchar(c);
}
 
 
/** Print hexadecimal digits
*
* Print fixed count of hexadecimal digits from
* the number num. The digits are printed in
* natural left-to-right order starting with
* the width-th digit.
*
* @param num Number containing digits.
* @param width Count of digits to print.
*
*/
static void print_fixed_hex(const __u64 num, const int width)
{
int i;
for (i = width*8 - 4; i >= 0; i -= 4)
putchar(digits[(num>>i) & 0xf]);
}
 
 
/** Print number in given base
*
* Print significant digits of a number in given
* base.
*
* @param num Number to print.
* @param base Base to print the number in (should
* be in range 2 .. 16).
*
*/
static void print_number(const __native num, const unsigned int base)
{
int val = num;
char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */
int i = sizeof(__native)*8-1;
do {
d[i--] = digits[val % base];
} while (val /= base);
d[sizeof(__native)*8] = 0;
print_str(&d[i + 1]);
}
 
 
static void print_double(double num, __u8 modifier, __u16 precision)
{
double intval,intval2;
int counter;
int exponent,exponenttmp;
142,69 → 206,7
return;
}
 
/** Print NULL terminated string
*
* Print characters from str using putchar() until
* \\0 character is reached.
*
* @param str Characters to print.
*
*/
void print_str(const char *str)
{
int i = 0;
char c;
while (c = str[i++])
putchar(c);
}
 
 
/** Print hexadecimal digits
*
* Print fixed count of hexadecimal digits from
* the number num. The digits are printed in
* natural left-to-right order starting with
* the width-th digit.
*
* @param num Number containing digits.
* @param width Count of digits to print.
*
*/
void print_fixed_hex(const __u64 num, const int width)
{
int i;
for (i = width*8 - 4; i >= 0; i -= 4)
putchar(digits[(num>>i) & 0xf]);
}
 
 
/** Print number in given base
*
* Print significant digits of a number in given
* base.
*
* @param num Number to print.
* @param base Base to print the number in (should
* be in range 2 .. 16).
*
*/
void print_number(const __native num, const unsigned int base)
{
int val = num;
char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */
int i = sizeof(__native)*8-1;
do {
d[i--] = digits[val % base];
} while (val /= base);
d[sizeof(__native)*8] = 0;
print_str(&d[i + 1]);
}
 
 
/** General formatted text print
*
* Print text formatted according the fmt parameter
/SPARTAN/trunk/arch/amd64/src/amd64.c
42,7 → 42,7
#include <arch/cpu.h>
#include <print.h>
#include <arch/cpuid.h>
#include <genarch/firmware/acpi/acpi.h>
#include <genarch/acpi/acpi.h>
#include <panic.h>
 
void arch_pre_mm_init(void)
/SPARTAN/trunk/arch/ia32/include/ega.h
37,7 → 37,4
extern void ega_init(void);
extern void ega_putchar(const char ch);
 
static void ega_check_cursor(void);
static void ega_display_char(char ch);
 
#endif
/SPARTAN/trunk/arch/ia32/Makefile.inc
1,73 → 1,105
ifeq (${NATIVE_COMPILER},yes)
CC=gcc
AS=as
LD=ld
OBJCOPY=objcopy
OBJDUMP=objdump
else
IA-32_TARGET=i686-pc-linux-gnu
#
# Copyright (C) 2005 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
IA-32_CC_DIR=/usr/local/i686/bin
IA-32_BINUTILS_DIR=/usr/local/i686/bin
## Toolchain configuration
#
 
CC=$(IA-32_CC_DIR)/$(IA-32_TARGET)-gcc
AS=$(IA-32_BINUTILS_DIR)/$(IA-32_TARGET)-as
LD=$(IA-32_BINUTILS_DIR)/$(IA-32_TARGET)-ld
OBJCOPY=$(IA-32_BINUTILS_DIR)/$(IA-32_TARGET)-objcopy
OBJDUMP=$(IA-32_BINUTILS_DIR)/$(IA-32_TARGET)-objdump
BFD_NAME = elf32-i386
BFD_ARCH = i386
TARGET = i686-pc-linux-gnu
TOOLCHAIN_DIR = /usr/local/i686/bin
 
## Accepted CPUs
#
# Default CPU is Pentium 4
#
 
ifeq ($CPU,athlon-xp)
CFLAGS += -march=athlon-xp -mmmx -msse -m3dnow
DEFS += -DFENCES=486
CONFIG_SMP = n
CONFIG_HT = n
elseifeq ($CPU,athlon-mp)
CFLAGS += -march=athlon-mp -mmmx -msse -m3dnow
DEFS += -DFENCES=486
elseifeq ($CPU,pentium3)
CFLAGS += -march=pentium3 -mmmx -msse -msse2
DEFS += -DFENCES=486
else
CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 -msse3
DEFS += -DFENCES=p4
endif
 
BFD_NAME=elf32-i386
BFD_ARCH=i386
## Own configuration directives
#
 
DEFS:=-DARCH=$(ARCH) -DFPU_LAZY
CONFIG_ACPI = y
 
ifeq (${STRONG_ORDERING},yes)
DEFS+=-D__STRONG_ORDERING__
endif
## Accepted configuration directives
#
 
ifdef SMP
DEFS+=-D$(SMP)
ifeq ($(CONFIG_SMP),y)
DEFS += -DSMP
endif
 
ifdef HT
DEFS+=-D$(HT)
ifeq ($(CONFIG_HT),y)
DEFS += -DHT
endif
ifeq ($(CONFIG_FPU_LAZY),y)
DEFS += -DFPU_LAZY
endif
 
CPPFLAGS=$(DEFS) -nostdinc -Iinclude/
CFLAGS=$(CPPFLAGS) -nostdlib -fno-builtin -fomit-frame-pointer -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3
LFLAGS=-M
 
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
$(CC) $(CFLAGS) -E -x c $< | grep -v "^\#" > $@
 
arch_sources= \
generic/src/arch/context.s \
generic/src/arch/debug/panic.s \
generic/src/arch/delay.s \
generic/src/arch/asm.S \
generic/src/arch/proc/scheduler.c \
generic/src/arch/bios/bios.c \
generic/src/arch/smp/ap.S \
generic/src/arch/smp/apic.c \
generic/src/arch/smp/mps.c \
generic/src/arch/smp/smp.c \
generic/src/arch/atomic.S \
generic/src/arch/smp/ipi.c \
generic/src/arch/ia32.c \
generic/src/arch/interrupt.c \
generic/src/arch/pm.c \
generic/src/arch/userspace.c \
generic/src/arch/cpu/cpu.c \
generic/src/arch/mm/frame.c \
generic/src/arch/mm/memory_init.c \
generic/src/arch/mm/page.c \
generic/src/arch/mm/tlb.c \
generic/src/arch/drivers/i8042.c \
generic/src/arch/drivers/i8254.c \
generic/src/arch/drivers/i8259.c \
generic/src/arch/drivers/ega.c \
generic/src/arch/boot/boot.S \
generic/src/arch/boot/memmap.S\
generic/src/arch/fpu_context.c\
generic/src/arch/fmath.c
ARCH_SOURCES = \
arch/$(ARCH)/src/context.s \
arch/$(ARCH)/src/debug/panic.s \
arch/$(ARCH)/src/delay.s \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/bios/bios.c \
arch/$(ARCH)/src/smp/ap.S \
arch/$(ARCH)/src/smp/apic.c \
arch/$(ARCH)/src/smp/mps.c \
arch/$(ARCH)/src/smp/smp.c \
arch/$(ARCH)/src/atomic.S \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/ia32.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/pm.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/memory_init.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/drivers/i8042.c \
arch/$(ARCH)/src/drivers/i8254.c \
arch/$(ARCH)/src/drivers/i8259.c \
arch/$(ARCH)/src/drivers/ega.c \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/boot/memmap.S \
arch/$(ARCH)/src/fpu_context.c\
arch/$(ARCH)/src/fmath.c
/SPARTAN/trunk/arch/ia32/src/ia32.c
44,7 → 44,7
 
#include <arch/interrupt.h>
#include <arch/asm.h>
#include <genarch/firmware/acpi/acpi.h>
#include <genarch/acpi/acpi.h>
 
#include <arch/bios/bios.h>
 
/SPARTAN/trunk/arch/ia32/src/cpu/cpu.c
100,7 → 100,6
void cpu_identify(void)
{
cpu_info_t info;
int i;
 
CPU->arch.vendor = VendorUnknown;
if (has_cpuid()) {
/SPARTAN/trunk/arch/ia32/src/smp/smp.c
30,8 → 30,8
#include <arch/smp/smp.h>
#include <arch/smp/mps.h>
#include <arch/smp/ap.h>
#include <genarch/firmware/acpi/acpi.h>
#include <genarch/firmware/acpi/madt.h>
#include <genarch/acpi/acpi.h>
#include <genarch/acpi/madt.h>
#include <config.h>
#include <synch/waitq.h>
#include <synch/synch.h>
/SPARTAN/trunk/arch/ia32/src/drivers/ega.c
58,7 → 58,7
ega_putchar('\n');
}
 
void ega_display_char(char ch)
static void ega_display_char(char ch)
{
__u8 *vram = (__u8 *) PA2KA(VIDEORAM);
68,7 → 68,7
/*
* This function takes care of scrolling.
*/
void ega_check_cursor(void)
static void ega_check_cursor(void)
{
if (ega_cursor < SCREEN)
return;
/SPARTAN/trunk/Makefile
1,8 → 1,90
#
# Copyright (C) 2005 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
## Kernel release
#
 
VERSION = 0
PATCHLEVEL = 1
SUBLEVEL = 0
EXTRAVERSION =
NAME = Dawn
RELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
## Make some default assumptions
#
 
ifndef ARCH
ARCH = ia32
endif
 
## Common compiler flags
#
 
CFLAGS = -fno-builtin -fomit-frame-pointer -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -nostdlib -nostdinc -Igeneric/include/
LFLAGS = -M
 
## Setup kernel configuration
#
 
include Makefile.config
include arch/$(ARCH)/Makefile.inc
include genarch/Makefile.inc
 
sources=generic/src/cpu/cpu.c \
ifeq ($(CONFIG_DEBUG),n)
DEFS += -DNDEBUG
endif
ifeq ($(CONFIG_DEBUG_SPINLOCK),y)
DEFS += -DDEBUG_SPINLOCK
endif
 
## Toolchain configuration
#
 
ifeq ($(COMPILER),native)
CC = gcc
AS = as
LD = ld
OBJCOPY = objcopy
OBJDUMP = objdump
else
CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
endif
 
## Generic kernel sources
#
 
GENERIC_SOURCES = \
generic/src/cpu/cpu.c \
generic/src/main/main.c \
generic/src/main/kinit.c \
generic/src/main/uinit.c \
35,68 → 117,42
generic/src/smp/ipi.c \
generic/src/fb/font-8x16.c
 
# CFLAGS options same for all targets
CFLAGS+=-nostdinc -Igeneric/include/ -Werror-implicit-function-declaration -Wmissing-prototypes -Werror
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
 
ifdef DEBUG_SPINLOCK
CFLAGS+=-D$(DEBUG_SPINLOCK)
endif
.PHONY: all clean config depend
 
ifdef USERSPACE
CFLAGS+=-D$(USERSPACE)
endif
all: kernel.bin
 
ifdef TEST
test_objects:=$(addsuffix .o,$(basename test/$(TEST_DIR)/$(TEST_FILE)))
CFLAGS+=-D$(TEST)
endif
arch_objects:=$(addsuffix .o,$(basename $(arch_sources)))
genarch_objects:=$(addsuffix .o,$(basename $(genarch_sources)))
objects:=$(addsuffix .o,$(basename $(sources)))
-include Makefile.depend
 
.PHONY : all config depend build clean dist-clean boot
clean:
find generic/src/ arch/$(ARCH)/src/ genarch/src/ -name '*.o' -exec rm \{\} \;
-rm -f kernel.bin kernel.map kernel.map.pre kernel.objdump src/debug/real_map.bin Makefile.depend generic/include/arch generic/include/genarch
 
all: dist-clean config depend build
 
-include Makefile.depend
 
config:
find generic/src/ generic/include/ -name arch -type l -exec rm \{\} \;
find generic/src/ generic/include/ -name genarch -type l -exec rm \{\} \;
ln -s ../../arch/$(ARCH)/src/ generic/src/arch
ln -s ../../arch/$(ARCH)/include/ generic/include/arch
ln -s ../../genarch/src/ generic/src/genarch
ln -s ../../genarch/include/ generic/include/genarch
ln -sfn ../../arch/$(ARCH)/include/ generic/include/arch
ln -sfn ../../genarch/include/ generic/include/genarch
 
depend:
$(CC) $(CFLAGS) -M $(arch_sources) $(genarch_sources) $(sources) >Makefile.depend
depend: config
$(CC) $(CFLAGS) -M $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend
 
build: kernel.bin boot
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
$(CC) $(CFLAGS) -E -x c $< | grep -v "^\#" > $@
 
clean:
find generic/src/ arch/$(ARCH)/src/ genarch/src/ test/ -name '*.o' -exec rm \{\} \;
-rm *.bin kernel.map kernel.map.pre kernel.objdump generic/src/debug/real_map.bin
$(MAKE) -C arch/$(ARCH)/boot/ clean
 
dist-clean:
find generic/src/ generic/include/ -name arch -type l -exec rm \{\} \;
find generic/src/ generic/include/ -name genarch -type l -exec rm \{\} \;
-rm Makefile.depend
-$(MAKE) clean
 
generic/src/debug/real_map.bin: $(arch_objects) $(genarch_objects) $(objects) $(test_objects) arch/$(ARCH)/_link.ld
generic/src/debug/real_map.bin: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
$(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) --prefix-sections=symtab Makefile generic/src/debug/empty_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(arch_objects) $(genarch_objects) $(objects) $(test_objects) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre
$(OBJDUMP) -t $(arch_objects) $(genarch_objects) $(objects) $(test_objects) > kernel.objdump
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin
 
generic/src/debug/real_map.o: generic/src/debug/real_map.bin
$(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) --prefix-sections=symtab $< $@
 
kernel.bin: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/real_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/real_map.o -o $@ -Map kernel.map
 
kernel.bin: $(arch_objects) $(genarch_objects) $(objects) $(test_objects) arch/$(ARCH)/_link.ld generic/src/debug/real_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(arch_objects) $(genarch_objects) $(objects) $(test_objects) generic/src/debug/real_map.o -o $@ -Map kernel.map
 
%.o: %.S
$(CC) $(ASFLAGS) $(CFLAGS) -c $< -o $@
 
105,8 → 161,3
 
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
 
KS=`cat kernel.bin | wc -c`
 
boot:
$(MAKE) -C arch/$(ARCH)/boot build KERNEL_SIZE=$(KS)