• Ingen resultater fundet

Summary

In document AN EMBEDDED SYSTEMS KERNEL (Sider 97-184)

as a hard real-time system. This would not require much coding, but a thorough analysis of the kernel.

Kernel locking Create a finer grained locking, and maybe even new mech-anisms for the locking such as spin-locks. To reduce the kernel latency, locking needs thorough analysing.

11.4 Summary

Hopefully, some of the above suggestion will inspire other students to con-tinue the work on this kernel project.

87

Chapter 12

Conclusion

A development system environment suitable for embedded system devel-opment has been composed. The environment includes Free Software tools and some interesting, reasonably fast and easy to use hardware with a good community and commercial support.

The resulting kernel, which has been developed during this thesis, is very small. The source code is approximately 3500 lines of C and assembly code and this includes all comments and header files. Even though its size is very limited, it does include some important features, to mention a few:

Effective timer implementation

Binary Semaphores which implements the basic priority inheritance protocol

A pre-emptive nano-kernel which reduces latency

The resulting kernel is highly modularized and the scheduler can be changed with minimum effort. With reasonably little coding effort the kernel could be used in hard real-time systems.

The kernel has been designed and implemented with portability in mind and as much code as possible has been written in C. The result is a kernel where the porting process to another architecture can be done almost by rewriting the assembly routines to fit the new architecture.

Even though there has been hard times carrying out this thesis, with linker bugs and hardware bugs that took several weeks to work around, it has been

an interesting and educational project. It has given me a good understand-ing of embedded development, hardware bootstrappunderstand-ing and initialization, as well as good insight to many different aspects of operating system’s theory.

Is has also been a good experience to hand over this kernel project to another student, and enable him to carry on the future kernel work.

89

Appendix A

Project description

Danish title: Bidrag til udvikling af nanokerne

English title: Contribution to development of a nanokernel Participant: Lars Munch Christensen

Danish project description:

Det langsigtede m˚al er at konstruere biblioteksrutiner, der kan karakteris-eres som en nanokerne, idet de skal kunne lænkes sammen med dels anvendel-ses- dels maskinspecifikke rutiner til indlejrede systemer. Ses bort fra kold-start skal et indlejret system kunne opfattes som et enkelt program med flere aktiviteter. N˚ar programmet starter eksisterer kun en enkelt aktivitet, der afvikles uden begrænsninger i privilegier.

Oprettelse og start af aktiviteter skal kunne udtrykkes ved hjælp af nanok-ernens rutiner. Der skal kunne styres b˚ade frivilligt og p˚atvungent pro-cesskifte.

Til udnyttelse af materiel til understøttelse af begrænsninger i forskellige aktiviteters privilegier søges udarbejdet og afprøvet et sæt passende kon-ventioner.

Koldstartsproblemer skal analyseres og behandles med henblik p˚a at

re-ducere afhængigheder af materiel s˚a meget som muligt.

Det konkrete m˚al for projektet er at implementere en nanokerne s˚a vidt, at et indlejret system kan koldstartes og udnytte en simpel ydre enhed. Ind-hentning af oplysninger om lignende systemer betragtes som en væsentlig del af projektet.

91

Bibliography

[1] SMcS FDC37817 Super I/O Controller datasheet.

[2] Atmel, AVR Microcontrollers, STK500 Starter Kit and Development system.

[3] Atmel, AT91EB40 Evaluation Board Users Guide.

[4] Galileo Technology, GT-64120A System Controller for RC4650/4700/5000 and RM526x/527x/7000 CPUs

[5] Intel, 82371AB PCI-TO-ISA / IDE XCELERATOR (PIIX4)

[6] MIPS Technologies, CoreLV User’s Manual, Document Number:

MD00007, Revision 02.06

[7] MIPS Technologies, Processor Core Family Software User’s Manual, Document Number: MD00012, Revision 02.04

[8] MIPS Technologies, 5Kc Processor Core Datasheet, January 15, 2001.

[9] GNU linker ld version 2.10.91 info pages [10] GNU Automake version 1.4 info pages

[11] S. Tan et al., An Object-Oriented Nano-Kernel for Operating System Hardware Support, Proceedings of the Fourth IWOOOS, IEEE Computer Society, Aug, 1995, Lund, Sweden.

[12] Jeffrey S. Chase, Henry M. Levy, Michale J. Feeley and Edward D.

Lazowska, Sharing and Protection in a Single Address Space Oper-ating System, Department of Computer Science and Engineering, FR-35, University of Washington, Seattle, WA 98195 USA.

[13] Design and implementation of an Object-Oriented 64-bit Single Address Space Microkernel, Kevin Murray, Tim Wilkinson, Peter Osmon - SARC, City University. Ashley Saulsbury - Swedish Institute of Computer Science. Tom Stiemerling, Paul Kelly - Imperial College.

[14] Implementation and Performance of the Mungi Single Address Space Operating System. Jochen Liedtke, The University of New South Wales.

[15] S. Tan et al. An Object-Oriented Nano-Kernel for Operating System Hardware Support, Department of Computer Science, University of Illinois at Urbana-Champaign.

[16] Exception Handling in Embedded C Programs, C/C++ Users Jour-nal, Yonatan Lehman

[17] A. S. Tannenbaum, A. S. Woolhull, Second edition, Operating Systems Design and implementation. Prentice Hall, 1997

[18] Michael Barr, Programming embedded Systems, O’Reilly and Asso-ciates, 1999

[19] M. Ben-Ari, Principles of Concurrent Programming.

[20] Dominic Sweetman, See MIPS Run. Morgan Kaufmann Publishers, Inc.

[21] GNU Project, http://gcc.gnu.org [22] MontaVista, http://www.mvista.com [23] Linux-VR Project, http://www.linux-vr.org [24] Red Hat Inc., http://www.redhat.com

BIBLIOGRAPHY 93

[25] Linux on SGI/MIPS, http://oss.sgi.com/mips/

[26] Newlib Library, http://sources.redhat.com/newlib/

[27] Small Device C Compiler project, SDCC http://sdcc.sourceforge.net/

[28] Red Hat eCos, http://www.redhat.com/embedded/technologies/ecos/

[29] The LinuxBIOS Home Page, http://www.acl.lanl.gov/linuxbios/index.html [30] The LILO Home Page, http://brun.dyndns.org/pub/linux/lilo/

[31] The GRUB Home Page, http://www.gnu.org/software/grub/

[32] The EtherBoot Home Page, http://etherboot.sourceforge.net/

[33] The RedBoot Home Page, http://www.redhat.com/embedded/technologies/redboot/

[34] The Embedded PowerPC Linux Boot Project,

http://ppcboot.sourceforge.net/

95

Appendix B

Source code

File Page File Page

Makefile 96 include/stddef.h 126

kernel/mips64/link.xn 99 include/system.h 126 include/addrspace.h 100 include/timer.h 128

include/asm.h 102 include/yamon.h 129

include/byteorder.h 103

include/cpu.h 103 kernel/cpu.c 136

include/interrupt.h 104 kernel/interrupt.c 138 include/kernel.h 105 kernel/kernel.c 142

include/lcd.h 105 kernel/lcd.c 144

include/list.h 105 kernel/list.c 145

include/mipsregs.h 107 kernel/mipsirq.S 147 include/piix4.h 111 kernel/panic.c 149 include/printf.h 113 kernel/process.c 150 include/process.h 113 kernel/sched.c 154 include/regdef.h 114 kernel/semaphore.c 156 include/regoffset.h 115 kernel/serial.c 158

include/rtc.h 117 kernel/setjmp.S 160

include/sched.h 118 kernel/stack.S 161 include/semaphore.h 119 kernel/start.S 162 include/serial.h 119 kernel/test1.c 163 include/setjmp.h 121 kernel/test2.c 163 include/stackframe.h 122 kernel/timer.c 164

: Makefile

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Kernel installation dir

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

TFTPDIR = /kernel

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Active compilation toolchain

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

TOOLCHAIN = mips64

#TOOLCHAIN = mips64el

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Architecture

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

ARCH = mips64

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Endianness EB|EL

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

ENDIAN = EB

#ENDIAN = EL

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Name of kernel

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

IMAGENAME = kernel

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# The following stuff should not be touched

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Directories

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

ROOT = . SUBDIRS = lib kernel SRCDIR = $(ROOT) VPATH = $(SRCDIR) BINDIR = $(ROOT)

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Image file names and map, disassembly file

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

IMAGE BIN = $(IMAGENAME).bin IMAGE REC = $(IMAGENAME).rec IMAGE ELF = $(IMAGENAME).elf IMAGE MAP = $(IMAGENAME).map IMAGE DIS = $(IMAGENAME).dis

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

97

# Compiler toolchain

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

ifeq ($(TOOLCHAIN),mipsel) CC = mipsel−linux−gcc LD = mipsel−linux−ld OBJCOPY = mipsel−linux−objcopy OBJDUMP = mipsel−linux−objdump endif

ifeq ($(TOOLCHAIN),mips64) CC = mips64−linux−gcc LD = mips64−linux−ld OBJCOPY = mips64−linux−objcopy OBJDUMP = mips64−linux−objdump endif

ifeq ($(TOOLCHAIN),mips64el) CC = mips64el−linux−gcc LD = mips64el−linux−ld OBJCOPY = mips64el−linux−objcopy OBJDUMP = mips64el−linux−objdump endif

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Compiler and linker options

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

INCLUDE =−I$(ROOT)/include

W OPTS =−Wimplicit−Wformat−Wall−Wstrict−prototypes W OPTS A =−Wformat−Wall−Wstrict−prototypes

ifeq ($(ARCH),mipsel)

DEFS =

CC OPTS = endif

ifeq ($(ARCH),mips64)

DEFS =

CC OPTS =−g−Wa,−32−mcpu=r4600−mabi=64−mips3−G0−pipe\

−D$(ENDIAN)−fno−strict−aliasing−g−c−O2−nostdinc $(INCLUDE) $(DEFS) CC OPTS A = $(CC OPTS)

endif

LD SCRIPT = $(ROOT)/kernel/$(ARCH)/link.xn

LD OPTS =−g−G 0−static−T $(LD SCRIPT)−o $(IMAGE ELF)\

−Map $(IMAGE MAP) ifeq ($(TOOLCHAIN),mips64) LD FORMAT = elf64−bigmips endif

ifeq ($(TOOLCHAIN),mips64el) LD FORMAT = elf64−littlemips endif

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Files to be compiled

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

OBJ = kernel/start.o \ kernel/mipsirq.o \ kernel/stack.o \ kernel/kernel .o \ kernel/ serial .o \ kernel/lcd.o \ kernel/setjmp.o \ kernel/cpu.o \ kernel/ list .o \ kernel/timer.o \ kernel/interrupt .o\ kernel/process.o \ kernel/sched.o \ kernel/semaphore.o\ kernel/panic.o \ kernel/test1 .o \ kernel/test2 .o \ lib /vsprintf .o

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

# Rules

#∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

%.o : %.c

$(CC) $(W OPTS) $(CC OPTS)−o $@ $<

%.o : %.S

$(CC) $(W OPTS A) $(CC OPTS A)−o $@ $<

all : prepare $(IMAGE BIN) $(IMAGE REC) $(IMAGE DIS) prepare:

rm−f include/arch

ln−s $(ARCH) include/arch rm−f kernel/arch

ln−s $(ARCH) kernel/arch

$(IMAGE BIN) : $(IMAGE ELF)

$(OBJCOPY)−O binary $(IMAGE ELF) $(IMAGE BIN)

$(IMAGE REC) : $(IMAGE ELF)

$(OBJCOPY)−O srec $(IMAGE ELF) $(IMAGE REC)

$(IMAGE DIS) : $(IMAGE ELF)

$(OBJDUMP)−S $(IMAGE ELF)>$(IMAGE DIS)

$(IMAGE ELF) : $(OBJ)

$(LD) $(LD OPTS) $(OBJ)

$(OBJCOPY)−O $(LD FORMAT)−−change−addresses=0xffffffff00000000\

$(IMAGE ELF) $(IMAGE ELF) install : $(IMAGE REC)

cp $(IMAGE REC) $(TFTPDIR) clean :

rm−f $(OBJ) $(IMAGE BIN) $(IMAGE REC) $(IMAGE DIS)

99

rm−f $(IMAGE ELF) $(IMAGE MAP) realclean : clean

rm−f include/arch rm−f kernel/arch

find .−name ’∗˜’|xargs rm−f

find .−name ’semantic.cache∗’|xargs rm−f

: kernel/mips64/link.xn

/∗

Linker script for the kernel . Created for the 64bit mips

big endian achitecture . Since the linker sucks at 64bit elf

we link in 32bit elf and then change it afterwards with objcopy.

∗/

OUTPUT(kernel.elf) /∗Default output name ∗/

OUTPUT ARCH(mips) /∗Output arch is mips ... no shit :−) ∗/

ENTRY( start) /∗Entry point of kernel ∗/

SECTIONS {

/∗∗∗∗Code and read−only data∗∗∗∗/

. = 0x80200000; /∗Here the code should be loaded so we∗/

/∗set the location counter to this ∗/

/∗address. ∗/

. text . :{

ftext = .; /∗Start of code and read−only data ∗/

kernel/start .o (. text) /∗This must be the first file since ∗/

/∗this has the kernel entry point ∗/

∗(. text) /∗The rest of the object files ∗/

ecode = .; /∗End of code ∗/

∗(.rodata) . = ALIGN(8);

etext = .; /∗End of code and read−only data ∗/

}= 0

/∗∗∗∗ Initialised data∗∗∗∗/

.data : {

fdata = .; /∗Start of initialised data ∗/

∗(.data)

. = ALIGN(8);

∗(. lit8 ) /∗Place 8−byte constants here ∗/

∗(. lit4 ) /∗Place 4−byte constants here ∗/

∗(.sdata) /∗Place subsequent data ∗/

. = ALIGN(8);

edata = .; /∗End of initialised data ∗/

}

/∗∗∗∗ Uninitialised data∗∗∗∗/

fbss = .; /∗Start of uninitialised data ∗/

. sbss : {

∗(.dynsbss)

∗(. sbss)

∗(. sbss .∗)

∗(.scommon) /∗Place small common symbols here ∗/

} .bss : {

∗(.dynbss)

∗(.bss)

∗(.bss.∗)

∗(COMMON) /∗Place common symbols here ∗/

sp end = .;

/∗Allocate room for stack∗/

. = ALIGN(8) ; . += 0x100000 ;

sp = .16;

}

end = .; /∗End of unitialised data ∗/

/∗∗∗∗These must appear regardless of . ∗∗∗∗/

.gptab.sdata :{ ∗(. gptab.data)∗(.gptab.sdata)} .gptab.sbss :{ ∗(. gptab.bss )∗(. gptab.sbss)}

/∗Provide the symbols etext, edata and end if they are not defined

by the kernel . It in the ISO/ANSI C standard that these should

be defined.

∗/

PROVIDE(etext = etext);

PROVIDE(edata = .);

PROVIDE(end = .);

}

: include/addrspace.h

/∗

This header defines the address space stuff for the

Malta board e.g convertion macros and addresses.

Some of the macros has been taken from the Linux kernel

This file is subject to the terms and conditions of the GNU General

Public License . See the file ”COPYING” in the main directory of

this archive for more details .

∗/

#ifndef ADDRSPACE H

#define ADDRSPACE H

101

/∗When addressing a byte you have to byteswap the

address due to a bug in the Galileo chip when running

in big endian mode.

∗/

#ifdefEB

#defineswap8addr(addr) ((addr) ˆ 0x0000000000000003)

#else

#defineswap8addr(addr) addr

#endif

#defineMALTA GT PORT BASE (KSEG1ADDR(0x18000000)) /∗

Malta RTC−device addresses

∗/

#defineMALTA RTC ADR REG 0x70

#defineMALTA RTC DAT REG 0x71 /∗

TTY addresses

∗/

#defineTTYS0 0x3F8

#defineTTYS1 0x2F8 /∗

Memory segments (64bit kernel mode addresses)

∗/

#defineKUSEG 0x0000000000000000

#defineKSEG0 0 xffffffff80000000

#defineKSEG1 0 xffffffffa0000000

#defineKSEG2 0 xffffffffc0000000

#defineKSEG3 0 xffffffffe0000000 /∗

Returns the kernel segment base of a given address

∗/

#defineKSEGX(a) (((unsigned long)(a)) & 0xe0000000) /∗

Map an address to a certain kernel segment

∗/

#defineKSEG0ADDR(a) (( typeof (a))\

(((unsigned long)(a) & 0x000000ffffffffffUL)|KSEG0))

#defineKSEG1ADDR(a) (( typeof (a))\

(((unsigned long)(a) & 0x000000ffffffffffUL)|KSEG1))

#defineKSEG2ADDR(a) (( typeof (a))\

(((unsigned long)(a) & 0x000000ffffffffffUL)|KSEG2))

#defineKSEG3ADDR(a) (( typeof (a))\

(((unsigned long)(a) & 0x000000ffffffffffUL)|KSEG3)) /∗

Memory segments (64bit kernel mode addresses)

∗/

#defineXKUSEG 0x0000000000000000

#defineXKSSEG 0x4000000000000000

#defineXKPHYS 0x8000000000000000

#defineXKSEG 0xc000000000000000

#defineCKSEG0 0 xffffffff80000000

#defineCKSEG1 0 xffffffffa0000000

#defineCKSSEG 0 xffffffffc0000000

#defineCKSEG3 0 xffffffffe0000000 /∗

Memory segments sizes

∗/

#defineKUSIZE 0x0000010000000000 /∗2ˆˆ40∗/

#defineKUSIZE 64 0x0000010000000000 /∗2ˆˆ40∗/

#defineK0SIZE 0x0000001000000000 /∗2ˆˆ36∗/

#defineK1SIZE 0x0000001000000000 /∗2ˆˆ36∗/

#defineK2SIZE 0x000000ff80000000

#defineKSEGSIZE 0x000000ff80000000 /∗max syssegsz∗/

#endif/∗ ADDRSPACE H∗/

: include/asm.h

/∗

Some useful macros for MIPS assembler code

This file is subject to the terms and conditions of the GNU General

Public License . See the file ”COPYING” in the main directory of

this archive for more details .

∗/

#ifndef ASM H

#define ASM H /∗

LEAFdeclare leaf routine

∗/

#defineLEAF(symbol) \

. globl symbol; \

. align 2; \

.type symbol,@function; \

.ent symbol,0; \

symbol: .frame sp ,0, ra /∗

NESTEDdeclare nested routine entry point

∗/

#defineNESTED(symbol, framesize, rpc) \

. globl symbol; \

. align 2; \

.type symbol,@function; \

.ent symbol,0; \

symbol: .frame sp , framesize , rpc /∗

ENDmark end of function

∗/

#defineEND(function) \

.end function; \

. size function,.−function

103

/∗

EXPORTexport definition of symbol

∗/

#defineEXPORT(symbol) \

. globl symbol; \

symbol:

/∗

Print formated string

∗/

#definePROM PRINT(string) \

. set push; \

. set reorder ; \

la a0,8f ; \

jal serial print ; \

. set pop; \

TEXT(string)

#defineTEXT(msg) \

.data; \

8: . asciiz msg; \

.previous;

#endif/∗ ASM H∗/

: include/byteorder.h

/∗$Id : byteorder.h,v 1.1.1.1 2001/09/23 15:00:00 lmc Exp $

This file is subject to the terms and conditions of the GNU General Public

License . See the file ”COPYING” in the main directory of this archive

for more details .

Copyright (C) 1996, 1999 by Ralf Baechle

∗/

#ifndef ASM BYTEORDER H

#define ASM BYTEORDER H

#include<asm/types.h>

#ifdef GNUC

#if!defined( STRICT ANSI )||defined( KERNEL )

# define BYTEORDER HAS U64

#endif

#endif/∗ GNUC ∗/

#ifdefined ( MIPSEB )

# include<linux/byteorder/big endian.h>

#elifdefined ( MIPSEL )

# include<linux/byteorder/little endian.h>

#else

# error”MIPS, but neither MIPSEB , nor MIPSEL ???”

#endif

#endif/∗ ASM BYTEORDER H∗/

: include/cpu.h

/∗

CPU functions

This file is subject to the terms and conditions of the GNU General

Public License . See the file ”COPYING” in the main directory of

this archive for more details .

∗/

#ifndef CPU H

#define CPU H /∗

Assigned values for the product ID register . In order to detect a

certain CPU type exactly eventually additional registers may need to

be examined.

∗/

#definePRID IMP R2000 0x0100

#definePRID IMP R3000 0x0200 /∗Same as R2000A∗/

#definePRID IMP R6000 0x0300 /∗Same as R3000A∗/

#definePRID IMP R4000 0x0400

#definePRID IMP R6000A 0x0600

#definePRID IMP R10000 0x0900

#definePRID IMP R12000 0x0e00

#definePRID IMP R4300 0x0b00

#definePRID IMP R12000 0x0e00

#definePRID IMP R8000 0x1000

#definePRID IMP R4600 0x2000

#definePRID IMP R4700 0x2100

#definePRID IMP R4640 0x2200

#definePRID IMP R4650 0x2200 /∗Same as R4640∗/

#definePRID IMP R5000 0x2300

#definePRID IMP SONIC 0x2400

#definePRID IMP MAGIC 0x2500

#definePRID IMP RM7000 0x2700

#definePRID IMP NEVADA 0x2800

#definePRID IMP 5KC 0x8100

#definePRID IMP 20KC 0x8200 voidcpu init(void);

voidcpu status(void);

voidcpu probe(void);

voidcpu speed(void);

#endif/∗ CPU H∗/

: include/interrupt.h

/∗

Interrupt functions

This file is subject to the terms and conditions of the GNU General

Public License . See the file ”COPYING” in the main directory of

this archive for more details .

∗/

105

#ifndef INTERRUPT H

#define INTERRUPT H

#include<regoffset.h>

extern intinterrupt nested;

typedef void(∗interrupt handler)(void);

void interrupt register (int irq , interrupt handler handler);

voidinterrupt hw( reg offset∗regs );

//voidinterrupt timer(struct reg offset ∗regs );

void interrupt init (void);

#endif/∗ INTERRUPT H∗/

: include/kernel.h

/∗

Kernel header. Global kernel stuff

This file is subject to the terms and conditions of the GNU General

Public License . See the file ”COPYING” in the main directory of

this archive for more details .

∗/

#ifndef KERNEL H

#define KERNEL H voidpanic(char∗buf);

#endif/∗ KERNEL H∗/

: include/lcd.h

/∗

LCD Display driver header

This file is subject to the terms and conditions of the GNU General

Public License . See the file ”COPYING” in the main directory of

this archive for more details .

∗/

#ifndef LCD H

#define LCD H

voidlcd int (unsigned intnum);

voidlcd message(const char∗str);

#endif/∗ LCD H∗/

: include/list.h

/∗

Double non−circular linked list functions

This file is subject to the terms and conditions of the GNU General

Public License . See the file ”COPYING” in the main directory of

this archive for more details .

∗/

#ifndef LIST H

#define LIST H

#include<stddef.h>

/∗The StructOffset macro returns the byte offset of the field ” field ”

in the structure ”st”

∗/

#defineStructOffset(st, field )\ ((long) &(((st∗)0)−>field))

/∗The StructBase returns a pointer to the structure of type ”st”

where ”ptr” is pointing to the filed ” field ” in that structure .

∗/

#defineStructBase(ptr, st, field )\

(( st∗) (((unsigned char∗)(ptr))StructOffset(st, field))) typedef structs list element{

struct s list elementpNext;

struct s list elementpPrev;

} t list element ; typedef struct{

int number;

t list element pFirst ; t list element pLast;

} t list head ;

#definelist empty(pHead) ((int)((pHead)−>pFirst == NULL)) void list init ( t list headpHead);

voidlist put ( t list head pHead, t list elementpElement);

void list put after ( t list head pHead, t list elementpElement1, t list elementpElement2);

void list put before ( t list head pHead, t list elementpElement1, t list elementpElement2);

t list element list get ( t list headpHead);

voidlist remove( t list head pHead, t list elementpElement);

int list length ( t list head pHead);

107

#endif/∗ LIST H∗/

: include/mipsregs.h

/∗

MIPS registers

This file is subject to the terms and conditions of the GNU General

Public License . See the file ”COPYING” in the main directory of

this archive for more details .

∗/

#ifndef MIPSREGS H

#define MIPSREGS H /∗

The following macros are especially useful for asm

inline assembler.

∗/

#ifndef STR

#define STR(x) #x

#endif

#ifndefSTR

#defineSTR(x) STR(x)

#endif /∗

Coprocessor 0 control register names

∗/

#defineCP0 INDEX $0

#defineCP0 RANDOM $1

#defineCP0 ENTRYLO0 $2

#defineCP0 ENTRYLO1 $3

#defineCP0 CONTEXT $4

#defineCP0 PAGEMASK $5

#defineCP0 WIRED $6

#defineCP0 BADVADDR $8

#defineCP0 COUNT $9

#defineCP0 ENTRYHI $10

#defineCP0 COMPARE $11

#defineCP0 STATUS $12

#defineCP0 CAUSE $13

#defineCP0 EPC $14

#defineCP0 PRID $15

#defineCP0 CONFIG $16

#defineCP0 LLADDR $17

#defineCP0 WATCHLO $18

#defineCP0 WATCHHI $19

#defineCP0 XCONTEXT $20

#defineCP0 FRAMEMASK $21

#defineCP0 DIAGNOSTIC $22

#defineCP0 PERFORMANCE $25

#defineCP0 ECC $26

#defineCP0 CACHEERR $27

#defineCP0 TAGLO $28

#defineCP0 TAGHI $29

#defineCP0 ERROREPC $30

#defineCP0 DESAVE $31

/∗

Macros to access the system control coprocessor

∗/

#defineread 32bit cp0 register(source) \

({int res ; \

asm volatile ( \

”mfc0\t%0,”STR(source) \

: ”=r” ( res )); \

res ;})

#definewrite 32bit cp0 register(register,value) \

asm volatile ( \

”mtc0\t%0,”STR(register) \

: : ”r” (value ));

/∗

R4x00 interrupt enable / cause bits

∗/

#defineIE SW0 (1<<8)

#defineIE SW1 (1<<9)

#defineIE IRQ0 (1<<10)

#defineIE IRQ1 (1<<11)

#defineIE IRQ2 (1<<12)

#defineIE IRQ3 (1<<13)

#defineIE IRQ4 (1<<14)

#defineIE IRQ5 (1<<15) /∗

R4x00 interrupt cause bits

∗/

#defineC SW0 (1<<8)

#defineC SW1 (1<<9)

#defineC IRQ0 (1<<10)

#defineC IRQ1 (1<<11)

#defineC IRQ2 (1<<12)

#defineC IRQ3 (1<<13)

#defineC IRQ4 (1<<14)

#defineC IRQ5 (1<<15)

#ifndef LANGUAGE ASSEMBLY /∗

Manipulate the status register .

Mostly used to access the interrupt bits .

∗/

#define BUILD SET CP0(name,register) \

extern inline unsigned int \

set cp0 ##name(unsigned intchange,unsigned intnew) \

{ \

unsigned intres; \

\ res = read 32bit cp0 register (register); \

res &= ˜change; \

res|= (new & change); \

write 32bit cp0 register (register, res ); \

\

returnres; \

}

109

BUILD SET CP0(status,CP0 STATUS) BUILD SET CP0(cause,CP0 CAUSE) BUILD SET CP0(config,CP0 CONFIG)

#endif/∗defined ( LANGUAGE ASSEMBLY)∗/

/∗

Bitfields in the R4xx0 cp0 status register

∗/

#defineST0 IE 0x00000001

#defineST0 EXL 0x00000002

#defineST0 ERL 0x00000004

#defineST0 KSU 0x00000018

# defineKSU USER 0x00000010

# defineKSU SUPERVISOR 0x00000008

# defineKSU KERNEL 0x00000000

#defineST0 UX 0x00000020

#defineST0 SX 0x00000040

#defineST0 KX 0x00000080

#defineST0 DE 0x00010000

#defineST0 CE 0x00020000 /∗

Status register bits available in all MIPS CPUs.

∗/

#defineST0 IM 0x0000ff00

#defineSTATUSB IP0 8

#defineSTATUSF IP0 (1 <<8)

#defineSTATUSB IP1 9

#defineSTATUSF IP1 (1 <<9)

#defineSTATUSB IP2 10

#defineSTATUSF IP2 (1 <<10)

#defineSTATUSB IP3 11

#defineSTATUSF IP3 (1 <<11)

#defineSTATUSB IP4 12

#defineSTATUSF IP4 (1 <<12)

#defineSTATUSB IP5 13

#defineSTATUSF IP5 (1 <<13)

#defineSTATUSB IP6 14

#defineSTATUSF IP6 (1 <<14)

#defineSTATUSB IP7 15

#defineSTATUSF IP7 (1 <<15)

#defineST0 CH 0x00040000

#defineST0 SR 0x00100000

#defineST0 TS 0x00200000

#defineST0 BEV 0x00400000

#defineST0 RE 0x02000000

#defineST0 FR 0x04000000

#defineST0 CU 0xf0000000

#defineST0 CU0 0x10000000

#defineST0 CU1 0x20000000

#defineST0 CU2 0x40000000

#defineST0 CU3 0x80000000

#defineST0 XX 0x80000000 /∗MIPS IV naming∗/

/∗

Bitfields and bit numbers in the coprocessor 0 cause register .

Refer to your MIPS R4xx0 manual, chapter 5 for explanation.

∗/

#defineCAUSEB EXCCODE 2

#defineCAUSEF EXCCODE (31 <<2)

#defineCAUSEB IP 8

#defineCAUSEF IP (255<<8)

#defineCAUSEB IP0 8

#defineCAUSEF IP0 (1 <<8)

#defineCAUSEB IP1 9

#defineCAUSEF IP1 (1 <<9)

#defineCAUSEB IP2 10

#defineCAUSEF IP2 (1 <<10)

#defineCAUSEB IP3 11

#defineCAUSEF IP3 (1 <<11)

#defineCAUSEB IP4 12

#defineCAUSEF IP4 (1 <<12)

#defineCAUSEB IP5 13

#defineCAUSEF IP5 (1 <<13)

#defineCAUSEB IP6 14

#defineCAUSEF IP6 (1 <<14)

#defineCAUSEB IP7 15

#defineCAUSEF IP7 (1 <<15)

#defineCAUSEB IV 23

#defineCAUSEF IV (1 <<23)

#defineCAUSEB CE 28

#defineCAUSEF CE (3 <<28)

#defineCAUSEB BD 31

#defineCAUSEF BD (1 <<31) /∗

Bits in the coprozessor 0 config register .

∗/

#defineCONF CM CACHABLE NO WA 0

#defineCONF CM CACHABLE WA 1

#defineCONF CM UNCACHED 2

#defineCONF CM CACHABLE NONCOHERENT 3

#defineCONF CM CACHABLE CE 4

#defineCONF CM CACHABLE COW 5

#defineCONF CM CACHABLE CUW 6

#defineCONF CM CACHABLE ACCELERATED 7

#defineCONF CM CMASK 7

#defineCONF DB (1<<4)

#defineCONF IB (1<<5)

#defineCONF SC (1<<17) /∗

Events counted by counter #0

∗/

#defineCE0 CYCLES 0

#defineCE0 INSN ISSUED 1

#defineCE0 LPSC ISSUED 2

#defineCE0 S ISSUED 3

#defineCE0 SC ISSUED 4

#defineCE0 SC FAILED 5

#defineCE0 BRANCH DECODED 6

#defineCE0 QW WB SECONDARY 7

#defineCE0 CORRECTED ECC ERRORS 8

#defineCE0 ICACHE MISSES 9

111

#defineCE0 SCACHE I MISSES 10

#defineCE0 SCACHE I WAY MISSPREDICTED 11

#defineCE0 EXT INTERVENTIONS REQ 12

#defineCE0 EXT INVALIDATE REQ 13

#defineCE0 VIRTUAL COHERENCY COND 14

#defineCE0 INSN GRADUATED 15 /∗

Events counted by counter #1

∗/

#defineCE1 CYCLES 0

#defineCE1 INSN GRADUATED 1

#defineCE1 LPSC GRADUATED 2

#defineCE1 S GRADUATED 3

#defineCE1 SC GRADUATED 4

#defineCE1 FP INSN GRADUATED 5

#defineCE1 QW WB PRIMARY 6

#defineCE1 TLB REFILL 7

#defineCE1 BRANCH MISSPREDICTED 8

#defineCE1 DCACHE MISS 9

#defineCE1 SCACHE D MISSES 10

#defineCE1 SCACHE D WAY MISSPREDICTED 11

#defineCE1 EXT INTERVENTION HITS 12

#defineCE1 EXT INVALIDATE REQ 13

#defineCE1 SP HINT TO CEXCL SC BLOCKS 14

#defineCE1 SP HINT TO SHARED SC BLOCKS 15 /∗

These flags define in which priviledge mode the counters count events

∗/

#defineCEB USER 8 /∗Count events in user mode, EXL = ERL = 0∗/

#defineCEB SUPERVISOR 4 /∗Count events in supvervisor mode EXL = ERL = 0∗/

#defineCEB KERNEL 2 /∗Count events in kernel mode EXL = ERL = 0∗/

#defineCEB EXL 1 /∗Count events with EXL = 1, ERL = 0∗/

#endif/∗ MIPSREGS H∗/

: include/piix4.h

/∗

Carsten Langgaard, carstenl@mips.com

Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved .

This program is free software ; you can distribute it and/or modify it

under the terms of the GNU General Public License (Version 2) as

published by the Free Software Foundation.

This program is distributed in the hope it will be useful , but WITHOUT

ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License

for more details .

You should have received a copy of the GNU General Public License along

with this program; if not, write to the Free Software Foundation, Inc.,

59 Temple PlaceSuite 330, Boston MA 02111−1307, USA.

Register definitions for Intel PIIX4 South Bridge Device.

In document AN EMBEDDED SYSTEMS KERNEL (Sider 97-184)