diff --git a/src/arch/alpha/config/crt0.base b/src/arch/alpha/config/crt0.base new file mode 100644 index 0000000000..6c41c1e0a2 --- /dev/null +++ b/src/arch/alpha/config/crt0.base @@ -0,0 +1,146 @@ +/* + * $ $ + * + */ + +.set noat +.set noreorder +.text + +#include + +#if USE_CPU_EV4 +#include +#elif USE_CPU_EV5 +#include +#elif USE_CPU_EV6 +#include +#else +#error Uknown alpha cpu type +#endif + + /* __fatal_error_pal Called with: + * a0 - Exception handler address that caught the exception + * a1 - Address where the exception occured. + * a2 - Potentially valid return address from the code + * that took the exception. + */ + FETCH_BLOCK_ALIGN +__fatal_error_non_pal: + /* Resetup the global pointers */ + ldgp gp, 0(pv) + lda sp, _estack + /* Display an error message */ + jsr ra, fatal_error + br zero, .-4 + + /* On entry to kernel_mode_start. + * a0 - Signature (0xDEC?????) likely (0xDECB001) + * a1 - Memory size in bytes + * a2 - Cpu speed in picoseconds + * + * These parameters should be available on the 164 & the 264. + */ + FETCH_BLOCK_ALIGN +kernel_mode_start: + /* Setup the global pointers */ + ldgp gp, 0(pv) + lda sp, _estack + + /* Zero the Bss */ + lda t1, _bss + lda t2, _ebss + subq t2, t1, t2 + br Zstart +Zero: subq t2, 8, t2 + stq zero, 0(t1) +Zstart: bne t2, Zero + + + /* Test for the srom valid signature */ + lda t1, 0xDEC(zero) + srl a0, 20, t2 + cmpeq t1, t2, t3 + beq t3, 1f + + /* Compute the number of cpu clocks per bit out to the srom + * debug port. + */ + bis a2, a2, t11 + ldq t10, picosecs_per_srom_clock + jsr t9, __divq + lda t11, srom_wait_reps + stq t12, 0(t11) + +1: + /* Jump to main */ + jsr ra, hardwaremain + br zero, .-4 /* spin in place */ + + + .p2align 3 +picosecs_per_srom_clock: + .quad 104166666 /* Pico seconds per tick of a 9600Hz clock */ +srom_wait_reps: + .quad 0 /* 48562 on a 466Mhz EV6 */ + + /* Wait bit time is private and should not be called from C */ + FETCH_BLOCK_ALIGN +wait_bit_time: +#if USE_CPU_EV6 + lda t8, 0x1(zero) + sll t8, 32, t8 /* t8 = 1.0000.0000 */ + hw_mtpr t8, EV6__CC_CTL /* clear cycle count */ + bis zero,zero,zero /* nop */ + bis zero,zero,zero /* nop */ + bis zero,zero,zero /* nop */ + hw_mtpr zero, (EV6__EXC_ADDR+32) /* dummy IPR write - sets SCBD bit 5 (to stall untill cc_ctl gets written) */ +#else + hw_mtpr t8, ccCtl /* clear cycle count */ + STALL /* wait 3 cycles to avoid palcode */ + STALL /* violation */ + STALL + STALL +#endif +wait: /* REPEAT */ + rpcc t8 /* : read the cycle count */ + zapnot t8, 0x0f, t8 /* : clear the high longword */ + cmplt t12, t8, t8 /* : */ + beq t8, wait /* UNTIL we have waited time specified */ + ret zero, (t10) + +GLOBL(srom_tx_byte) + /* Initialze routine variables */ + ldgp gp, 0(pv) + ldq t12, (srom_wait_reps - srom_tx_byte)(pv) + lda t11, 16(zero) /* 1 high + 1 start + 8 data + */ + /* 6 stop (5 extra for delay). */ + lda a0, 0x3F00(a0) /* add stop bits at the end and */ + s4addq a0, 1, a0 /* then add start and high bit */ + +#if USE_CPU_EV6 + FETCH_BLOCK_ALIGN /* align with nop instructions */ +data_bit: /* REPEAT */ + hw_mfpr t9, EV6__I_CTL /* get current I_CTL value */ + lda t8, 0x1(zero) /* t8 - mask for sl_xmit bit */ + sll t8, EV6__I_CTL__SL_XMIT__S, t8 /* move to the correct position */ + bic t9, t8, t9 /* clear sl_xmit bit in old I_CTL value */ + blbc a0, send_bit /* check the new sl_xmit bit */ + bis t9, t8, t9 /* set sl_xmit bit in old I_CTL value */ +send_bit: /* continue */ + hw_mtpr t9, EV6__I_CTL /* EV6 Send the data bit */ +#else + sll a0, (SLXMIT_V_TMT), a0 /* Put bits into position */ +data_bit: /* REPEAT */ + hw_mtpr a0, slXmit /* EV5 Send the first bit */ +#endif + srl a0, 1, a0 /* Shift right, to the next bit. */ + subq t11, 1, t11 /* Decrement the bit count. */ + + bsr t10, wait_bit_time /* Wait for a bit time */ + bne t11, data_bit /* UNTIL all data sent */ + ret zero, (ra) + + + + diff --git a/src/arch/alpha/config/ldscript.base b/src/arch/alpha/config/ldscript.base new file mode 100644 index 0000000000..cf453451b7 --- /dev/null +++ b/src/arch/alpha/config/ldscript.base @@ -0,0 +1,100 @@ +OUTPUT_FORMAT("elf64-alpha") +ENTRY(__start_offset) +PHDRS { kernel PT_LOAD AT(0x310000); } +__start_offset = start + 0x310000; +SECTIONS +{ + . = _ROMBASE; + /* + * First we place the code and read only data (typically const declared). + * This get placed in rom. + */ + .text : { + _text = .; + *(.text) + _etext = .; + } : kernel + .rodata : { + _rodata = .; + *(.rodata); + _erodata = .; + } : kernel + + . = _RAMBASE; + /* Global data */ + .data : { + _data = .; + *(.data.cacheline_aligned) + *(.data) CONSTRUCTORS + *(.got) + *(.sdata) + _edata = .; + } + _ldata = LOADADDR(.data); + _eldata = LOADADDR(.data) + SIZEOF(.data); + + + /* Important align _bss so bss may be zeroed with quadword access */ + . = ALIGN(8); + .bss : { + _bss = .; + *(.sbss) + *(.scommon) + *(.bss) + *(COMMON) + /* Important align _ebss so bss may be zeroed with quadword access */ + . = ALIGN(8); + _ebss = .; + } + _end = .; + + /* Align the heap to a quadword boundary */ + . = ALIGN(8); + .heap : { + _heap = .; + /* Reserve a meg for the heap */ + . = . + 1024*1024; + . = ALIGN(8); + _eheap = .; + } + . = ALIGN(8); + .stack : { + _stack = .; + /* Allocate an 8k stack that grows backwards into the heap */ + . = . + 8192; + . = ALIGN(8); + _estack = .; + } + + /DISCARD/ : { + /* Comment sections */ + *(.mdebug) + *(.note) + *(.comment) + /* DWARF 1 */ + *(.debug) + *(.line) + /* GNU DWARF 1 extensions */ + *(.debug_srcinfo) + *(.debug_sfnames) + /* DWARF 1.1 and DWARF 2 */ + *(.debug_aranges) + *(.debug_pubnames) + /* DWARF 2 */ + *(.debug_info) + *(.debug_abbrev) + *(.debug_line) + *(.debug_frame) + *(.debug_str) + *(.debug_loc) + *(.debug_macinfo) + /* SGI/MIPS DWARF 2 extensions */ + *(.debug_weaknames) + *(.debug_funcnames) + *(.debug_typenames) + *(.debug_varnames) + /* Kernel module cleanup sections */ + *(.text.exit) + *(.data.exit) + } +} diff --git a/src/arch/alpha/config/make.base b/src/arch/alpha/config/make.base new file mode 100644 index 0000000000..9938aad155 --- /dev/null +++ b/src/arch/alpha/config/make.base @@ -0,0 +1,35 @@ +biosbase 0 +rambase 0x10000 +makedefine LINK = ld -T ldscript.ld -o $@ crt0.o linuxbios.a +makedefine CPPFLAGS= -I$(TOP)/src/include -I$(TOP)/src/arch/$(ARCH)/include $(CPUFLAGS) +makedefine CFLAGS= $(CPU_OPT) $(CPPFLAGS) -O2 -nostdinc -nostdlib -fno-builtin -Wall +makedefine CC=cc +makerule all : linuxbios.rom ; +makerule linuxbios.rom: linuxbios.strip makerom ; ./makerom -l0x310000 -i7 -v linuxbios.strip -o linuxbios.rom +makerule linuxbios.strip: linuxbios ; objcopy -O binary -R .note -R .comment -S linuxbios linuxbios.strip +makerule linuxbios: linuxbios.a ; @rm -f biosobject +addaction linuxbios $(LINK) +addaction linuxbios nm -n linuxbios > linuxbios.map + +makerule linuxbios.a : $(OBJECTS) ; rm -f linuxbios.a +addaction linuxbios.a ar cr linuxbios.a $(OBJECTS) + +makerule crt0.s: crt0.S ; $(CC) $(CPPFLAGS) -I$(TOP)/src -E $< > crt0.s + +makerule crt0.o : crt0.s; $(CC) $(CPU_OPT) -c crt0.s +#makerule makerom: $(TOP)/util/makerom/makerom.c $(TOP)/util/makerom/compress.c ; $(CC) -o makerom $(TOP)/util/makerom/makerom.c $(TOP)/util/makerom/compress.c + +makerule clean : ; rm -f linuxbios.* *.o mkrom xa? *~ +addaction clean rm -f linuxbios crt0.s +addaction clean rm -f a.out *.s *.l +addaction clean rm -f TAGS tags +addaction clean rm -f docipl + + +# do standard config files that the user need not specify +# for now, this is just 'lib', but it may be more later. +dir /src/arch/alpha +dir /src/lib +dir /src/boot +dir /src/rom +dir /util/makerom diff --git a/src/arch/alpha/include/arch/asm.h b/src/arch/alpha/include/arch/asm.h new file mode 100644 index 0000000000..3c686059aa --- /dev/null +++ b/src/arch/alpha/include/arch/asm.h @@ -0,0 +1,18 @@ +#ifndef ALPHA_ARCH_ASM_H +#define ALPHA_ARCH_ASM_H + +/* assembly language utility macros */ + +/* Load immediate signed constants */ +#define LOAD_CONSTANT16(reg, constant) \ + lda reg, (constant)(zero) + +#define LOAD_CONSTANT32(reg, constant) \ + ldah reg, ((constant + 0x8000) >> 16)(zero) ; \ + lda reg, (constant & 0xffff)(reg) + +/* Declare a global symbol */ +#define GLOBL(label) .globl label ; label: + + +#endif /* ALPHA_ARCH_ASM_H */ diff --git a/src/arch/alpha/include/arch/compiler.h b/src/arch/alpha/include/arch/compiler.h new file mode 100644 index 0000000000..e7d37a8a1d --- /dev/null +++ b/src/arch/alpha/include/arch/compiler.h @@ -0,0 +1,84 @@ +#ifndef ALPHA_COMPILER_H +#define ALPHA_COMPILER_H + +/* + * Herein are macros we use when describing various patterns we want to GCC. + * In all cases we can get better schedules out of the compiler if we hide + * as little as possible inside inline assembly. However, we want to be + * able to know what we'll get out before giving up inline assembly. Thus + * these tests and macros. + */ + +#if 0 +#define __kernel_insbl(val, shift) \ + (((unsigned long)(val) & 0xfful) << ((shift) * 8)) +#define __kernel_inswl(val, shift) \ + (((unsigned long)(val) & 0xfffful) << ((shift) * 8)) +#define __kernel_insql(val, shift) \ + ((unsigned long)(val) << ((shift) * 8)) +#else +#define __kernel_insbl(val, shift) \ + ({ unsigned long __kir; \ + __asm__("insbl %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val)); \ + __kir; }) +#define __kernel_inswl(val, shift) \ + ({ unsigned long __kir; \ + __asm__("inswl %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val)); \ + __kir; }) +#define __kernel_insql(val, shift) \ + ({ unsigned long __kir; \ + __asm__("insql %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val)); \ + __kir; }) +#endif + +#if 0 && (__GNUC__ > 2 || __GNUC_MINOR__ >= 92) +#define __kernel_extbl(val, shift) (((val) >> (((shift) & 7) * 8)) & 0xfful) +#define __kernel_extwl(val, shift) (((val) >> (((shift) & 7) * 8)) & 0xfffful) +#else +#define __kernel_extbl(val, shift) \ + ({ unsigned long __kir; \ + __asm__("extbl %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val)); \ + __kir; }) +#define __kernel_extwl(val, shift) \ + ({ unsigned long __kir; \ + __asm__("extwl %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val)); \ + __kir; }) +#endif + + +/* + * Beginning with EGCS 1.1, GCC defines __alpha_bwx__ when the BWX + * extension is enabled. Previous versions did not define anything + * we could test during compilation -- too bad, so sad. + */ + +#if defined(__alpha_bwx__) +#define __kernel_ldbu(mem) (mem) +#define __kernel_ldwu(mem) (mem) +#define __kernel_stb(val,mem) ((mem) = (val)) +#define __kernel_stw(val,mem) ((mem) = (val)) +#else +#define __kernel_ldbu(mem) \ + ({ unsigned char __kir; \ + __asm__("ldbu %0,%1" : "=r"(__kir) : "m"(mem)); \ + __kir; }) +#define __kernel_ldwu(mem) \ + ({ unsigned short __kir; \ + __asm__("ldwu %0,%1" : "=r"(__kir) : "m"(mem)); \ + __kir; }) +#define __kernel_stb(val,mem) \ + __asm__("stb %1,%0" : "=m"(mem) : "r"(val)) +#define __kernel_stw(val,mem) \ + __asm__("stw %1,%0" : "=m"(mem) : "r"(val)) +#endif + +/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented + a mechanism by which the user can annotate likely branch directions and + expect the blocks to be reordered appropriately. Define __builtin_expect + to nothing for earlier compilers. */ + +#if __GNUC__ == 2 && __GNUC_MINOR__ < 96 +#define __builtin_expect(x, expected_value) (x) +#endif + +#endif /* ALPHA_COMPILER_H */ diff --git a/src/arch/alpha/include/arch/cpu.h b/src/arch/alpha/include/arch/cpu.h new file mode 100644 index 0000000000..bfbbe33593 --- /dev/null +++ b/src/arch/alpha/include/arch/cpu.h @@ -0,0 +1,64 @@ +#ifndef ALPHA_CPU_H +#define ALPHA_CPU_H + +/* Alpha Logical Register Definitions + * ========================================================= + */ + +/* Return value */ +#define v0 $0 +/* temporaries */ +#define t0 $1 +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define t6 $7 +#define t7 $8 +#define t8 $22 +#define t9 $23 +#define t10 $24 +#define t11 $25 +#define t12 $27 +/* Saved registers */ +#define s0 $9 +#define s1 $10 +#define s2 $11 +#define s3 $12 +#define s4 $13 +#define s5 $14 +#define s6 $15 +/* Frame pointer */ +#define fp $15 +/* Argument registers */ +#define a0 $16 +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 +/* return address */ +#define ra $26 +/* Procedure value */ +#define pv $27 +/* Assember temporary */ +#define at $28 +/* Global pointer */ +#define gp $29 +/* Stack Pointer */ +#define sp $30 +/* zero */ +#define zero $31 + +#if USE_CPU_EV4 +#include +#elif USE_CPU_EV5 +#include +#elif USE_CPU_EV6 +#include +#else +#error Uknown alpha cpu type +#endif + +#endif /* ALPHA_CPU_H */ diff --git a/src/arch/alpha/include/arch/io.h b/src/arch/alpha/include/arch/io.h new file mode 100644 index 0000000000..83f5f0a170 --- /dev/null +++ b/src/arch/alpha/include/arch/io.h @@ -0,0 +1,29 @@ +#ifndef ALPHA_IO_H +#define ALPHA_IO_H + +#include + +#define mb() \ +__asm__ __volatile__("mb": : :"memory") + +#define rmb() \ +__asm__ __volatile__("mb": : :"memory") + +#define wmb() \ +__asm__ __volatile__("wmb": : :"memory") + +/* + * Virtual -> physical identity mapping starts at this offset + */ +#ifdef USE_48_BIT_KSEG +#define IDENT_ADDR 0xffff800000000000 +#else +#define IDENT_ADDR 0xfffffc0000000000 +#endif + +#if defined(USE_CORE_TSUNAMI) +#include +#else +#error "What system is this?" +#endif +#endif /* ALPHA_IO_H */ diff --git a/src/arch/alpha/include/arch/pal.h b/src/arch/alpha/include/arch/pal.h new file mode 100644 index 0000000000..510d13326d --- /dev/null +++ b/src/arch/alpha/include/arch/pal.h @@ -0,0 +1,51 @@ +#ifndef __ALPHA_PAL_H +#define __ALPHA_PAL_H + +/* + * Common PAL-code + */ +#define PAL_halt 0 +#define PAL_cflush 1 +#define PAL_draina 2 +#define PAL_bpt 128 +#define PAL_bugchk 129 +#define PAL_chmk 131 +#define PAL_callsys 131 +#define PAL_imb 134 +#define PAL_rduniq 158 +#define PAL_wruniq 159 +#define PAL_gentrap 170 +#define PAL_nphalt 190 + +/* + * VMS specific PAL-code + */ +#define PAL_swppal 10 +#define PAL_mfpr_vptb 41 + +/* + * OSF specific PAL-code + */ +#define PAL_cserve 9 +#define PAL_wripir 13 +#define PAL_rdmces 16 +#define PAL_wrmces 17 +#define PAL_wrfen 43 +#define PAL_wrvptptr 45 +#define PAL_jtopal 46 +#define PAL_swpctx 48 +#define PAL_wrval 49 +#define PAL_rdval 50 +#define PAL_tbi 51 +#define PAL_wrent 52 +#define PAL_swpipl 53 +#define PAL_rdps 54 +#define PAL_wrkgp 55 +#define PAL_wrusp 56 +#define PAL_wrperfmon 57 +#define PAL_rdusp 58 +#define PAL_whami 60 +#define PAL_rtsys 61 +#define PAL_rti 63 + +#endif /* __ALPHA_PAL_H */