mirror of https://github.com/ipxe/ipxe.git
They can come back when they have someone to support them.
parent
a2b15fd1fe
commit
b2909e547d
|
@ -1,29 +0,0 @@
|
||||||
# Config for armnommu Etherboot
|
|
||||||
#
|
|
||||||
|
|
||||||
# For a clean compilation, switch in global Config
|
|
||||||
# off: -DCONFIG_PCI, -DTAGGED_IMAGE, -DELF_IMAGE, -DPXE*, -DRELOCATE and INCLUDE_FILO
|
|
||||||
# on : -DRAW_IMAGE
|
|
||||||
|
|
||||||
# Serial line settings
|
|
||||||
CFLAGS+= -DCONSOLE_SERIAL -DCONSPEED=57600
|
|
||||||
|
|
||||||
# System Frequency
|
|
||||||
CFLAGS+= -DSYSCLK=73728000
|
|
||||||
|
|
||||||
# Image Download Address
|
|
||||||
CFLAGS+= -DRAWADDR=0x40100000
|
|
||||||
|
|
||||||
# NIC Debug Outputs
|
|
||||||
#CFLAGS+= -DDEBUG_NIC
|
|
||||||
|
|
||||||
# Reduced Media Independent Interface
|
|
||||||
# MAZBR LPEC2001: MII (Intel LXT971ALE at 0..1)
|
|
||||||
# Elmeg D@VOS : RMII (Altima AC104-QF at 4..7)
|
|
||||||
# Telekom XI521 : RMII (Altima AC104-QF at 4..7)
|
|
||||||
#CFLAGS+= -DRMII
|
|
||||||
|
|
||||||
# Fixed MAC address
|
|
||||||
# p2001_eth has no flash and fixed mac address
|
|
||||||
#CFLAGS+= -DMAC_HW_ADDR_DRV="'H','Y','L','N','X','1'"
|
|
||||||
CFLAGS+= -DMAC_HW_ADDR_DRV="0x00,0x09,0x4F,0x00,0x00,0x02"
|
|
|
@ -1,58 +0,0 @@
|
||||||
ARCH_FORMAT= armnommu
|
|
||||||
|
|
||||||
ROMLIMIT= 20480
|
|
||||||
CHECKSIZE= { read d1; read d1 d2 d3 size d4; [ $$size -gt $(ROMLIMIT) ] &&\
|
|
||||||
{ $(RM) $@; echo "ERROR: code size exceeds limit!"; exit 1; }; exit 0; }
|
|
||||||
|
|
||||||
START= $(BIN)/start.o
|
|
||||||
|
|
||||||
SRCS+= arch/armnommu/core/arm_timer.c
|
|
||||||
SRCS+= arch/armnommu/core/start.S
|
|
||||||
SRCS+= arch/armnommu/core/serial.c
|
|
||||||
SRCS+= arch/armnommu/core/mem.c
|
|
||||||
SRCS+= arch/armnommu/core/setjmp.S
|
|
||||||
SRCS+= arch/armnommu/drivers/net/p2001_eth.c
|
|
||||||
|
|
||||||
# not greater than 100kB
|
|
||||||
ROMLIMIT:=1024000
|
|
||||||
|
|
||||||
include $(BIN)/Roms
|
|
||||||
|
|
||||||
ROMS= $(BIN)/p2001_eth.rom
|
|
||||||
IMGS= $(BIN)/p2001_eth.img
|
|
||||||
|
|
||||||
|
|
||||||
allfiles: $(ROMS)
|
|
||||||
|
|
||||||
BOBJS+= $(BIN)/arm_timer.o
|
|
||||||
BOBJS+= $(BIN)/serial.o
|
|
||||||
BOBJS+= $(BIN)/mem.o
|
|
||||||
BOBJS+= $(BIN)/setjmp.o
|
|
||||||
BOBJS+= $(BIN)/lib1funcs.o
|
|
||||||
|
|
||||||
# Utilities
|
|
||||||
|
|
||||||
$(BIN)/nrv2b: util/nrv2b.c
|
|
||||||
$(HOST_CC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG -DBITSIZE=32 -DENDIAN=0 -o $@ $<
|
|
||||||
|
|
||||||
# Pattern Rules
|
|
||||||
# General for compiling/assembly source files
|
|
||||||
$(BIN)/%.o: arch/armnommu/core/%.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
$(BIN)/%.o: arch/armnommu/drivers/net/%.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
$(BIN)/%.S: arch/armnommu/core/%.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) -S -o $@ -c $<
|
|
||||||
|
|
||||||
$(BIN)/%.o: arch/armnommu/core/%.S $(MAKEDEPS)
|
|
||||||
$(CPP) $(CFLAGS) -D ASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
# general ruls for generating .img files
|
|
||||||
$(BIN)/%.tmp: $(BIN)/%.o $(START) $(BIN)/config.o arch/$(ARCH)/core/etherboot.lds $(LIBS) $(STDDEPS) $(MAKEDEPS)
|
|
||||||
$(LD) $(LDFLAGS) -T arch/$(ARCH)/core/etherboot.lds -o $@ $(START) $(BIN)/config.o $< $(LIBS)
|
|
||||||
@$(SIZE) $@ | $(CHECKSIZE)
|
|
||||||
|
|
||||||
$(BIN)/%.img: $(BIN)/%.tmp $(MAKEDEPS)
|
|
||||||
$(OBJCOPY) -O binary $< $@
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#include "etherboot.h"
|
|
||||||
#include "timer.h"
|
|
||||||
#include "latch.h"
|
|
||||||
#include "hardware.h"
|
|
||||||
#include "init.h"
|
|
||||||
|
|
||||||
/* get timer returns the contents of the timer */
|
|
||||||
static unsigned long get_timer(void)
|
|
||||||
{
|
|
||||||
return P2001_TIMER->Freerun_Timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------ Calibrate the TSC -------
|
|
||||||
* Time how long it takes to excute a loop that runs in known time.
|
|
||||||
* And find the convertion needed to get to CLOCK_TICK_RATE
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned long configure_timer(void)
|
|
||||||
{
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long clocks_per_tick = 1;
|
|
||||||
|
|
||||||
static void setup_timers(void)
|
|
||||||
{
|
|
||||||
if (!clocks_per_tick) {
|
|
||||||
clocks_per_tick = configure_timer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long currticks(void)
|
|
||||||
{
|
|
||||||
return get_timer(); /* /clocks_per_tick */
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long timer_timeout;
|
|
||||||
static int __timer_running(void)
|
|
||||||
{
|
|
||||||
return get_timer() < timer_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void udelay(unsigned int usecs)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
now = get_timer();
|
|
||||||
timer_timeout = now + usecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000));
|
|
||||||
while(__timer_running());
|
|
||||||
}
|
|
||||||
void ndelay(unsigned int nsecs)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
now = get_timer();
|
|
||||||
timer_timeout = now + nsecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000*1000));
|
|
||||||
while(__timer_running());
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_timer2(unsigned int timer2_ticks)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
unsigned long clocks;
|
|
||||||
now = get_timer();
|
|
||||||
clocks = timer2_ticks * ((clocks_per_tick * TICKS_PER_SEC)/CLOCK_TICK_RATE);
|
|
||||||
timer_timeout = now + clocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
int timer2_running(void)
|
|
||||||
{
|
|
||||||
return __timer_running();
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );
|
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
|
||||||
OUTPUT_ARCH(arm)
|
|
||||||
ENTRY(_start)
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
/*. = 0x00000000;*/ /* PIC */
|
|
||||||
/*. = 0x00000400;*/ /* ROM Bootloader */
|
|
||||||
. = 0x40000000; /* SDRAM */
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
_text = . ;
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
_start = .;
|
|
||||||
_virt_start = .;
|
|
||||||
bin/start.o (.text)
|
|
||||||
*(.text)
|
|
||||||
|
|
||||||
. = ALIGN(16);
|
|
||||||
isa_drivers = . ;
|
|
||||||
*(.drivers.isa);
|
|
||||||
isa_drivers_end = . ;
|
|
||||||
}
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
.rodata : { *(.rodata) }
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
.data : { *(.data) }
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
.got : { *(.got) }
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
_bss = . ;
|
|
||||||
.bss : { *(.bss) }
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
_ebss = .;
|
|
||||||
_end = .;
|
|
||||||
|
|
||||||
. = ALIGN(16);
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
*(.dma.desc);
|
|
||||||
*(.dma.buffer);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* from gcc/config/udivmodsi4.c
|
|
||||||
*/
|
|
||||||
unsigned long
|
|
||||||
udivmodsi4(unsigned long num, unsigned long den, int modwanted)
|
|
||||||
{
|
|
||||||
unsigned long bit = 1;
|
|
||||||
unsigned long res = 0;
|
|
||||||
|
|
||||||
while (den < num && bit && !(den & (1L<<31)))
|
|
||||||
{
|
|
||||||
den <<=1;
|
|
||||||
bit <<=1;
|
|
||||||
}
|
|
||||||
while (bit)
|
|
||||||
{
|
|
||||||
if (num >= den)
|
|
||||||
{
|
|
||||||
num -= den;
|
|
||||||
res |= bit;
|
|
||||||
}
|
|
||||||
bit >>=1;
|
|
||||||
den >>=1;
|
|
||||||
}
|
|
||||||
if (modwanted) return num;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* from gcc/config/udivmod.c
|
|
||||||
*/
|
|
||||||
long
|
|
||||||
__udivsi3 (long a, long b)
|
|
||||||
{
|
|
||||||
return udivmodsi4 (a, b, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
long
|
|
||||||
__umodsi3 (long a, long b)
|
|
||||||
{
|
|
||||||
return udivmodsi4 (a, b, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* from gcc/config/divmod.c
|
|
||||||
*/
|
|
||||||
long
|
|
||||||
__divsi3 (long a, long b)
|
|
||||||
{
|
|
||||||
int neg = 0;
|
|
||||||
long res;
|
|
||||||
|
|
||||||
if (a < 0)
|
|
||||||
{
|
|
||||||
a = -a;
|
|
||||||
neg = !neg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b < 0)
|
|
||||||
{
|
|
||||||
b = -b;
|
|
||||||
neg = !neg;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = udivmodsi4 (a, b, 0);
|
|
||||||
|
|
||||||
if (neg)
|
|
||||||
res = -res;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
long
|
|
||||||
__modsi3 (long a, long b)
|
|
||||||
{
|
|
||||||
int neg = 0;
|
|
||||||
long res;
|
|
||||||
|
|
||||||
if (a < 0)
|
|
||||||
{
|
|
||||||
a = -a;
|
|
||||||
neg = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b < 0)
|
|
||||||
b = -b;
|
|
||||||
|
|
||||||
res = udivmodsi4 (a, b, 1);
|
|
||||||
|
|
||||||
if (neg)
|
|
||||||
res = -res;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#include "hooks.h"
|
|
||||||
#include "io.h"
|
|
||||||
#include "etherboot.h"
|
|
||||||
|
|
||||||
struct meminfo meminfo;
|
|
||||||
void get_memsizes(void)
|
|
||||||
{
|
|
||||||
/* We initialize the meminfo structure
|
|
||||||
* according to our development board's specs
|
|
||||||
* We do not have a way to automatically probe the
|
|
||||||
* memspace instead we initialize it manually
|
|
||||||
*/
|
|
||||||
meminfo.basememsize = 0x00000000;
|
|
||||||
meminfo.memsize = 0x00008000;
|
|
||||||
meminfo.map_count = 1;
|
|
||||||
|
|
||||||
meminfo.map[0].addr = 0x40000000;
|
|
||||||
meminfo.map[0].size = 0x01000000;
|
|
||||||
meminfo.map[0].type = E820_RAM;
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifdef RAW_IMAGE
|
|
||||||
static unsigned long raw_load_addr;
|
|
||||||
|
|
||||||
int mach_boot(register unsigned long entry_point)
|
|
||||||
{
|
|
||||||
void (*fnc)(void) = (void *) entry_point;
|
|
||||||
// r0 = 0
|
|
||||||
// r1 = 625 (machine nr. MACH_TYPE_P2001)
|
|
||||||
(*fnc)();
|
|
||||||
|
|
||||||
return 0; /* We should never reach this point ! */
|
|
||||||
}
|
|
||||||
|
|
||||||
static sector_t raw_download(unsigned char *data, unsigned int len, int eof)
|
|
||||||
{
|
|
||||||
memcpy(phys_to_virt(raw_load_addr), data, len);
|
|
||||||
raw_load_addr += len;
|
|
||||||
if (!eof)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
done(1);
|
|
||||||
printf("Starting program.\n");
|
|
||||||
mach_boot(RAWADDR);
|
|
||||||
printf("Bootsector returned?");
|
|
||||||
longjmp(restart_etherboot, -2);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static os_download_t raw_probe(unsigned char *data __unused, unsigned int len __unused)
|
|
||||||
{
|
|
||||||
printf("(RAW");
|
|
||||||
// probe something here...
|
|
||||||
printf(")... \n");
|
|
||||||
|
|
||||||
//raw_load_addr = phys_to_virt(_end);
|
|
||||||
raw_load_addr = RAWADDR;
|
|
||||||
printf("Writing image to 0x%x\n", raw_load_addr);
|
|
||||||
return raw_download;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#include "etherboot.h"
|
|
||||||
#include "hardware.h"
|
|
||||||
#ifdef CONSOLE_SERIAL
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void serial_putc(int ch);
|
|
||||||
* Write character `ch' to port UART_BASE.
|
|
||||||
*/
|
|
||||||
void serial_putc(int ch)
|
|
||||||
{
|
|
||||||
/* wait for room in the 32 byte tx FIFO */
|
|
||||||
while ((P2001_UART->r.STATUS & 0x3f) > /* 30 */ 0) ;
|
|
||||||
P2001_UART->w.TX[0] = ch & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* int serial_getc(void);
|
|
||||||
* Read a character from port UART_BASE.
|
|
||||||
*/
|
|
||||||
int serial_getc(void)
|
|
||||||
{
|
|
||||||
while (((P2001_UART->r.STATUS >> 6) & 0x3f) == 0) ;
|
|
||||||
return P2001_UART->r.RX[0] & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* int serial_ischar(void);
|
|
||||||
* If there is a character in the input buffer of port UART_BASE,
|
|
||||||
* return nonzero; otherwise return 0.
|
|
||||||
*/
|
|
||||||
int serial_ischar(void)
|
|
||||||
{
|
|
||||||
return (P2001_UART->r.STATUS >> 6) & 0x3f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* int serial_init(void);
|
|
||||||
* Initialize port to speed 57.600, line settings 8N1.
|
|
||||||
*/
|
|
||||||
int serial_init(void)
|
|
||||||
{
|
|
||||||
static unsigned int N;
|
|
||||||
// const M=3
|
|
||||||
P2001_UART->w.Clear = 0; // clear
|
|
||||||
N = ((SYSCLK/8)*3)/CONSPEED;
|
|
||||||
P2001_UART->w.Baudrate = (N<<16)+3; // set 57.600 BAUD
|
|
||||||
P2001_UART->w.Config = 0xcc100; // set 8N1, *water = 12
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void serial_fini(void);
|
|
||||||
* Cleanup our use of the serial port, in particular flush the
|
|
||||||
* output buffer so we don't accidentially loose characters.
|
|
||||||
*/
|
|
||||||
void serial_fini(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
|
|
||||||
.global sigsetjmp;
|
|
||||||
.type sigsetjmp,%function
|
|
||||||
.align 4;
|
|
||||||
sigsetjmp:
|
|
||||||
/* Save registers */
|
|
||||||
stmia r0, {v1-v6, sl, fp, sp, lr}
|
|
||||||
|
|
||||||
mov r0, #0
|
|
||||||
bx lr
|
|
||||||
.size sigsetjmp,.-sigsetjmp;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.global longjmp;
|
|
||||||
.type longjmp,%function
|
|
||||||
.align 4;
|
|
||||||
longjmp:
|
|
||||||
mov ip, r0 /* save jmp_buf pointer */
|
|
||||||
|
|
||||||
movs r0, r1 /* get the return value in place */
|
|
||||||
moveq r0, #1 /* can't let setjmp() return zero! */
|
|
||||||
|
|
||||||
ldmia ip, {v1-v6, sl, fp, sp, pc}
|
|
||||||
.size longjmp,.-longjmp;
|
|
|
@ -1,184 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
.global _start
|
|
||||||
|
|
||||||
/* Mode definitions */
|
|
||||||
#define Mode_USR 0x10
|
|
||||||
#define Mode_FIQ 0x11
|
|
||||||
#define Mode_IRQ 0x12
|
|
||||||
#define Mode_SVC 0x13
|
|
||||||
#define Mode_ABT 0x17
|
|
||||||
#define Mode_UNDEF 0x1B
|
|
||||||
#define Mode_SYS 0x1F // only available on ARM Arch. v4
|
|
||||||
#define I_Bit 0x80
|
|
||||||
#define F_Bit 0x40
|
|
||||||
|
|
||||||
/* LPEC register definitions */
|
|
||||||
#define Adr_SYS_BASE 0x00100000
|
|
||||||
#define REL_Adr_SDRAM_Ctrl 0x10
|
|
||||||
#define REL_Adr_ExtMem_Ctrl 0x14
|
|
||||||
#define REL_Adr_WaitState_Ext 0x18
|
|
||||||
#define REL_Adr_WaitState_Asic 0x1c
|
|
||||||
#define Adr_TIMER_BASE 0x00110000
|
|
||||||
#define REL_Adr_Timer12_PreDiv 0x0c
|
|
||||||
#define REL_Adr_PLL_12000_config 0x30
|
|
||||||
#define REL_Adr_PLL_12288_config 0x34
|
|
||||||
#define REL_Adr_DIV_12288_config 0x38
|
|
||||||
#define REL_Adr_FSC_CONFIG 0x44
|
|
||||||
#define Adr_GPIO_BASE 0x00120000
|
|
||||||
#define REL_Adr_NRES_OUT 0x2c
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Define entry point */
|
|
||||||
.arm // Next instruction will be ARM
|
|
||||||
_start:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize memory system
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize stack pointer registers
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Enter SVC mode and set up the SVC stack pointer */
|
|
||||||
mov r0, #(Mode_SVC|I_Bit|F_Bit)
|
|
||||||
msr cpsr_c, r0
|
|
||||||
ldr sp, SP_SVC
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize critical IO devices
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* watchdog off */
|
|
||||||
mov r0, #Adr_TIMER_BASE
|
|
||||||
ldr r1, Timer12_PreDiv
|
|
||||||
str r1, [r0, #REL_Adr_Timer12_PreDiv]
|
|
||||||
|
|
||||||
/* NRES=1 */
|
|
||||||
mov r0, #Adr_GPIO_BASE
|
|
||||||
ldr r1, NRES_OUT
|
|
||||||
str r1, [r0, #REL_Adr_NRES_OUT]
|
|
||||||
|
|
||||||
/* ExtMem */
|
|
||||||
mov r0, #Adr_SYS_BASE
|
|
||||||
ldr r1, ExtMem_Ctrl
|
|
||||||
str r1, [r0, #REL_Adr_ExtMem_Ctrl]
|
|
||||||
|
|
||||||
/* SDRAM */
|
|
||||||
mov r0, #Adr_SYS_BASE
|
|
||||||
ldr r1, SDRAM_Ctrl
|
|
||||||
str r1, [r0, #REL_Adr_SDRAM_Ctrl]
|
|
||||||
/*
|
|
||||||
_wait_sdram_ctrl:
|
|
||||||
ldr r1, [r0]
|
|
||||||
tst r1, #0x20000
|
|
||||||
beq _wait_sdram_ctrl
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* WaitState_Ext */
|
|
||||||
ldr r1, WaitState_Ext
|
|
||||||
str r1, [r0, #REL_Adr_WaitState_Ext]
|
|
||||||
/* WaitState_Asic */
|
|
||||||
ldr r1, WaitState_Asic
|
|
||||||
str r1, [r0, #REL_Adr_WaitState_Asic]
|
|
||||||
|
|
||||||
/* PLL_12288 */
|
|
||||||
mov r0, #Adr_TIMER_BASE
|
|
||||||
ldr r1, PLL_12288_config
|
|
||||||
str r1, [r0, #REL_Adr_PLL_12288_config]
|
|
||||||
/* DIV_12288 */
|
|
||||||
ldr r1, DIV_12288_config
|
|
||||||
str r1, [r0, #REL_Adr_DIV_12288_config]
|
|
||||||
/* PLL_12200 */
|
|
||||||
ldr r1, PLL_12000_config
|
|
||||||
str r1, [r0, #REL_Adr_PLL_12000_config]
|
|
||||||
|
|
||||||
/* FSC_CONFIG */
|
|
||||||
ldr r1, [r0, #REL_Adr_FSC_CONFIG]
|
|
||||||
bic r1, r1, #0x07
|
|
||||||
ldr r2, FSC_CONFIG
|
|
||||||
orr r1, r1, r2
|
|
||||||
str r1, [r0, #REL_Adr_FSC_CONFIG]
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize interrupt system variables here
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize memory required by main C code
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* jump to main program */
|
|
||||||
mov r0, #0
|
|
||||||
b main
|
|
||||||
|
|
||||||
|
|
||||||
Timer12_PreDiv:
|
|
||||||
.word 0x40bb0000 /* watchdog off */
|
|
||||||
NRES_OUT:
|
|
||||||
.word 0x00000003 /* NRES_OUT_DRV=1, NRES_OUT_DAT=1 */
|
|
||||||
|
|
||||||
#if SYSCLK == 73728000
|
|
||||||
ExtMem_Ctrl:
|
|
||||||
.word 0x000000e8 /* fuer FPGA 32 Bit konfiguriert */
|
|
||||||
SDRAM_Ctrl:
|
|
||||||
// .word 0x28fc0037 /* default */
|
|
||||||
.word 0xaef40027 /* p2001_bit_compact */
|
|
||||||
WaitState_Ext:
|
|
||||||
.word 0xa0001245 /* fuer 73 MHz */
|
|
||||||
// .word 0x0000fff3 /* rom bootloader */
|
|
||||||
WaitState_Asic:
|
|
||||||
.word 0x00ff8a5f /* fuer 85 MHz */
|
|
||||||
// .word 0x00000203 /* rom bootloader */
|
|
||||||
PLL_12288_config:
|
|
||||||
.word 0x00000004 /* fuer 73 MHz */
|
|
||||||
DIV_12288_config:
|
|
||||||
.word 0x00010601 /* fuer 73 MHz */
|
|
||||||
PLL_12000_config:
|
|
||||||
.word 0x10004e75 /* fuer 85 MHz */
|
|
||||||
FSC_CONFIG:
|
|
||||||
.word 0xc0000005 /* fuer 73 MHz */
|
|
||||||
#else
|
|
||||||
#error "Please define proper timings and wait states for that sysclk."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SP_SVC:
|
|
||||||
.word 0x40fffffc
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NORELOCATE
|
|
||||||
/**************************************************************************
|
|
||||||
RELOCATE_TO - relocate etherboot to the specified address
|
|
||||||
**************************************************************************/
|
|
||||||
.global relocate_to
|
|
||||||
|
|
||||||
relocate_to:
|
|
||||||
ldr r1, =_start
|
|
||||||
ldr r2, =_end
|
|
||||||
|
|
||||||
/* while (r1 < r2) { *(r0++) = *(r1++) } */
|
|
||||||
_relocate_loop:
|
|
||||||
cmp r1, r2
|
|
||||||
ldrcc r3, [r1], #4
|
|
||||||
strcc r3, [r0], #4
|
|
||||||
bcc _relocate_loop
|
|
||||||
mov pc, lr
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
.global __gccmain
|
|
||||||
__gccmain:
|
|
||||||
mov pc, lr /* return from subroutine */
|
|
|
@ -1,592 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
* Etherboot - BOOTP/TFTP Bootstrap Program
|
|
||||||
* P2001 NIC driver for Etherboot
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2005 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* to get some global routines like printf */
|
|
||||||
#include "etherboot.h"
|
|
||||||
/* to get the interface to the body of the program */
|
|
||||||
#include "nic.h"
|
|
||||||
/* to get the ISA support functions, if this is an ISA NIC */
|
|
||||||
#include "isa.h"
|
|
||||||
|
|
||||||
#include "hardware.h"
|
|
||||||
#include "mii.h"
|
|
||||||
#include "timer.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* NIC specific static variables go here */
|
|
||||||
static unsigned char MAC_HW_ADDR[6]={MAC_HW_ADDR_DRV};
|
|
||||||
|
|
||||||
/* DMA descriptors and buffers */
|
|
||||||
#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
|
|
||||||
#define DMA_BUF_SIZE 2048 /* Buffer size */
|
|
||||||
static DMA_DSC txd __attribute__ ((__section__(".dma.desc")));
|
|
||||||
static DMA_DSC rxd[NUM_RX_DESC] __attribute__ ((__section__(".dma.desc")));
|
|
||||||
static char rxb[NUM_RX_DESC * DMA_BUF_SIZE] __attribute__ ((__section__(".dma.buffer")));
|
|
||||||
static char txb[ DMA_BUF_SIZE] __attribute__ ((__section__(".dma.buffer")));
|
|
||||||
static unsigned int cur_rx;
|
|
||||||
|
|
||||||
/* Device selectors */
|
|
||||||
static unsigned int cur_channel; // DMA channel : 0..3
|
|
||||||
static unsigned int cur_phy; // PHY Address : 0..31
|
|
||||||
static P2001_ETH_regs_ptr EU; // Ethernet Unit : 0x0018_000 with _=0..3
|
|
||||||
|
|
||||||
/* mdio handling */
|
|
||||||
static int p2001_eth_mdio_read (int phy_id, int location);
|
|
||||||
static void p2001_eth_mdio_write(int phy_id, int location, int val);
|
|
||||||
|
|
||||||
/* net_device functions */
|
|
||||||
static int p2001_eth_poll (struct nic *nic, int retrieve);
|
|
||||||
static void p2001_eth_transmit (struct nic *nic, const char *d,
|
|
||||||
unsigned int t, unsigned int s, const char *p);
|
|
||||||
|
|
||||||
static void p2001_eth_irq (struct nic *nic, irq_action_t action);
|
|
||||||
|
|
||||||
static void p2001_eth_init ();
|
|
||||||
static void p2001_eth_disable (struct dev *dev);
|
|
||||||
|
|
||||||
static int p2001_eth_check_link(unsigned int phy);
|
|
||||||
static int link;
|
|
||||||
static void p2001_eth_phyreset ();
|
|
||||||
static int p2001_eth_probe (struct dev *dev, unsigned short *probe_addrs __unused);
|
|
||||||
|
|
||||||
/* Supported MII list */
|
|
||||||
static struct mii_chip_info {
|
|
||||||
const char * name;
|
|
||||||
unsigned int physid; // (MII_PHYSID2 << 16) | MII_PHYSID1
|
|
||||||
} mii_chip_table[] = {
|
|
||||||
{ "Intel LXT971A", 0x78e20013 },
|
|
||||||
{ "Altima AC104-QF", 0x55410022 },
|
|
||||||
{NULL,0},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* PHY MANAGEMENT UNIT - Read/write
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mdio_read - read MII PHY register
|
|
||||||
* @dev: the net device to read
|
|
||||||
* @regadr: the phy register id to read
|
|
||||||
*
|
|
||||||
* Read MII registers through MDIO and MDC
|
|
||||||
* using MDIO management frame structure and protocol(defined by ISO/IEC).
|
|
||||||
*/
|
|
||||||
static int p2001_eth_mdio_read(int phy_id, int location)
|
|
||||||
{
|
|
||||||
int result, boguscnt = 1000;
|
|
||||||
|
|
||||||
do {
|
|
||||||
/* Warten bis Hardware inaktiv (MIU = "0") */
|
|
||||||
while (P2001_MU->MU_CNTL & 0x8000)
|
|
||||||
barrier();
|
|
||||||
|
|
||||||
/* Schreiben MU_CNTL */
|
|
||||||
P2001_MU->MU_CNTL = location + (phy_id<<5) + (2<<10);
|
|
||||||
|
|
||||||
/* Warten bis Hardware aktiv (MIU = "1") */
|
|
||||||
while ((P2001_MU->MU_CNTL & 0x8000) == 0)
|
|
||||||
barrier();
|
|
||||||
//asm("nop \r\n nop");
|
|
||||||
|
|
||||||
/* Warten bis Hardware inaktiv (MIU = "0") */
|
|
||||||
while (P2001_MU->MU_CNTL & 0x8000)
|
|
||||||
barrier();
|
|
||||||
|
|
||||||
/* Fehler, wenn MDIO Read Error (MRE = "1") */
|
|
||||||
} while ((P2001_MU->MU_CNTL & 0x4000) && (--boguscnt > 0));
|
|
||||||
|
|
||||||
/* Lesen MU_DATA */
|
|
||||||
result = P2001_MU->MU_DATA;
|
|
||||||
|
|
||||||
if (boguscnt == 0)
|
|
||||||
return 0;
|
|
||||||
if ((result & 0xffff) == 0xffff)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return result & 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mdio_write - write MII PHY register
|
|
||||||
* @dev: the net device to write
|
|
||||||
* @regadr: the phy register id to write
|
|
||||||
* @value: the register value to write with
|
|
||||||
*
|
|
||||||
* Write MII registers with @value through MDIO and MDC
|
|
||||||
* using MDIO management frame structure and protocol(defined by ISO/IEC)
|
|
||||||
*/
|
|
||||||
static void p2001_eth_mdio_write(int phy_id, int location, int val)
|
|
||||||
{
|
|
||||||
/* Warten bis Hardware inaktiv (MIU = "0") */
|
|
||||||
while (P2001_MU->MU_CNTL & 0x8000)
|
|
||||||
barrier();
|
|
||||||
|
|
||||||
/* Schreiben MU_DATA */
|
|
||||||
P2001_MU->MU_DATA = val;
|
|
||||||
|
|
||||||
/* Schreiben MU_CNTL */
|
|
||||||
P2001_MU->MU_CNTL = location + (phy_id<<5) + (1<<10);
|
|
||||||
|
|
||||||
/* Warten bis Hardware aktiv (MIU = "1") */
|
|
||||||
while ((P2001_MU->MU_CNTL & 0x8000) == 0)
|
|
||||||
barrier();
|
|
||||||
//asm("nop \r\n nop");
|
|
||||||
|
|
||||||
/* Warten bis Hardware inaktiv (MIU = "0") */
|
|
||||||
while (P2001_MU->MU_CNTL & 0x8000)
|
|
||||||
barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* POLL - Wait for a frame
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/* Function: p2001_eth_poll
|
|
||||||
*
|
|
||||||
* Description: checks for a received packet and returns it if found.
|
|
||||||
*
|
|
||||||
* Arguments: struct nic *nic: NIC data structure
|
|
||||||
*
|
|
||||||
* Returns: 1 if a packet was received.
|
|
||||||
* 0 if no pacet was received.
|
|
||||||
*
|
|
||||||
* Side effects:
|
|
||||||
* Returns (copies) the packet to the array nic->packet.
|
|
||||||
* Returns the length of the packet in nic->packetlen.
|
|
||||||
*/
|
|
||||||
static int p2001_eth_poll(struct nic *nic, int retrieve)
|
|
||||||
{
|
|
||||||
/* return true if there's an ethernet packet ready to read */
|
|
||||||
/* nic->packet should contain data on return */
|
|
||||||
/* nic->packetlen should contain length of data */
|
|
||||||
|
|
||||||
int retstat = 0;
|
|
||||||
|
|
||||||
if (rxd[cur_rx].stat & (1<<31)) // OWN
|
|
||||||
return retstat;
|
|
||||||
|
|
||||||
if (!retrieve)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
nic->packetlen = rxd[cur_rx].cntl & 0xffff;
|
|
||||||
|
|
||||||
if (rxd[cur_rx].stat & ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22))) {
|
|
||||||
/* corrupted packet received */
|
|
||||||
printf("p2001_eth_poll: Corrupted packet received, stat = %X\n",
|
|
||||||
rxd[cur_rx].stat);
|
|
||||||
retstat = 0;
|
|
||||||
} else {
|
|
||||||
/* give packet to higher routine */
|
|
||||||
memcpy(nic->packet, (rxb + cur_rx*DMA_BUF_SIZE), nic->packetlen);
|
|
||||||
retstat = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_NIC
|
|
||||||
printf("p2001_eth_poll: packet from %! to %! received\n",
|
|
||||||
(rxb+cur_rx*DMA_BUF_SIZE)+ETH_ALEN,
|
|
||||||
(rxb+cur_rx*DMA_BUF_SIZE));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* disable receiver */
|
|
||||||
// FIXME: is that ok? it can produce grave errors.
|
|
||||||
EU->RMAC_DMA_EN = 0; /* clear run bit */
|
|
||||||
|
|
||||||
/* return the descriptor and buffer to receive ring */
|
|
||||||
rxd[cur_rx].stat = (1<<31) | (1<<30) | (1<<29); // DSC0 OWN|START|END
|
|
||||||
rxd[cur_rx].cntl = (1<<23); // DSC1 RECEIVE
|
|
||||||
rxd[cur_rx].cntl |= cur_channel << 16; // DSC1 CHANNEL
|
|
||||||
rxd[cur_rx].cntl |= DMA_BUF_SIZE; // DSC1 LEN
|
|
||||||
|
|
||||||
if (++cur_rx == NUM_RX_DESC)
|
|
||||||
cur_rx = 0;
|
|
||||||
|
|
||||||
/* enable receiver */
|
|
||||||
if (!(EU->RMAC_DMA_EN & 0x01))
|
|
||||||
EU->RMAC_DMA_EN = 0x01; /* set run bit */
|
|
||||||
|
|
||||||
#ifdef DEBUG_NIC
|
|
||||||
printf("RMAC_MIB0..5: %d:%d:%d:%d:%d:%d\n",
|
|
||||||
EU->RMAC_MIB0, EU->RMAC_MIB1,
|
|
||||||
EU->RMAC_MIB2, EU->RMAC_MIB3,
|
|
||||||
EU->RMAC_MIB4, EU->RMAC_MIB5);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return retstat; /* initially as this is called to flush the input */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* TRANSMIT - Transmit a frame
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/* Function: p2001_eth_transmit
|
|
||||||
*
|
|
||||||
* Description: transmits a packet and waits for completion or timeout.
|
|
||||||
*
|
|
||||||
* Arguments: char d[6]: destination ethernet address.
|
|
||||||
* unsigned short t: ethernet protocol type.
|
|
||||||
* unsigned short s: size of the data-part of the packet.
|
|
||||||
* char *p: the data for the packet.
|
|
||||||
*
|
|
||||||
* Returns: void.
|
|
||||||
*/
|
|
||||||
static void p2001_eth_transmit(
|
|
||||||
struct nic *nic __unused,
|
|
||||||
const char *d, /* Destination */
|
|
||||||
unsigned int t, /* Type */
|
|
||||||
unsigned int s, /* size */
|
|
||||||
const char *p) /* Packet */
|
|
||||||
{
|
|
||||||
unsigned int nstype;
|
|
||||||
#ifdef DEBUG_NIC
|
|
||||||
unsigned int status;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* assemble packet */
|
|
||||||
memcpy(txb, d, ETH_ALEN); // destination
|
|
||||||
memcpy(txb+ETH_ALEN, nic->node_addr, ETH_ALEN); // source
|
|
||||||
nstype = htons(t);
|
|
||||||
memcpy(txb+2*ETH_ALEN, (char*)&nstype, 2); // type
|
|
||||||
memcpy(txb+ETH_HLEN, p, s); // packet
|
|
||||||
s += ETH_HLEN;
|
|
||||||
|
|
||||||
/* pad to minimum packet size */
|
|
||||||
// while (s<ETH_ZLEN)
|
|
||||||
// txb[s++] = '\0';
|
|
||||||
// TMAC_CNTL.ATP does the same
|
|
||||||
|
|
||||||
#ifdef DEBUG_NIC
|
|
||||||
printf("p2001_eth_transmit: packet from %! to %! sent (size: %d)\n", txb+ETH_ALEN, txb, s);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* configure descriptor */
|
|
||||||
txd.stat = (1<<31) | (1<<30) | (1<<29); // DSC0 OWN|START|END
|
|
||||||
txd.cntl = cur_channel << 16; // DSC1 CHANNEL
|
|
||||||
txd.cntl |= s; // DSC1 LEN
|
|
||||||
|
|
||||||
/* restart the transmitter */
|
|
||||||
EU->TMAC_DMA_EN = 0x01; /* set run bit */
|
|
||||||
while(EU->TMAC_DMA_EN & 0x01); /* wait */
|
|
||||||
|
|
||||||
#ifdef DEBUG_NIC
|
|
||||||
/* check status */
|
|
||||||
status = EU->TMAC_DMA_STAT;
|
|
||||||
if (status & ~(0x40)) // not END
|
|
||||||
printf("p2001_eth_transmit: dma status=0x%hx\n", status);
|
|
||||||
|
|
||||||
printf("TMAC_MIB6..7: %d:%d\n", EU->TMAC_MIB6, EU->TMAC_MIB7);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* IRQ - Enable, Disable or Force Interrupts
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/* Function: p2001_eth_irq
|
|
||||||
*
|
|
||||||
* Description: Enable, Disable, or Force, interrupts
|
|
||||||
*
|
|
||||||
* Arguments: struct nic *nic: NIC data structure
|
|
||||||
* irq_action_t action: Requested action
|
|
||||||
*
|
|
||||||
* Returns: void.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
p2001_eth_irq(struct nic *nic __unused, irq_action_t action __unused)
|
|
||||||
{
|
|
||||||
switch ( action ) {
|
|
||||||
case DISABLE :
|
|
||||||
break;
|
|
||||||
case ENABLE :
|
|
||||||
break;
|
|
||||||
case FORCE :
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* INIT - Initialize device
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/* Function: p2001_init
|
|
||||||
*
|
|
||||||
* Description: resets the ethernet controller chip and various
|
|
||||||
* data structures required for sending and receiving packets.
|
|
||||||
*
|
|
||||||
* returns: void.
|
|
||||||
*/
|
|
||||||
static void p2001_eth_init()
|
|
||||||
{
|
|
||||||
static int i;
|
|
||||||
|
|
||||||
/* activate MII 3 */
|
|
||||||
if (cur_channel == 3)
|
|
||||||
P2001_GPIO->PIN_MUX |= (1<<8); // MII_3_en = 1
|
|
||||||
|
|
||||||
#ifdef RMII
|
|
||||||
/* RMII init sequence */
|
|
||||||
if (link & LPA_100) {
|
|
||||||
EU->CONF_RMII = (1<<2) | (1<<1); // softres | 100Mbit
|
|
||||||
EU->CONF_RMII = (1<<2) | (1<<1) | (1<<0); // softres | 100Mbit | RMII
|
|
||||||
EU->CONF_RMII = (1<<1) | (1<<0); // 100 Mbit | RMII
|
|
||||||
} else {
|
|
||||||
EU->CONF_RMII = (1<<2); // softres
|
|
||||||
EU->CONF_RMII = (1<<2) | (1<<0); // softres | RMII
|
|
||||||
EU->CONF_RMII = (1<<0); // RMII
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* disable transceiver */
|
|
||||||
// EU->TMAC_DMA_EN = 0; /* clear run bit */
|
|
||||||
// EU->RMAC_DMA_EN = 0; /* clear run bit */
|
|
||||||
|
|
||||||
/* set rx filter (physical mac addresses) */
|
|
||||||
EU->RMAC_PHYU =
|
|
||||||
(MAC_HW_ADDR[0]<< 8) +
|
|
||||||
(MAC_HW_ADDR[1]<< 0);
|
|
||||||
EU->RMAC_PHYL =
|
|
||||||
(MAC_HW_ADDR[2]<<24) +
|
|
||||||
(MAC_HW_ADDR[3]<<16) +
|
|
||||||
(MAC_HW_ADDR[4]<<8 ) +
|
|
||||||
(MAC_HW_ADDR[5]<<0 );
|
|
||||||
|
|
||||||
/* initialize the tx descriptor ring */
|
|
||||||
// txd.stat = (1<<31) | (1<<30) | (1<<29); // DSC0 OWN|START|END
|
|
||||||
// txd.cntl = cur_channel << 16; // DSC1 CHANNEL
|
|
||||||
// txd.cntl |= DMA_BUF_SIZE; // DSC1 LEN
|
|
||||||
txd.buf = (char *)&txb; // DSC2 BUFFER
|
|
||||||
txd.next = &txd; // DSC3 NEXTDSC @self
|
|
||||||
EU->TMAC_DMA_DESC = &txd;
|
|
||||||
|
|
||||||
/* initialize the rx descriptor ring */
|
|
||||||
cur_rx = 0;
|
|
||||||
for (i = 0; i < NUM_RX_DESC; i++) {
|
|
||||||
rxd[i].stat = (1<<31) | (1<<30) | (1<<29); // DSC0 OWN|START|END
|
|
||||||
rxd[i].cntl = (1<<23); // DSC1 RECEIVE
|
|
||||||
rxd[i].cntl |= cur_channel << 16; // DSC1 CHANNEL
|
|
||||||
rxd[i].cntl |= DMA_BUF_SIZE; // DSC1 LEN
|
|
||||||
rxd[i].buf = &rxb[i*DMA_BUF_SIZE]; // DSC2 BUFFER (EU-RX data)
|
|
||||||
rxd[i].next = &rxd[i+1]; // DSC3 NEXTDSC @next
|
|
||||||
}
|
|
||||||
rxd[NUM_RX_DESC-1].next = &rxd[0]; // DSC3 NEXTDSC @first
|
|
||||||
EU->RMAC_DMA_DESC = &rxd[0];
|
|
||||||
|
|
||||||
/* set transmitter mode */
|
|
||||||
if (link & LPA_DUPLEX)
|
|
||||||
EU->TMAC_CNTL = (1<<4) | /* COI: Collision ignore */
|
|
||||||
(1<<3) | /* CSI: Carrier Sense ignore */
|
|
||||||
(1<<2); /* ATP: Automatic Transmit Padding */
|
|
||||||
else
|
|
||||||
EU->TMAC_CNTL = (1<<2); /* ATP: Automatic Transmit Padding */
|
|
||||||
|
|
||||||
/* set receive mode */
|
|
||||||
EU->RMAC_CNTL = (1<<3) | /* BROAD: Broadcast packets */
|
|
||||||
(1<<1); /* PHY : Packets to out MAC address */
|
|
||||||
|
|
||||||
/* enable receiver */
|
|
||||||
EU->RMAC_DMA_EN = 1; /* set run bit */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* DISABLE - Turn off ethernet interface
|
|
||||||
**************************************************************************/
|
|
||||||
static void p2001_eth_disable(struct dev *dev __unused)
|
|
||||||
{
|
|
||||||
/* put the card in its initial state */
|
|
||||||
/* This function serves 3 purposes.
|
|
||||||
* This disables DMA and interrupts so we don't receive
|
|
||||||
* unexpected packets or interrupts from the card after
|
|
||||||
* etherboot has finished.
|
|
||||||
* This frees resources so etherboot may use
|
|
||||||
* this driver on another interface
|
|
||||||
* This allows etherboot to reinitialize the interface
|
|
||||||
* if something is something goes wrong.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* disable transmitter */
|
|
||||||
EU->TMAC_DMA_EN = 0; /* clear run bit */
|
|
||||||
|
|
||||||
/* disable receiver */
|
|
||||||
EU->RMAC_DMA_EN = 0; /* clear run bit */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* LINK - Check for valid link
|
|
||||||
**************************************************************************/
|
|
||||||
static int p2001_eth_check_link(unsigned int phy)
|
|
||||||
{
|
|
||||||
static int status;
|
|
||||||
static unsigned int i, physid;
|
|
||||||
|
|
||||||
/* print some information about out PHY */
|
|
||||||
physid = (p2001_eth_mdio_read(phy, MII_PHYSID2) << 16) |
|
|
||||||
p2001_eth_mdio_read(phy, MII_PHYSID1);
|
|
||||||
printf("PHY %d, ID 0x%x ", phy, physid);
|
|
||||||
for (i = 0; mii_chip_table[i].physid; i++)
|
|
||||||
if (mii_chip_table[i].physid == physid) {
|
|
||||||
printf("(%s).\n", mii_chip_table[i].name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!mii_chip_table[i].physid)
|
|
||||||
printf("(unknown).\n");
|
|
||||||
|
|
||||||
/* Use 0x3300 for restarting NWay */
|
|
||||||
printf("Starting auto-negotiation... ");
|
|
||||||
p2001_eth_mdio_write(phy, MII_BMCR, 0x3300);
|
|
||||||
|
|
||||||
/* Bit 1.5 is set once the Auto-Negotiation process is completed. */
|
|
||||||
i = 0;
|
|
||||||
do {
|
|
||||||
mdelay(500);
|
|
||||||
status = p2001_eth_mdio_read(phy, MII_BMSR);
|
|
||||||
if (!status || (i++ > 6)) // 6*500ms = 3s timeout
|
|
||||||
goto failed;
|
|
||||||
} while (!(status & BMSR_ANEGCOMPLETE));
|
|
||||||
|
|
||||||
/* Bits 1.2 is set once the link is established. */
|
|
||||||
if ((status = p2001_eth_mdio_read(phy, MII_BMSR)) & BMSR_LSTATUS) {
|
|
||||||
link = p2001_eth_mdio_read(phy, MII_ADVERTISE) &
|
|
||||||
p2001_eth_mdio_read(phy, MII_LPA);
|
|
||||||
printf(" Valid link, operating at: %sMb-%s\n",
|
|
||||||
(link & LPA_100) ? "100" : "10",
|
|
||||||
(link & LPA_DUPLEX) ? "FD" : "HD");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
failed:
|
|
||||||
if (!status)
|
|
||||||
printf("Failed\n");
|
|
||||||
else
|
|
||||||
printf("No valid link\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* PHYRESET - hardware reset all MII PHYs
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* p2001_eth_phyreset - hardware reset all MII PHYs
|
|
||||||
*/
|
|
||||||
static void p2001_eth_phyreset()
|
|
||||||
{
|
|
||||||
/* GPIO24/25: TX_ER2/TX_ER0 */
|
|
||||||
/* GPIO26/27: PHY_RESET/TX_ER1 */
|
|
||||||
P2001_GPIO->PIN_MUX |= 0x0018;
|
|
||||||
// 31-16: 0000 1111 0000 0000
|
|
||||||
P2001_GPIO->GPIO2_En |= 0x0400;
|
|
||||||
|
|
||||||
P2001_GPIO->GPIO2_Out |= 0x04000000;
|
|
||||||
P2001_GPIO->GPIO2_Out &= ~0x0400;
|
|
||||||
mdelay(500);
|
|
||||||
P2001_GPIO->GPIO2_Out |= 0x0400;
|
|
||||||
|
|
||||||
#ifdef RMII
|
|
||||||
/* RMII_clk_sel = 0xxb no RMII (default) */
|
|
||||||
/* RMII_clk_sel = 100b COL_0 */
|
|
||||||
/* RMII_clk_sel = 101b COL_1 */
|
|
||||||
/* RMII_clk_sel = 110b COL_2 */
|
|
||||||
/* RMII_clk_sel = 111b COL_3 */
|
|
||||||
P2001_GPIO->PIN_MUX |= (4 << 13);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* PROBE - Look for an adapter, this routine's visible to the outside
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
static int p2001_eth_probe(struct dev *dev, unsigned short *probe_addrs __unused)
|
|
||||||
{
|
|
||||||
struct nic *nic = (struct nic *)dev;
|
|
||||||
/* if probe_addrs is 0, then routine can use a hardwired default */
|
|
||||||
|
|
||||||
/* reset phys and configure mdio clk */
|
|
||||||
printf("Resetting PHYs...\n");
|
|
||||||
p2001_eth_phyreset();
|
|
||||||
|
|
||||||
/* set management unit clock divisor */
|
|
||||||
// max. MDIO CLK = 2.048 MHz (EU.doc)
|
|
||||||
P2001_MU->MU_DIV = (SYSCLK/4096000)-1; // 2.048 MHz
|
|
||||||
//asm("nop \n nop");
|
|
||||||
|
|
||||||
/* find the correct PHY/DMA/MAC combination */
|
|
||||||
printf("Searching for P2001 NICs...\n");
|
|
||||||
cur_phy = -1;
|
|
||||||
for (cur_channel=0; cur_channel<4; cur_channel++) {
|
|
||||||
EU = P2001_EU(cur_channel);
|
|
||||||
|
|
||||||
/* find next phy */
|
|
||||||
while (++cur_phy < 16) {
|
|
||||||
//printf("phy detect %d\n", cur_phy);
|
|
||||||
if (p2001_eth_mdio_read(cur_phy, MII_BMSR) != 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (cur_phy == 16) {
|
|
||||||
printf("no more MII PHYs found\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* first a non destructive test for initial value RMAC_TLEN=1518 */
|
|
||||||
if (EU->RMAC_TLEN == 1518) {
|
|
||||||
printf("Checking EU%d...\n", cur_channel);
|
|
||||||
|
|
||||||
if (p2001_eth_check_link(cur_phy)) {
|
|
||||||
/* initialize device */
|
|
||||||
p2001_eth_init(nic);
|
|
||||||
|
|
||||||
/* set node address */
|
|
||||||
printf("Setting MAC address to %!\n", MAC_HW_ADDR);
|
|
||||||
memcpy(nic->node_addr, MAC_HW_ADDR, 6);
|
|
||||||
|
|
||||||
/* point to NIC specific routines */
|
|
||||||
dev->disable = p2001_eth_disable;
|
|
||||||
nic->poll = p2001_eth_poll;
|
|
||||||
nic->transmit = p2001_eth_transmit;
|
|
||||||
nic->irq = p2001_eth_irq;
|
|
||||||
|
|
||||||
/* Report the ISA pnp id of the board */
|
|
||||||
dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* else */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ISA_ROM("p2001_eth", "P2001 Ethernet Driver")
|
|
||||||
static struct isa_driver p2001_eth_driver __isa_driver = {
|
|
||||||
.type = NIC_DRIVER,
|
|
||||||
.name = "P2001 Ethernet Driver",
|
|
||||||
.probe = p2001_eth_probe,
|
|
||||||
.ioaddrs = 0,
|
|
||||||
};
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef ETHERBOOT_BITS_BYTESWAP_H
|
|
||||||
#define ETHERBOOT_BITS_BYTESWAP_H
|
|
||||||
|
|
||||||
/* We do not have byte swap functions ... We are
|
|
||||||
* RISC processor ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline unsigned short __swap16(volatile unsigned short v)
|
|
||||||
{
|
|
||||||
return ((v << 8) | (v >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int __swap32(volatile unsigned long v)
|
|
||||||
{
|
|
||||||
return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __bswap_constant_16(x) \
|
|
||||||
((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
|
|
||||||
(((uint16_t)(x) & 0xff00) >> 8)))
|
|
||||||
|
|
||||||
#define __bswap_constant_32(x) \
|
|
||||||
((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
|
|
||||||
(((uint32_t)(x) & 0x0000ff00U) << 8) | \
|
|
||||||
(((uint32_t)(x) & 0x00ff0000U) >> 8) | \
|
|
||||||
(((uint32_t)(x) & 0xff000000U) >> 24)))
|
|
||||||
|
|
||||||
# define __bswap_16(x) \
|
|
||||||
(__extension__ \
|
|
||||||
({ unsigned short int __bsx = (x); \
|
|
||||||
((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); }))
|
|
||||||
|
|
||||||
|
|
||||||
# define __bswap_32(x) \
|
|
||||||
(__extension__ \
|
|
||||||
({ unsigned int __bsx = (x); \
|
|
||||||
((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | \
|
|
||||||
(((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); }))
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_BYTESWAP_H */
|
|
|
@ -1,13 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef ARM_BITS_CPU_H
|
|
||||||
#define ARM_BITS_CPU_H
|
|
||||||
|
|
||||||
#define cpu_setup() do {} while(0)
|
|
||||||
|
|
||||||
#endif /* ARM_BITS_CPU_H */
|
|
|
@ -1,18 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef ARM_BITS_ELF_H
|
|
||||||
#define ARM_BITS_ELF_H
|
|
||||||
|
|
||||||
/* ELF Defines for the current architecture */
|
|
||||||
#define EM_CURRENT EM_ARM
|
|
||||||
#define ELFDATA_CURRENT ELFDATA2LSB
|
|
||||||
|
|
||||||
#define ELF_CHECK_ARCH(x) \
|
|
||||||
((x).e_machine == EM_CURRENT)
|
|
||||||
|
|
||||||
#endif /* ARM_BITS_ELF_H */
|
|
|
@ -1,17 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef ETHERBOOT_BITS_ENDIAN_H
|
|
||||||
#define ETHERBOOT_BITS_ENDIAN_H
|
|
||||||
|
|
||||||
#ifdef __ARMEB__
|
|
||||||
#define __BYTE_ORDER __BIG_ENDIAN
|
|
||||||
#else
|
|
||||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_ENDIAN_H */
|
|
|
@ -1,11 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef ETHERBOOT_BITS_STRING_H
|
|
||||||
#define ETHERBOOT_BITS_STRING_H
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_STRING_H */
|
|
|
@ -1 +0,0 @@
|
||||||
/* empty file */
|
|
|
@ -1,170 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Architecture: ARM9TDMI
|
|
||||||
* Processor : P2001
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARCH_HARDWARE_H
|
|
||||||
#define ARCH_HARDWARE_H
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
|
|
||||||
/* DMA descriptor */
|
|
||||||
typedef struct {
|
|
||||||
unsigned int stat; /* status: own, start, end, offset, status */
|
|
||||||
unsigned int cntl; /* control: loop, int, type, channel, length */
|
|
||||||
char *buf; /* buffer */
|
|
||||||
void *next; /* nextdsc */
|
|
||||||
} DMA_DSC;
|
|
||||||
|
|
||||||
|
|
||||||
/* The address definitions are from asic_bf.h */
|
|
||||||
typedef struct { // 0x00100000U
|
|
||||||
volatile unsigned int reserved1[0x3];
|
|
||||||
volatile unsigned int ArmDmaPri; // 0x0000000CU
|
|
||||||
volatile unsigned int SDRAM_Ctrl; // 0x00000010U
|
|
||||||
volatile unsigned int ExtMem_Ctrl; // 0x00000014U
|
|
||||||
volatile unsigned int WaitState_Ext; // 0x00000018U
|
|
||||||
volatile unsigned int WaitState_Asic; // 0x0000001CU
|
|
||||||
volatile unsigned int TOP; // 0x00000020U
|
|
||||||
volatile unsigned int reserved2[0x3];
|
|
||||||
volatile unsigned int Adr1_EQ_30Bit; // 0x00000030U
|
|
||||||
volatile unsigned int Adr2_EQ_30Bit; // 0x00000034U
|
|
||||||
volatile unsigned int Adr3_EQ_30Bit; // 0x00000038U
|
|
||||||
volatile unsigned int Dat3_EQ_32Bit; // 0x0000003CU
|
|
||||||
volatile unsigned int Adr4_HE_20Bit; // 0x00000040U
|
|
||||||
volatile unsigned int Adr4_LT_20Bit; // 0x00000044U
|
|
||||||
volatile unsigned int Adr5_HE_20Bit; // 0x00000048U
|
|
||||||
volatile unsigned int Adr5_LT_20Bit; // 0x0000004CU
|
|
||||||
volatile unsigned int Adr_Control; // 0x00000050U
|
|
||||||
volatile unsigned int ABORT_IA_32Bit; // 0x00000054U
|
|
||||||
} *P2001_SYS_regs_ptr;
|
|
||||||
#define P2001_SYS ((volatile P2001_SYS_regs_ptr) 0x00100000)
|
|
||||||
|
|
||||||
typedef struct { // 0x00110000U
|
|
||||||
volatile unsigned int Timer1; // 0x00000000U
|
|
||||||
volatile unsigned int Timer2; // 0x00000004U
|
|
||||||
volatile unsigned int TIMER_PRELOAD; // 0x00000008U
|
|
||||||
volatile unsigned int Timer12_PreDiv; // 0x0000000CU
|
|
||||||
volatile unsigned int TIMER_INT; // 0x00000010U
|
|
||||||
volatile unsigned int Freerun_Timer; // 0x00000014U
|
|
||||||
volatile unsigned int WatchDog_Timer; // 0x00000018U
|
|
||||||
volatile unsigned int PWM_CNT; // 0x00000020U
|
|
||||||
volatile unsigned int PWM_CNT2; // 0x00000024U
|
|
||||||
volatile unsigned int PLL_12000_config; // 0x00000030U
|
|
||||||
volatile unsigned int PLL_12288_config; // 0x00000034U
|
|
||||||
volatile unsigned int DIV_12288_config; // 0x00000038U
|
|
||||||
volatile unsigned int MOD_CNT_768; // 0x0000003CU
|
|
||||||
volatile unsigned int FSC_IRQ_STATUS; // 0x00000040U
|
|
||||||
volatile unsigned int FSC_CONFIG; // 0x00000044U
|
|
||||||
volatile unsigned int FSC_CONSTRUCT; // 0x00000048U
|
|
||||||
volatile unsigned int FSC_base_clk_reg; // 0x0000004CU
|
|
||||||
volatile unsigned int SYSCLK_SHAPE; // 0x00000050U
|
|
||||||
volatile unsigned int SDRAMCLK_SHAPE; // 0x00000054U
|
|
||||||
volatile unsigned int RING_OSZI; // 0x00000058U
|
|
||||||
} *P2001_TIMER_regs_ptr;
|
|
||||||
#define P2001_TIMER ((volatile P2001_TIMER_regs_ptr) 0x00110000)
|
|
||||||
|
|
||||||
typedef struct { // 0x00120000U
|
|
||||||
volatile unsigned int reserved1[0x5];
|
|
||||||
volatile unsigned int GPIO_Config; // 0x00000014U
|
|
||||||
volatile unsigned int GPIO_INT; // 0x00000018U
|
|
||||||
volatile unsigned int GPIO_Out; // 0x0000001CU
|
|
||||||
volatile unsigned int GPIO_IN; // 0x00000020U
|
|
||||||
volatile unsigned int GPIO_En; // 0x00000024U
|
|
||||||
volatile unsigned int PIN_MUX; // 0x00000028U
|
|
||||||
volatile unsigned int NRES_OUT; // 0x0000002CU
|
|
||||||
volatile unsigned int GPIO2_Out; // 0x00000030U
|
|
||||||
volatile unsigned int GPIO2_IN; // 0x00000034U
|
|
||||||
volatile unsigned int GPIO2_En; // 0x00000038U
|
|
||||||
volatile unsigned int GPIO_INT_SEL; // 0x0000003CU
|
|
||||||
volatile unsigned int GPI3_IN; // 0x00000040U
|
|
||||||
volatile unsigned int GPO4_OUT; // 0x00000044U
|
|
||||||
} *P2001_GPIO_regs_ptr;
|
|
||||||
#define P2001_GPIO ((volatile P2001_GPIO_regs_ptr) 0x00120000)
|
|
||||||
|
|
||||||
typedef struct { // 0x00130000U
|
|
||||||
volatile unsigned int Main_NFIQ_Int_Ctrl; // 0x00000000U
|
|
||||||
volatile unsigned int Main_NIRQ_Int_Ctrl; // 0x00000004U
|
|
||||||
volatile unsigned int Status_NFIQ; // 0x00000008U
|
|
||||||
volatile unsigned int Status_NIRQ; // 0x0000000CU
|
|
||||||
} *P2001_INT_CTRL_regs_ptr;
|
|
||||||
#define P2001_INT_CTRL ((volatile P2001_INT_CTRL_regs_ptr) 0x00130000)
|
|
||||||
|
|
||||||
typedef union { // 0x00140000U
|
|
||||||
struct { // write
|
|
||||||
volatile unsigned int TX[4]; // 0x00000000-0x000CU
|
|
||||||
volatile unsigned int Baudrate; // 0x00000010U
|
|
||||||
volatile unsigned int reserved1[0x3];
|
|
||||||
volatile unsigned int Config; // 0x00000020U
|
|
||||||
volatile unsigned int Clear; // 0x00000024U
|
|
||||||
volatile unsigned int Echo_EN; // 0x00000028U
|
|
||||||
volatile unsigned int IRQ_Status; // 0x0000002CU
|
|
||||||
} w; // write
|
|
||||||
|
|
||||||
struct { // read
|
|
||||||
volatile unsigned int RX[4]; // 0x00000000-0x000CU
|
|
||||||
volatile unsigned int reserved1[0x4];
|
|
||||||
volatile unsigned int PRE_STATUS; // 0x00000020U
|
|
||||||
volatile unsigned int STATUS; // 0x00000024U
|
|
||||||
volatile unsigned int reserved2[0x1];
|
|
||||||
volatile unsigned int IRQ_Status; // 0x0000002CU
|
|
||||||
} r; // read
|
|
||||||
} *P2001_UART_regs_ptr;
|
|
||||||
#define P2001_UART ((volatile P2001_UART_regs_ptr) 0x00140000)
|
|
||||||
|
|
||||||
typedef struct { // 0x0018_000U _=0,1,2,3
|
|
||||||
volatile DMA_DSC * RMAC_DMA_DESC; // 0x00000000U
|
|
||||||
volatile unsigned int RMAC_DMA_CNTL; // 0x00000004U
|
|
||||||
volatile unsigned int RMAC_DMA_STAT; // 0x00000008U
|
|
||||||
volatile unsigned int RMAC_DMA_EN; // 0x0000000CU
|
|
||||||
volatile unsigned int RMAC_CNTL; // 0x00000010U
|
|
||||||
volatile unsigned int RMAC_TLEN; // 0x00000014U
|
|
||||||
volatile unsigned int RMAC_PHYU; // 0x00000018U
|
|
||||||
volatile unsigned int RMAC_PHYL; // 0x0000001CU
|
|
||||||
volatile unsigned int RMAC_PFM0; // 0x00000020U
|
|
||||||
volatile unsigned int RMAC_PFM1; // 0x00000024U
|
|
||||||
volatile unsigned int RMAC_PFM2; // 0x00000028U
|
|
||||||
volatile unsigned int RMAC_PFM3; // 0x0000002CU
|
|
||||||
volatile unsigned int RMAC_PFM4; // 0x00000030U
|
|
||||||
volatile unsigned int RMAC_PFM5; // 0x00000034U
|
|
||||||
volatile unsigned int RMAC_PFM6; // 0x00000038U
|
|
||||||
volatile unsigned int RMAC_PFM7; // 0x0000003CU
|
|
||||||
volatile unsigned int RMAC_MIB0; // 0x00000040U
|
|
||||||
volatile unsigned int RMAC_MIB1; // 0x00000044U
|
|
||||||
volatile unsigned int RMAC_MIB2; // 0x00000048U
|
|
||||||
volatile unsigned int RMAC_MIB3; // 0x0000004CU
|
|
||||||
volatile unsigned int RMAC_MIB4; // 0x00000050U
|
|
||||||
volatile unsigned int RMAC_MIB5; // 0x00000054U
|
|
||||||
volatile unsigned int reserved1[0x1e8];
|
|
||||||
volatile unsigned int RMAC_DMA_DATA; // 0x000007F8U
|
|
||||||
volatile unsigned int RMAC_DMA_ADR; // 0x000007FCU
|
|
||||||
volatile DMA_DSC * TMAC_DMA_DESC; // 0x00000800U
|
|
||||||
volatile unsigned int TMAC_DMA_CNTL; // 0x00000804U
|
|
||||||
volatile unsigned int TMAC_DMA_STAT; // 0x00000808U
|
|
||||||
volatile unsigned int TMAC_DMA_EN; // 0x0000080CU
|
|
||||||
volatile unsigned int TMAC_CNTL; // 0x00000810U
|
|
||||||
volatile unsigned int TMAC_MIB6; // 0x00000814U
|
|
||||||
volatile unsigned int TMAC_MIB7; // 0x00000818U
|
|
||||||
volatile unsigned int reserved2[0x1];
|
|
||||||
volatile unsigned int MU_CNTL; // 0x00000820U
|
|
||||||
volatile unsigned int MU_DATA; // 0x00000824U
|
|
||||||
volatile unsigned int MU_DIV; // 0x00000828U
|
|
||||||
volatile unsigned int CONF_RMII; // 0x0000082CU
|
|
||||||
volatile unsigned int reserved3[0x1f2];
|
|
||||||
volatile unsigned int TMAC_DMA_DATA; // 0x00000FF8U
|
|
||||||
volatile unsigned int TMAC_DMA_ADR; // 0x00000FFCU
|
|
||||||
} *P2001_ETH_regs_ptr;
|
|
||||||
#define P2001_EU(x) ((volatile P2001_ETH_regs_ptr) ((unsigned int) 0x00180000UL+(0x1000UL*(x)))) /* x = 0..3 */
|
|
||||||
#define P2001_MU P2001_EU(0)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ARCH_HARDWARE_H */
|
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef ETHERBOOT_ARM_HOOKS_H
|
|
||||||
#define ETHERBOOT_ARM_HOOKS_H
|
|
||||||
|
|
||||||
struct Elf_Bhdr;
|
|
||||||
|
|
||||||
#define arch_main(data, params) do {} while(0)
|
|
||||||
//void arch_main(in_call_data_t *data, va_list params);
|
|
||||||
|
|
||||||
#define arch_on_exit(status) do {} while(0)
|
|
||||||
//void arch_on_exit(int status);
|
|
||||||
|
|
||||||
#define arch_relocate_to(addr) do {} while(0)
|
|
||||||
//void arch_relocate_to(unsigned long addr);
|
|
||||||
|
|
||||||
#define arch_relocated_from(old_addr) do {} while(0)
|
|
||||||
//void arch_relocate_from(unsigned long old_addr);
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_ARM_HOOKS_H */
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef ETHERBOOT_IO_H
|
|
||||||
#define ETHERBOOT_IO_H
|
|
||||||
|
|
||||||
#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
|
|
||||||
#define phys_to_virt(vaddr) ((void *) (vaddr))
|
|
||||||
|
|
||||||
#define virt_to_bus virt_to_phys
|
|
||||||
#define bus_to_virt phys_to_virt
|
|
||||||
|
|
||||||
#define iounmap(addr) ((void)0)
|
|
||||||
#define ioremap(physaddr, size) (physaddr)
|
|
||||||
|
|
||||||
extern unsigned char inb (unsigned long int port);
|
|
||||||
extern unsigned short int inw (unsigned long int port);
|
|
||||||
extern unsigned long int inl (unsigned long int port);
|
|
||||||
extern void outb (unsigned char value, unsigned long int port);
|
|
||||||
extern void outw (unsigned short value, unsigned long int port);
|
|
||||||
extern void outl (unsigned long value, unsigned long int port);
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_IO_H */
|
|
|
@ -1,15 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef LATCH_H
|
|
||||||
#define LATCH_H
|
|
||||||
|
|
||||||
// Freerun_Timer is always at 12.288 MHZ
|
|
||||||
#define TICKS_PER_SEC (12288000UL)
|
|
||||||
//#define TICKS_PER_SEC (73728000UL)
|
|
||||||
|
|
||||||
#endif /* LATCH_H */
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef __LIMITS_H
|
|
||||||
#define __LIMITS_H 1
|
|
||||||
|
|
||||||
#define MB_LEN_MAX 16
|
|
||||||
|
|
||||||
#define CHAR_BIT 8
|
|
||||||
|
|
||||||
#define SCHAR_MIN (-128)
|
|
||||||
#define SCHAR_MAX 127
|
|
||||||
|
|
||||||
#define UCHAR_MAX 255
|
|
||||||
|
|
||||||
#define CHAR_MIN SCHAR_MIN
|
|
||||||
#define CHAR_MAX SCHAR_MAX
|
|
||||||
|
|
||||||
#define SHRT_MIN (-32768)
|
|
||||||
#define SHRT_MAX 32767
|
|
||||||
|
|
||||||
#define USHRT_MAX 65535
|
|
||||||
|
|
||||||
#define INT_MIN (-INT_MAX - 1)
|
|
||||||
#define INT_MAX 2147483647
|
|
||||||
|
|
||||||
#define UINT_MAX 4294967295U
|
|
||||||
|
|
||||||
#define LONG_MAX 2147483647L
|
|
||||||
#define LONG_MIN (-LONG_MAX - 1L)
|
|
||||||
|
|
||||||
#define ULONG_MAX 4294967295UL
|
|
||||||
|
|
||||||
#define LLONG_MAX 9223372036854775807LL
|
|
||||||
#define LLONG_MIN (-LLONG_MAX - 1LL)
|
|
||||||
|
|
||||||
#define ULLONG_MAX 18446744073709551615ULL
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef ETHERBOOT_SETJMP_H
|
|
||||||
#define ETHERBOOT_SETJMP_H
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
/* Jump buffer contains v1-v6, sl, fp, sp and pc. Other registers are not
|
|
||||||
saved. */
|
|
||||||
//typedef int jmp_buf[22];
|
|
||||||
typedef int jmp_buf[10];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int sigsetjmp(jmp_buf __env, int __savemask);
|
|
||||||
extern void longjmp(jmp_buf __env, int __val) __attribute__((__noreturn__));
|
|
||||||
|
|
||||||
#define setjmp(env) sigsetjmp(env,0)
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_SETJMP_H */
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2004 Tobias Lorenz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#ifndef STDINT_H
|
|
||||||
#define STDINT_H
|
|
||||||
|
|
||||||
typedef unsigned long size_t;
|
|
||||||
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef unsigned long uint32_t;
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef signed short int16_t;
|
|
||||||
typedef signed int int32_t;
|
|
||||||
typedef signed long long int64_t;
|
|
||||||
|
|
||||||
typedef signed char s8;
|
|
||||||
typedef unsigned char u8;
|
|
||||||
|
|
||||||
typedef signed short s16;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
|
|
||||||
typedef signed long s32;
|
|
||||||
typedef unsigned int u32;
|
|
||||||
|
|
||||||
typedef signed long long s64;
|
|
||||||
typedef unsigned long long u64;
|
|
||||||
|
|
||||||
#endif /* STDINT_H */
|
|
|
@ -1,7 +0,0 @@
|
||||||
# Config for e1 Etherboot
|
|
||||||
#
|
|
||||||
|
|
||||||
CFLAGS+= -mgnu-param -DCONSOLE_SERIAL -DCOMCONSOLE=0x01C00000 -DCONSPEED=28800
|
|
||||||
CFLAGS+= -DSIZEINDICATOR -DNO_DHCP_SUPPORT -DBAR_PROGRESS
|
|
||||||
#CFLAGS+= -DEMBEDDED -DMAC_HW_ADDR_DRV="'H','Y','L','N','X','1'"
|
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
ARCH_FORMAT= coff-e1
|
|
||||||
|
|
||||||
BUILD_ROMS= $(ROMS)
|
|
||||||
BUILD_COFFS= $(patsubst %img, %coff, $(IMGS))
|
|
||||||
SUFFIXES+= rom zrom coff
|
|
||||||
|
|
||||||
CC= e1-coff-gcc
|
|
||||||
AS= e1-coff-as
|
|
||||||
LD= e1-coff-ld
|
|
||||||
SIZE= e1-coff-size
|
|
||||||
AR= e1-coff-ar
|
|
||||||
RANLIB= e1-coff-ranlib
|
|
||||||
OBJCOPY=e1-coff-objcopy
|
|
||||||
|
|
||||||
# DMAC_HW_ADDR_DRV holds the ethernet's MAC address. It is passed as
|
|
||||||
# flag to the low level driver instead of reading it from an
|
|
||||||
# external EEPROM, which we do not have!
|
|
||||||
EXTRA_CFLAGS = -DEMBEDDED -DMAC_HW_ADDR_DRV="'H','Y','L','N','X','1'"
|
|
||||||
|
|
||||||
START= $(BIN)/start.o
|
|
||||||
START16= $(BIN)/start.o
|
|
||||||
|
|
||||||
SRCS+= arch/e1/core/e132_xs.c
|
|
||||||
SRCS+= arch/e1/core/e1_timer.c
|
|
||||||
SRCS+= arch/e1/core/longjmp.c
|
|
||||||
SRCS+= arch/e1/core/memcmp.S
|
|
||||||
SRCS+= arch/e1/core/memcpy.S
|
|
||||||
SRCS+= arch/e1/core/memset.S
|
|
||||||
SRCS+= arch/e1/core/setjmp.c
|
|
||||||
SRCS+= arch/e1/core/strcmp.S
|
|
||||||
SRCS+= arch/e1/core/start.S
|
|
||||||
|
|
||||||
ROMLIMIT:=3276800
|
|
||||||
|
|
||||||
include $(BIN)/Roms
|
|
||||||
|
|
||||||
ROMS= $(BIN)/cs89x0.rom
|
|
||||||
IMGS= $(BIN)/cs89x0.img
|
|
||||||
|
|
||||||
#allfiles: $(BUILD_ROMS)
|
|
||||||
all: $(BUILD_COFFS)
|
|
||||||
|
|
||||||
BOBJS+= $(BIN)/e1_timer.o
|
|
||||||
BOBJS+= $(BIN)/memcmp.o $(BIN)/memcpy.o $(BIN)/memset.o
|
|
||||||
BOBJS+= $(BIN)/setjmp.o $(BIN)/longjmp.o
|
|
||||||
BOBJS+= $(BIN)/e132_xs.o
|
|
||||||
|
|
||||||
# Utilities
|
|
||||||
|
|
||||||
$(BIN)/nrv2b: util/nrv2b.c
|
|
||||||
$(HOST_CC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG -DBITSIZE=32 -DENDIAN=0 -o $@ $<
|
|
||||||
|
|
||||||
# Pattern Rules
|
|
||||||
# General for compiling/assembly source files
|
|
||||||
$(BIN)/cs89x0.o: drivers/net/cs89x0.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -o $@ -c $<
|
|
||||||
# With the current tools we have problem with the compilation
|
|
||||||
# of the vsprintf file when the -O2 is selected. So we compile
|
|
||||||
# the aforemntioned file with -O1 !!!
|
|
||||||
$(BIN)/vsprintf.o: core/vsprintf.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) -O1 -o $@ -c $<
|
|
||||||
|
|
||||||
$(BIN)/%.o: arch/e1/core/%.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
$(BIN)/%.o: arch/e1/core/%.S $(MAKEDEPS)
|
|
||||||
$(CPP) $(CFLAGS) -D ASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/%.coff: $(BIN)/%.tmp $(MAKEDEPS)
|
|
||||||
mv $< $(BIN)/etherboot.coff
|
|
|
@ -1,67 +0,0 @@
|
||||||
ARCH_FORMAT= coff-e1
|
|
||||||
|
|
||||||
CC= e1-coff-gcc
|
|
||||||
AS= e1-coff-as
|
|
||||||
LD= e1-coff-ld
|
|
||||||
SIZE= e1-coff-size
|
|
||||||
AR= e1-coff-ar
|
|
||||||
RANLIB= e1-coff-ranlib
|
|
||||||
OBJCOPY=e1-coff-objcopy
|
|
||||||
|
|
||||||
EXTRA_CFLAGS = -DEMBEDDED -DMAC_HW_ADDR_DRV="'H','Y','L','N','X','1'"
|
|
||||||
|
|
||||||
BUILD_ROMS= $(ROMS)
|
|
||||||
BUILD_COFFS= $(BIN)/cs89x0.coff
|
|
||||||
#BUILD_COFFS= $(patsubst %img, %coff, $(IMGS))
|
|
||||||
|
|
||||||
START= $(BIN)/start.o
|
|
||||||
START16= $(BIN)/start.o
|
|
||||||
|
|
||||||
#SRCS+= arch/e1/core/coff_loader.c
|
|
||||||
SRCS+= arch/e1/core/e132_xs.c
|
|
||||||
SRCS+= arch/e1/core/e1_timer.c
|
|
||||||
SRCS+= arch/e1/core/longjmp.c
|
|
||||||
SRCS+= arch/e1/core/memcmp.S
|
|
||||||
SRCS+= arch/e1/core/memcpy.S
|
|
||||||
SRCS+= arch/e1/core/memset.S
|
|
||||||
SRCS+= arch/e1/core/setjmp.c
|
|
||||||
SRCS+= arch/e1/core/strcmp.S
|
|
||||||
SRCS+= arch/e1/core/start.S
|
|
||||||
|
|
||||||
ROMLIMIT:=3276800
|
|
||||||
|
|
||||||
include $(BIN)/Roms
|
|
||||||
|
|
||||||
hyperstone: $(BUILD_COFFS)
|
|
||||||
coff: $(BUILD_COFFS)
|
|
||||||
|
|
||||||
BOBJS+= $(BIN)/e1_timer.o
|
|
||||||
BOBJS+= $(BIN)/memcmp.o $(BIN)/memcpy.o $(BIN)/memset.o
|
|
||||||
BOBJS+= $(BIN)/setjmp.o $(BIN)/longjmp.o
|
|
||||||
BOBJS+= $(BIN)/e132_xs.o
|
|
||||||
|
|
||||||
# Utilities
|
|
||||||
|
|
||||||
$(BIN)/nrv2b: util/nrv2b.c
|
|
||||||
$(HOST_CC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG -DBITSIZE=32 -DENDIAN=0 -o $@ $<
|
|
||||||
|
|
||||||
# Pattern Rules
|
|
||||||
# General for compiling/assembly source files
|
|
||||||
|
|
||||||
$(BIN)/cs89x0.o: drivers/net/cs89x0.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -o $@ -c $<
|
|
||||||
# With the current tools we have problem with the compilation
|
|
||||||
# of the vsprintf file when the -O2 is selected. So we compile
|
|
||||||
# the aforemntioned file with -O1 !!!
|
|
||||||
$(BIN)/vsprintf.o: core/vsprintf.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) -O1 -o $@ -c $<
|
|
||||||
|
|
||||||
$(BIN)/%.o: arch/e1/core/%.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
$(BIN)/%.o: arch/e1/core/%.S $(MAKEDEPS)
|
|
||||||
$(CPP) $(CFLAGS) -D ASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/%.coff: $(BIN)/%.tmp $(MAKEDEPS)
|
|
||||||
mv $< $(BIN)/etherboot.coff
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
Introduction
|
|
||||||
---------------------
|
|
||||||
This README file provides guideliness to compile successfully the
|
|
||||||
Etherboot for Hyperstone.
|
|
||||||
This directory (src/arch/e1) contains the files that depend on
|
|
||||||
Hyperstone's architecture. The header files that include the
|
|
||||||
configuration of the system are based on Hyperstone's E132-XS
|
|
||||||
development board. The can be very easily modified to support
|
|
||||||
anyother configuration environment.
|
|
||||||
|
|
||||||
Software Perquisites:
|
|
||||||
---------------------
|
|
||||||
The build environment requires a C compiler for the E1-32XS
|
|
||||||
processor. Normally you can simply install a cross-compiling tool
|
|
||||||
chain based on the GNU tools (that is binutils and gcc). If you
|
|
||||||
are running a Linux system on a x86 CPU then you can just download
|
|
||||||
the toolchain as a binary from Hyperstone's official web-site. The
|
|
||||||
binary distribution will untar the tools in the /usr/local/e1-coff
|
|
||||||
directory. On any other system you will need to build the tool
|
|
||||||
chain from the sources.
|
|
||||||
|
|
||||||
To compile successfully the following tools should be available:
|
|
||||||
- GNU toolchain:
|
|
||||||
- GCC ver 2.95.2 20030110 (release) e1-coff-gcc -v
|
|
||||||
- LD ver 2.12.90 20020726 e1-coff-ld -V
|
|
||||||
|
|
||||||
Hardware Perquisites:
|
|
||||||
---------------------
|
|
||||||
The etherboot has been successfully tested in the E1-32XS
|
|
||||||
development board. A second serial device is initialized
|
|
||||||
to act as a console. The standard messages
|
|
||||||
are redirected to the console. Nevertheless, if one wants not
|
|
||||||
to use the serial console he may omit the corresponding switches
|
|
||||||
from the Config file located under "src/arch/e1/" directory.
|
|
||||||
|
|
||||||
On the E1-32XS board that was used, a daughter-board was employed
|
|
||||||
to connect a second HyIce to the development board. Since the HyIce
|
|
||||||
embeds a standard 16550 device, the Etherboot's standard device
|
|
||||||
driver is used.
|
|
||||||
|
|
||||||
The position of the jumpers of the development board in order to
|
|
||||||
initialize both the second HyIce and the Ethernet device is
|
|
||||||
depicted in the following table:
|
|
||||||
|
|
||||||
Jumper: Position
|
|
||||||
------:--------------
|
|
||||||
J3 1-2 (default)
|
|
||||||
J4 1-2 (default)
|
|
||||||
J13 5-6
|
|
||||||
J5 1-2 (default)
|
|
||||||
J6 1-2 & 3-4
|
|
||||||
J7 3-4
|
|
||||||
J9 1-2 (default)
|
|
||||||
J10 1-2
|
|
||||||
J11 3-4
|
|
||||||
|
|
||||||
Compilation
|
|
||||||
---------------------
|
|
||||||
In order to compile Etherboot for Hyperstone, the following steps should be followed:
|
|
||||||
1) Edit the main Makefile (located under "src" directory") and comment-out
|
|
||||||
the ARCH variable (by putting a "#" in front of it). Append the following line:
|
|
||||||
ARCH:=e1
|
|
||||||
2) Edit the Config file (the one located under "src" directory) and make sure that
|
|
||||||
the CFLAGS variable will contain *only* the following swithces:
|
|
||||||
CFLAGS+= -DCONFIG_ISA
|
|
||||||
CFLAGS+= -DBOOT_FIRST=BOOT_NIC
|
|
||||||
CFLAGS+= -DALLOW_ONLY_ENCAPSULATED
|
|
||||||
CFLAGS+= -DBACKOFF_LIMIT=7 -DCONGESTED
|
|
||||||
CFLAGS+= -DCOFF_IMAGE
|
|
||||||
CFLAGS+= -DDOWNLOAD_PROTO_TFTP
|
|
||||||
Please note that extra or any other switches may cause failure of compilation!
|
|
||||||
3) type "make hyperstone" or "make coff"
|
|
||||||
4) the generated file will be located under the "src/bin" directory and will be called :
|
|
||||||
"etherboot.coff". Now you may download it with usual way using e1-coff-gdb ..
|
|
||||||
|
|
||||||
Have Fun
|
|
||||||
|
|
||||||
Yannis Mitsos, George Thanos
|
|
||||||
{gmitsos,gthanos}@telecom.ntua.gr
|
|
||||||
|
|
|
@ -1,176 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2003 Yannis Mitsos and George Thanos
|
|
||||||
* {gmitsos@gthanos}@telecom.ntua.gr
|
|
||||||
* Released under GPL2, see the file COPYING in the top directory
|
|
||||||
* COFF loader is based on the source code of the ELF loader.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "coff.h"
|
|
||||||
|
|
||||||
#define COFF_DEBUG 0
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
COFF_filehdr coff32;
|
|
||||||
COFF_opthdr opthdr32;
|
|
||||||
union {
|
|
||||||
COFF_scnhdr scnhdr32[1];
|
|
||||||
unsigned char dummy[1024];
|
|
||||||
} p;
|
|
||||||
unsigned long curaddr;
|
|
||||||
signed int segment; /* current segment number, -1 for none */
|
|
||||||
unsigned int loc; /* start offset of current block */
|
|
||||||
unsigned int skip; /* padding to be skipped to current segment */
|
|
||||||
unsigned long toread; /* remaining data to be read in the segment */
|
|
||||||
}coff_state;
|
|
||||||
|
|
||||||
coff_state cstate;
|
|
||||||
|
|
||||||
static sector_t coff32_download(unsigned char *data, unsigned int len, int eof);
|
|
||||||
static inline os_download_t coff_probe(unsigned char *data, unsigned int len)
|
|
||||||
{
|
|
||||||
unsigned long phdr_size;
|
|
||||||
|
|
||||||
if (len < (sizeof(cstate.coff32)+ sizeof(cstate.opthdr32))) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(&cstate.coff32, data, (sizeof(cstate.coff32)+sizeof(cstate.opthdr32)));
|
|
||||||
|
|
||||||
if ((cstate.coff32.f_magic != EM_E1) ||
|
|
||||||
(cstate.opthdr32.magic != O_MAGIC)){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
printf("(COFF");
|
|
||||||
printf(")... \n");
|
|
||||||
|
|
||||||
if (cstate.coff32.f_opthdr == 0){
|
|
||||||
printf("No optional header in COFF file, cannot find the entry point\n");
|
|
||||||
return dead_download;
|
|
||||||
}
|
|
||||||
|
|
||||||
phdr_size = cstate.coff32.f_nscns * sizeof(cstate.p.scnhdr32);
|
|
||||||
if (sizeof(cstate.coff32) + cstate.coff32.f_opthdr + phdr_size > len) {
|
|
||||||
printf("COFF header outside first block\n");
|
|
||||||
return dead_download;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&cstate.p.scnhdr32, data + (sizeof(cstate.coff32) + cstate.coff32.f_opthdr), phdr_size);
|
|
||||||
|
|
||||||
/* Check for Etherboot related limitations. Memory
|
|
||||||
* between _text and _end is not allowed.
|
|
||||||
* Reasons: the Etherboot code/data area.
|
|
||||||
*/
|
|
||||||
for (cstate.segment = 0; cstate.segment < cstate.coff32.f_nscns; cstate.segment++) {
|
|
||||||
unsigned long start, mid, end, istart, iend;
|
|
||||||
|
|
||||||
if ((cstate.p.scnhdr32[cstate.segment].s_flags != S_TYPE_TEXT) &&
|
|
||||||
(cstate.p.scnhdr32[cstate.segment].s_flags != S_TYPE_DATA) &&
|
|
||||||
(cstate.p.scnhdr32[cstate.segment].s_flags != S_TYPE_BSS)){ /* Do we realy need to check the BSS section ? */
|
|
||||||
#ifdef COFF_DEBUG
|
|
||||||
printf("Section <%s> in not a loadable section \n",cstate.p.scnhdr32[cstate.segment].s_name);
|
|
||||||
#endif
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
start = cstate.p.scnhdr32[cstate.segment].s_paddr;
|
|
||||||
mid = start + cstate.p.scnhdr32[cstate.segment].s_size;
|
|
||||||
end = start + cstate.p.scnhdr32[cstate.segment].s_size;
|
|
||||||
|
|
||||||
/* Do we need the following variables ? */
|
|
||||||
istart = 0x8000;
|
|
||||||
iend = 0x8000;
|
|
||||||
|
|
||||||
if (!prep_segment(start, mid, end, istart, iend)) {
|
|
||||||
return dead_download;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cstate.segment = -1;
|
|
||||||
cstate.loc = 0;
|
|
||||||
cstate.skip = 0;
|
|
||||||
cstate.toread = 0;
|
|
||||||
return coff32_download;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int mach_boot(unsigned long entry_point);
|
|
||||||
static sector_t coff32_download(unsigned char *data, unsigned int len, int eof)
|
|
||||||
{
|
|
||||||
unsigned long skip_sectors = 0;
|
|
||||||
unsigned int offset; /* working offset in the current data block */
|
|
||||||
int i;
|
|
||||||
|
|
||||||
offset = 0;
|
|
||||||
do {
|
|
||||||
if (cstate.segment != -1) {
|
|
||||||
if (cstate.skip) {
|
|
||||||
if (cstate.skip >= len - offset) {
|
|
||||||
cstate.skip -= len - offset;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
offset += cstate.skip;
|
|
||||||
cstate.skip = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cstate.toread) {
|
|
||||||
unsigned int cplen;
|
|
||||||
cplen = len - offset;
|
|
||||||
if (cplen >= cstate.toread) {
|
|
||||||
cplen = cstate.toread;
|
|
||||||
}
|
|
||||||
memcpy(phys_to_virt(cstate.curaddr), data+offset, cplen);
|
|
||||||
cstate.curaddr += cplen;
|
|
||||||
cstate.toread -= cplen;
|
|
||||||
offset += cplen;
|
|
||||||
if (cstate.toread)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data left, but current segment finished - look for the next
|
|
||||||
* segment (in file offset order) that needs to be loaded.
|
|
||||||
* We can only seek forward, so select the program headers,
|
|
||||||
* in the correct order.
|
|
||||||
*/
|
|
||||||
cstate.segment = -1;
|
|
||||||
for (i = 0; i < cstate.coff32.f_nscns; i++) {
|
|
||||||
|
|
||||||
if ((cstate.p.scnhdr32[i].s_flags != S_TYPE_TEXT) &&
|
|
||||||
(cstate.p.scnhdr32[i].s_flags != S_TYPE_DATA))
|
|
||||||
continue;
|
|
||||||
if (cstate.p.scnhdr32[i].s_size == 0)
|
|
||||||
continue;
|
|
||||||
if (cstate.p.scnhdr32[i].s_scnptr < cstate.loc + offset)
|
|
||||||
continue; /* can't go backwards */
|
|
||||||
if ((cstate.segment != -1) &&
|
|
||||||
(cstate.p.scnhdr32[i].s_scnptr >= cstate.p.scnhdr32[cstate.segment].s_scnptr))
|
|
||||||
continue; /* search minimum file offset */
|
|
||||||
cstate.segment = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cstate.segment == -1) {
|
|
||||||
/* No more segments to be loaded, so just start the
|
|
||||||
* kernel. This saves a lot of network bandwidth if
|
|
||||||
* debug info is in the kernel but not loaded. */
|
|
||||||
goto coff_startkernel;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cstate.curaddr = cstate.p.scnhdr32[cstate.segment].s_paddr;
|
|
||||||
cstate.skip = cstate.p.scnhdr32[cstate.segment].s_scnptr - (cstate.loc + offset);
|
|
||||||
cstate.toread = cstate.p.scnhdr32[cstate.segment].s_size;
|
|
||||||
#if COFF_DEBUG
|
|
||||||
printf("PHDR %d, size %#lX, curaddr %#lX\n",
|
|
||||||
cstate.segment, cstate.toread, cstate.curaddr);
|
|
||||||
#endif
|
|
||||||
} while (offset < len);
|
|
||||||
|
|
||||||
cstate.loc += len + (cstate.skip & ~0x1ff);
|
|
||||||
skip_sectors = cstate.skip >> 9;
|
|
||||||
cstate.skip &= 0x1ff;
|
|
||||||
|
|
||||||
if (eof) {
|
|
||||||
unsigned long entry;
|
|
||||||
coff_startkernel:
|
|
||||||
entry = cstate.opthdr32.entry;
|
|
||||||
done();
|
|
||||||
mach_boot(entry);
|
|
||||||
}
|
|
||||||
return skip_sectors;
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2003 Yannis Mitsos and George Thanos
|
|
||||||
* {gmitsos@gthanos}@telecom.ntua.gr
|
|
||||||
* Released under GPL2, see the file COPYING in the top directory
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "hooks.h"
|
|
||||||
#include "io.h"
|
|
||||||
#include "etherboot.h"
|
|
||||||
#include "e132_xs_board.h"
|
|
||||||
|
|
||||||
unsigned int io_periph[NR_CS] = {[0 ... NR_CS-1] = 0 };
|
|
||||||
|
|
||||||
/*
|
|
||||||
void arch_main(struct Elf_Bhdr *ptr __unused)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void init_peripherals(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0; i< NR_CS; i++){
|
|
||||||
io_periph[i]= (SLOW_IO_ACCESS | i << 22);
|
|
||||||
}
|
|
||||||
|
|
||||||
io_periph[ETHERNET_CS] = (io_periph[ETHERNET_CS] | 1 << IOWait);
|
|
||||||
|
|
||||||
asm volatile("
|
|
||||||
ori SR, 0x20
|
|
||||||
movi FCR, 0x66ffFFFF"
|
|
||||||
:
|
|
||||||
:);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct meminfo meminfo;
|
|
||||||
void get_memsizes(void)
|
|
||||||
{
|
|
||||||
/* We initialize the meminfo structure
|
|
||||||
* according to our development board's specs
|
|
||||||
* We do not have a way to automatically probe the
|
|
||||||
* memspace instead we initialize it manually
|
|
||||||
*/
|
|
||||||
meminfo.basememsize = BASEMEM;
|
|
||||||
meminfo.memsize = SDRAM_SIZE;
|
|
||||||
meminfo.map_count = NR_MEMORY_REGNS;
|
|
||||||
|
|
||||||
meminfo.map[0].addr = SDRAM_BASEMEM;
|
|
||||||
meminfo.map[0].size = SDRAM_SIZE;
|
|
||||||
meminfo.map[0].type = E820_RAM;
|
|
||||||
meminfo.map[1].addr = SRAM_BASEMEM;
|
|
||||||
meminfo.map[1].size = SRAM_SIZE;
|
|
||||||
meminfo.map[1].type = E820_RAM;
|
|
||||||
meminfo.map[2].addr = IRAM_BASEMEM;
|
|
||||||
meminfo.map[2].size = IRAM_SIZE;
|
|
||||||
meminfo.map[2].type = E820_RAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mach_boot(register unsigned long entry_point)
|
|
||||||
{
|
|
||||||
asm volatile(
|
|
||||||
"mov PC, %0"
|
|
||||||
: /* no outputs */
|
|
||||||
: "l" (entry_point) );
|
|
||||||
return 0; /* We should never reach this point ! */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2003 Yannis Mitsos and George Thanos
|
|
||||||
* {gmitsos@gthanos}@telecom.ntua.gr
|
|
||||||
* Released under GPL2, see the file COPYING in the top directory
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "etherboot.h"
|
|
||||||
#include "timer.h"
|
|
||||||
#include "e132_xs_board.h"
|
|
||||||
#include "init.h"
|
|
||||||
|
|
||||||
/* get timer returns the contents of the timer */
|
|
||||||
static inline unsigned long get_timer(void)
|
|
||||||
{
|
|
||||||
unsigned long result;
|
|
||||||
__asm__ __volatile__("
|
|
||||||
ORI SR, 0x20
|
|
||||||
mov %0, TR"
|
|
||||||
: "=l"(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------ Calibrate the TSC -------
|
|
||||||
* Time how long it takes to excute a loop that runs in known time.
|
|
||||||
* And find the convertion needed to get to CLOCK_TICK_RATE
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned long configure_timer(void)
|
|
||||||
{
|
|
||||||
unsigned long TPR_value; /* Timer Prescalar Value */
|
|
||||||
|
|
||||||
TPR_value = 0x000C00000;
|
|
||||||
|
|
||||||
asm volatile ("
|
|
||||||
FETCH 4
|
|
||||||
ORI SR, 0x20
|
|
||||||
MOV TPR, %0
|
|
||||||
ORI SR, 0x20
|
|
||||||
MOVI TR, 0x0"
|
|
||||||
: /* no outputs */
|
|
||||||
: "l" (TPR_value)
|
|
||||||
);
|
|
||||||
|
|
||||||
printf("The time prescaler register is set to: <%#x>\n",TPR_value);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long clocks_per_tick;
|
|
||||||
|
|
||||||
static void setup_timers(void)
|
|
||||||
{
|
|
||||||
if (!clocks_per_tick) {
|
|
||||||
clocks_per_tick = configure_timer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long currticks(void)
|
|
||||||
{
|
|
||||||
return get_timer()/clocks_per_tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long timer_timeout;
|
|
||||||
static int __timer_running(void)
|
|
||||||
{
|
|
||||||
return get_timer() < timer_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void udelay(unsigned int usecs)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
now = get_timer();
|
|
||||||
timer_timeout = now + usecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000));
|
|
||||||
while(__timer_running());
|
|
||||||
}
|
|
||||||
void ndelay(unsigned int nsecs)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
now = get_timer();
|
|
||||||
timer_timeout = now + nsecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000*1000));
|
|
||||||
while(__timer_running());
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_timer2(unsigned int timer2_ticks)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
unsigned long clocks;
|
|
||||||
now = get_timer();
|
|
||||||
clocks = timer2_ticks * ((clocks_per_tick * TICKS_PER_SEC)/CLOCK_TICK_RATE);
|
|
||||||
timer_timeout = now + clocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
int timer2_running(void)
|
|
||||||
{
|
|
||||||
return __timer_running();
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );
|
|
|
@ -1,126 +0,0 @@
|
||||||
/* Default linker script, for normal executables */
|
|
||||||
OUTPUT_FORMAT("coff-e1-big")
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
romvec : ORIGIN = 0x2000000, LENGTH = 0x0000400
|
|
||||||
flash : ORIGIN = 0xE0000000, LENGTH = 0x20000
|
|
||||||
eflash : ORIGIN = 0x2200000, LENGTH = 0x20000
|
|
||||||
ram : ORIGIN = 0x00000000, LENGTH = 0x1000000
|
|
||||||
eram16MB : ORIGIN = 0x01000000, LENGTH = 0
|
|
||||||
sram : ORIGIN = 0x40000000, LENGTH = 0x40000
|
|
||||||
iram : ORIGIN = 0xC0000000, LENGTH = 0x4000
|
|
||||||
}
|
|
||||||
|
|
||||||
SEARCH_DIR("/usr/local/e1-coff/lib");
|
|
||||||
ENTRY(Main)
|
|
||||||
MEM0start = 0x00000000;
|
|
||||||
MEM0size = 0x40000000;
|
|
||||||
MEM1start = 0x40000000;
|
|
||||||
MEM1size = 0x40000000;
|
|
||||||
MEM2start = 0x80000000;
|
|
||||||
MEM2size = 0x40000000;
|
|
||||||
IRAMstart = 0xC0000000;
|
|
||||||
IRAMsize = 0x20000000;
|
|
||||||
MEM3start = 0xE0000000;
|
|
||||||
MEM3size = 0x20000000;
|
|
||||||
Stack1Reserve = 560;
|
|
||||||
_Stack1Size = DEFINED(_Stack1Size)? _Stack1Size : 1*1024;
|
|
||||||
_Stack2Size = DEFINED(_Stack2Size)? _Stack2Size : 16*1024;
|
|
||||||
_Stack1Base = DEFINED(_Stack1Base)? _Stack1Base : __bss_end__;
|
|
||||||
_Stack2Base = DEFINED(_Stack2Base)? _Stack2Base : __bss_end__ + _Stack1Size + Stack1Reserve;
|
|
||||||
_Mem0HeapBase = DEFINED(_Mem0HeapBase)? _Mem0HeapBase : _Stack2Base + _Stack2Size;
|
|
||||||
_Mem1HeapBase = DEFINED(_Mem1HeapBase)? _Mem1HeapBase : 0;
|
|
||||||
Priority = DEFINED(Priority) ? Priority : 31;
|
|
||||||
TextBase = DEFINED(TextBase) ? TextBase : 0xa00000;
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.G6 (DEFINED(G6Base) ? G6Base : 0x9000) : {
|
|
||||||
*(.G6)
|
|
||||||
}
|
|
||||||
.G7 (DEFINED(G7Base) ? G7Base : 0x40001000) : {
|
|
||||||
*(.G7)
|
|
||||||
}
|
|
||||||
.G8 (DEFINED(G8Base) ? G8Base : 0xC0000000) : {
|
|
||||||
*(.G8)
|
|
||||||
}
|
|
||||||
.G9 (DEFINED(G9Base) ? G9Base : 0) : {
|
|
||||||
*(.G9)
|
|
||||||
}
|
|
||||||
.G10 (DEFINED(G10Base) ? G10Base : 0) : {
|
|
||||||
*(.G10)
|
|
||||||
}
|
|
||||||
.G11 (DEFINED(G11Base) ? G11Base : 0) : {
|
|
||||||
*(.G11)
|
|
||||||
}
|
|
||||||
.G12 (DEFINED(G12Base) ? G12Base : 0) : {
|
|
||||||
*(.G12)
|
|
||||||
}
|
|
||||||
.G13 (DEFINED(G13Base) ? G13Base : 0) : {
|
|
||||||
*(.G13)
|
|
||||||
}
|
|
||||||
|
|
||||||
.text TextBase : {
|
|
||||||
__virt_start = .;
|
|
||||||
__text = . ;
|
|
||||||
*(.text)
|
|
||||||
*(.fini)
|
|
||||||
. = ALIGN(16);
|
|
||||||
_isa_drivers = . ;
|
|
||||||
*(.drivisa);
|
|
||||||
_isa_drivers_end = . ;
|
|
||||||
. = ALIGN(16);
|
|
||||||
|
|
||||||
*(.init)
|
|
||||||
_etext = . ;
|
|
||||||
/* _init = DEFINED(_init) ? _init : 0; */
|
|
||||||
/* _fini = DEFINED(_fini) ? _fini : 0; */
|
|
||||||
/* _argc = DEFINED(_argc) ? _argc : 0; */
|
|
||||||
/* _argv = DEFINED(_argv) ? _argv : 0; */
|
|
||||||
/* _envp = DEFINED(_envp) ? _envp : 0; */
|
|
||||||
/* _hwinit = DEFINED(_hwinit) ? _hwinit : 0; */
|
|
||||||
/* _atexit = DEFINED(_atexit) ? _atexit : 0; */
|
|
||||||
G6Size = SIZEOF(.G6);
|
|
||||||
G7Size = SIZEOF(.G7);
|
|
||||||
G8Size = SIZEOF(.G8);
|
|
||||||
G9Size = SIZEOF(.G9);
|
|
||||||
G10Size = SIZEOF(.G10);
|
|
||||||
G11Size = SIZEOF(.G11);
|
|
||||||
G12Size = SIZEOF(.G12);
|
|
||||||
G13Size = SIZEOF(.G13);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.data SIZEOF(.text) + ADDR(.text) : {
|
|
||||||
*(.data)
|
|
||||||
_edata = . ;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bss SIZEOF(.data) + ADDR(.data) :
|
|
||||||
{
|
|
||||||
__bss_start__ = ALIGN( 0x10 ) ;
|
|
||||||
__bss = . ;
|
|
||||||
*(.bss)
|
|
||||||
*(COMMON)
|
|
||||||
__end = . ;
|
|
||||||
__bss_end__ = ALIGN( 0x10 ) ;
|
|
||||||
__ebss = . ;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eram16MB :
|
|
||||||
{
|
|
||||||
___ramend = . - 0x7000;
|
|
||||||
} > eram16MB
|
|
||||||
|
|
||||||
.stab 0 (NOLOAD) :
|
|
||||||
{
|
|
||||||
[ .stab ]
|
|
||||||
}
|
|
||||||
.stabstr 0 (NOLOAD) :
|
|
||||||
{
|
|
||||||
[ .stabstr ]
|
|
||||||
}
|
|
||||||
_GOT_ 0 (NOLOAD) :
|
|
||||||
{
|
|
||||||
[ _GOT_ ]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2003 Yannis Mitsos and George Thanos
|
|
||||||
* {gmitsos@gthanos}@telecom.ntua.gr
|
|
||||||
* Released under GPL2, see the file COPYING in the top directory
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "setjmp.h"
|
|
||||||
|
|
||||||
unsigned long jmpbuf_ptr;
|
|
||||||
|
|
||||||
void longjmp(jmp_buf state, int value )
|
|
||||||
{
|
|
||||||
if(!value)
|
|
||||||
state->__jmpbuf->ReturnValue = 1;
|
|
||||||
else
|
|
||||||
state->__jmpbuf->ReturnValue = value;
|
|
||||||
|
|
||||||
jmpbuf_ptr = (unsigned long)state;
|
|
||||||
|
|
||||||
#define _state_ ((struct __jmp_buf_tag*)jmpbuf_ptr)
|
|
||||||
asm volatile("mov L0, %0\n\t"
|
|
||||||
"mov L1, %1\n\t"
|
|
||||||
"mov L2, %2\n\t"
|
|
||||||
"mov G3, %3\n\t"
|
|
||||||
"mov G4, %4\n\t"
|
|
||||||
"ret PC, L1\n\t"
|
|
||||||
:/*no output*/
|
|
||||||
:"l"(_state_->__jmpbuf->ReturnValue),
|
|
||||||
"l"(_state_->__jmpbuf->SavedPC),
|
|
||||||
"l"(_state_->__jmpbuf->SavedSR),
|
|
||||||
"l"(_state_->__jmpbuf->G3),
|
|
||||||
"l"(_state_->__jmpbuf->G4)
|
|
||||||
:"%G3", "%G4", "%L0", "%L1" );
|
|
||||||
#undef _state_
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Derived from the Hyperstone's library source code.
|
|
||||||
* Modefied src in order to apply the -mgnu-param compiler option.
|
|
||||||
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
|
|
||||||
* George Thanos <gthanos@telecom.ntua.gr>
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
.align 2
|
|
||||||
.global _memcmp
|
|
||||||
|
|
||||||
;ENTRY (_memcmp)
|
|
||||||
_memcmp:
|
|
||||||
FRAME L9, L3 # get incoming parameters
|
|
||||||
CMPBI L2,3 # check word alignment
|
|
||||||
BNZ byte_compare
|
|
||||||
CMPBI L1,3 # check word alignment
|
|
||||||
BNZ byte_compare
|
|
||||||
|
|
||||||
double_compare:
|
|
||||||
ADDI L0, -8
|
|
||||||
BLT is_equal
|
|
||||||
LDD.P L1, L5
|
|
||||||
LDD.P L2, L7
|
|
||||||
SUB L5, L7
|
|
||||||
DBNZ corr_8
|
|
||||||
SUB L6, L8
|
|
||||||
BZ double_compare
|
|
||||||
ADDI L0, 4
|
|
||||||
ADDI L2, -4
|
|
||||||
ADDI L1, -4
|
|
||||||
BR byte_compare
|
|
||||||
|
|
||||||
corr_8: ADDI L0, 8
|
|
||||||
ADDI L2, -8
|
|
||||||
ADDI L1, -8
|
|
||||||
byte_compare:
|
|
||||||
ADDI L0, -1
|
|
||||||
BLT equal
|
|
||||||
LDBU.N L2, L5, 1 # Load and compare bytes
|
|
||||||
LDBU.N L1, L6, 1
|
|
||||||
SUB L5, L6
|
|
||||||
BZ byte_compare
|
|
||||||
MOV L2, L5
|
|
||||||
RET PC, L3
|
|
||||||
|
|
||||||
is_equal: CMPI L0, -8
|
|
||||||
DBNE byte_compare
|
|
||||||
ADDI L0, 8
|
|
||||||
equal:
|
|
||||||
MOVI L2, 0
|
|
||||||
RET PC, L3
|
|
||||||
|
|
||||||
.END
|
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* Derived from the Hyperstone's library source code.
|
|
||||||
* Modefied src in order to apply the -mgnu-param compiler option.
|
|
||||||
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
|
|
||||||
* George Thanos <gthanos@telecom.ntua.gr>
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
.align 2
|
|
||||||
.global _memcpy
|
|
||||||
;ENTRY(_memcpy)
|
|
||||||
_memcpy:
|
|
||||||
FRAME L8, L3
|
|
||||||
MOV L7, L2 # Save for return
|
|
||||||
|
|
||||||
#*****************************
|
|
||||||
# Perform byte copy if both
|
|
||||||
# not on a word alignment
|
|
||||||
#*****************************
|
|
||||||
CMPBI L2, 3 # check word alignment
|
|
||||||
BNZ mem_except
|
|
||||||
CMPBI L1, 3 # check word alignment
|
|
||||||
BNZ mem_except
|
|
||||||
|
|
||||||
#*****************************
|
|
||||||
# Copy Double,Word,Halfword,
|
|
||||||
# then byte
|
|
||||||
#*****************************
|
|
||||||
DBL_LOOP:
|
|
||||||
CMPI L0, 8 # Copy Doubles
|
|
||||||
BLT DO_WORD
|
|
||||||
LDD.P L1, L5
|
|
||||||
ADDI L0, -8
|
|
||||||
DBR DBL_LOOP
|
|
||||||
STD.P L2, L5
|
|
||||||
|
|
||||||
DO_WORD:
|
|
||||||
CMPI L0, 4 # Copy leftover word
|
|
||||||
BLT DO_HALF
|
|
||||||
LDW.P L1, L5
|
|
||||||
ADDI L0, -4
|
|
||||||
DBZ DONE # Done if L0 is 0
|
|
||||||
STW.P L2, L5
|
|
||||||
|
|
||||||
DO_HALF:
|
|
||||||
CMPI L0, 2 # Copy leftover byte
|
|
||||||
BLT DO_BYTE
|
|
||||||
LDHU.N L1, L5, 2
|
|
||||||
ADDI L0, -2
|
|
||||||
DBZ DONE # Done if L0 is 0
|
|
||||||
STHU.N L2, L5, 2
|
|
||||||
|
|
||||||
DO_BYTE:
|
|
||||||
CMPI L0, 1 # Copy leftover byte
|
|
||||||
BLT DONE
|
|
||||||
LDBU.D L1, L5, 0
|
|
||||||
STBU.D L2, L5, 0
|
|
||||||
|
|
||||||
DONE: # Copy done
|
|
||||||
MOV L2, L7 # Return pointer
|
|
||||||
RET PC, L3
|
|
||||||
|
|
||||||
#****************************
|
|
||||||
# Byte memcpy
|
|
||||||
#****************************
|
|
||||||
mem_except:
|
|
||||||
DBR L_5
|
|
||||||
MOVI L6,0
|
|
||||||
L_3:
|
|
||||||
LDBS.D L1, L5, 0 # Transfer the byte
|
|
||||||
ADDI L6, 1
|
|
||||||
STBS.D L2, L5, 0
|
|
||||||
ADDI L2, 1
|
|
||||||
ADDI L1, 1
|
|
||||||
L_5: # Loop test
|
|
||||||
CMP L6, L0
|
|
||||||
BST L_3
|
|
||||||
MOV L2, L7 # Return pointer
|
|
||||||
RET PC, L3
|
|
||||||
.END
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Derived from the Hyperstone's library source code.
|
|
||||||
* Modefied src in order to apply the -mgnu-param compiler option.
|
|
||||||
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
|
|
||||||
* George Thanos <gthanos@telecom.ntua.gr>
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
.align 2
|
|
||||||
.global _memset
|
|
||||||
|
|
||||||
;ENTRY(_memset)
|
|
||||||
_memset: FRAME L9, L3
|
|
||||||
MASK L5, L1, 0xFF
|
|
||||||
MOV L8, L2
|
|
||||||
CMPI L0, 0 # if n = 0 then return
|
|
||||||
BE retour
|
|
||||||
|
|
||||||
loop0: CMPBI L8, 0x3
|
|
||||||
BZ word_bound
|
|
||||||
ADDI L0, -1
|
|
||||||
DBNZ loop0
|
|
||||||
STBU.N L8, L5, 1
|
|
||||||
retour: RET PC, L3
|
|
||||||
|
|
||||||
word_bound:
|
|
||||||
CMPI L0, 8
|
|
||||||
DBLT loop2
|
|
||||||
MOV L7, L5
|
|
||||||
SHLI L7, 8
|
|
||||||
OR L5, L7
|
|
||||||
MOV L7, L5
|
|
||||||
SHLI L7, 16
|
|
||||||
OR L5, L7
|
|
||||||
MOV L6, L5
|
|
||||||
loop1: ADDI L0, -8
|
|
||||||
CMPI L0, 8
|
|
||||||
DBGE loop1
|
|
||||||
STD.P L8, L5
|
|
||||||
CMPI L0, 0
|
|
||||||
DBNZ loop2
|
|
||||||
ANDNI L5, ~ 0xFF
|
|
||||||
RET PC, L3
|
|
||||||
|
|
||||||
loop2: ADDI L0, -1
|
|
||||||
DBNZ loop2
|
|
||||||
STBU.N L8, L5, 1
|
|
||||||
RET PC, L3
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2003 Yannis Mitsos and George Thanos
|
|
||||||
* {gmitsos@gthanos}@telecom.ntua.gr
|
|
||||||
* Released under GPL2, see the file COPYING in the top directory
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "setjmp.h"
|
|
||||||
|
|
||||||
int setjmp( jmp_buf state)
|
|
||||||
{
|
|
||||||
asm volatile( "mov %0, G3\n\t"
|
|
||||||
"mov %1, G4\n\t"
|
|
||||||
:"=l"(state->__jmpbuf->G3),
|
|
||||||
"=l"(state->__jmpbuf->G4)
|
|
||||||
:/*no input*/
|
|
||||||
:"%G3", "%G4" );
|
|
||||||
|
|
||||||
asm volatile( "setadr %0\n\t"
|
|
||||||
"mov %1, L1\n\t"
|
|
||||||
"mov %2, L2\n\t"
|
|
||||||
:"=l"(state->__jmpbuf->SavedSP),
|
|
||||||
"=l"(state->__jmpbuf->SavedPC),
|
|
||||||
"=l"(state->__jmpbuf->SavedSR)
|
|
||||||
:/*no input*/);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
/*
|
|
||||||
* Derived from the Hyperstone's library source code.
|
|
||||||
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
|
|
||||||
* George Thanos <gthanos@telecom.ntua.gr>
|
|
||||||
*/
|
|
||||||
.global Priority ; Task-Priority
|
|
||||||
.global _Stack1Size ; Size of hardware stack
|
|
||||||
.global _Stack2Size ; Size of aggregate stack
|
|
||||||
.global _Stack1Base ; Base of hardware stack
|
|
||||||
.global _Stack2Base ; Base of aggregate stack
|
|
||||||
.global _Mem0HeapBase ; Base of Heap in Mem0
|
|
||||||
.global _Mem1HeapBase ; Base of Heap in Mem1
|
|
||||||
|
|
||||||
.global _init_peripherals
|
|
||||||
.global _main
|
|
||||||
.global Main
|
|
||||||
|
|
||||||
.global __exit
|
|
||||||
.global __fmode
|
|
||||||
.global __MaxArgCount
|
|
||||||
|
|
||||||
.text
|
|
||||||
BasePtrs:
|
|
||||||
.weak G6Base,G7Base,G8Base,G9Base,G10Base,G11Base,G12Base,G13Base
|
|
||||||
.long G6Base,G7Base,G8Base,G9Base,G10Base,G11Base,G12Base,G13Base
|
|
||||||
BasePtrsEnd:
|
|
||||||
HeapPtrs:
|
|
||||||
.long _Mem0HeapBase
|
|
||||||
.long _Mem1HeapBase
|
|
||||||
HeapPtrsEnd:
|
|
||||||
|
|
||||||
__MaxArgCount:
|
|
||||||
.long 32
|
|
||||||
__StandAloneMode:
|
|
||||||
.long 0 ; 0 indicate stand alone mode
|
|
||||||
|
|
||||||
;============================================================================;
|
|
||||||
; Startup-Code ;
|
|
||||||
;============================================================================;
|
|
||||||
.data
|
|
||||||
|
|
||||||
; do not change the order of: __argc,..
|
|
||||||
__argc:
|
|
||||||
.long 0
|
|
||||||
__argv:
|
|
||||||
.long 0
|
|
||||||
__IsShell:
|
|
||||||
.long 1
|
|
||||||
ErrorLevel:
|
|
||||||
.long 0
|
|
||||||
__lab:
|
|
||||||
.long 0
|
|
||||||
__fmode:
|
|
||||||
.long 0x4000 ; O_TEXT attribute
|
|
||||||
|
|
||||||
_isa_drivers:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
_isa_drivers_end:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
|
|
||||||
.text
|
|
||||||
Main:
|
|
||||||
StartUp:
|
|
||||||
FRAME L5, L0
|
|
||||||
MOVI L2, __bss_start__ ; clear the .bss segment
|
|
||||||
0: CMPI L2, __bss_end__
|
|
||||||
BHE 0f
|
|
||||||
DBR 0b
|
|
||||||
STW.P L2, 0
|
|
||||||
0: SUM L2, PC, BasePtrs-$ ; Load BasePtrs G6-G13
|
|
||||||
LDD.P L2, G6
|
|
||||||
LDD.P L2, G8
|
|
||||||
; LDD.P L2, G10
|
|
||||||
LDD.P L2, G12
|
|
||||||
MOVI L2, 1
|
|
||||||
SUM L3, PC, __StandAloneMode-$
|
|
||||||
STW.R L3, L2
|
|
||||||
|
|
||||||
;----------------------------------------------------------------;
|
|
||||||
; Call main C function ;
|
|
||||||
;----------------------------------------------------------------;
|
|
||||||
2: LDW.D PC, L2, __argc - $ ; pass count of arguments to main
|
|
||||||
LDW.D PC, L3, __argv - $ ; pass pointer array to main
|
|
||||||
CALL L4, PC, _init_peripherals - $
|
|
||||||
CALL L4, PC, _main - $ ; --> Call Main-Program
|
|
||||||
CHK PC, PC ; trap if execution arrives here
|
|
||||||
|
|
||||||
__exit:
|
|
||||||
FRAME L5, L1
|
|
||||||
STW.D PC, L0, ErrorLevel - $ ; Store ERRORLEVEL
|
|
||||||
|
|
||||||
CHK PC, PC
|
|
||||||
RET PC, L1
|
|
||||||
|
|
||||||
.global ___main
|
|
||||||
___main:
|
|
||||||
FRAME L4, L1
|
|
||||||
MOVI L3, 2
|
|
||||||
STW.D PC, L3, __StandAloneMode-$
|
|
||||||
RET PC, L1 ; does not return
|
|
||||||
|
|
||||||
.section _GOT_
|
|
||||||
.long Main+4 ; OnCreate
|
|
||||||
.long Main+8 ; OnError
|
|
||||||
.long BasePtrs ; G6
|
|
||||||
.long BasePtrs+4 ; G7
|
|
||||||
.long BasePtrs+8 ; G8
|
|
||||||
|
|
||||||
.END
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* Derived from the Hyperstone's library source code.
|
|
||||||
* Modefied src in order to apply the -mgnu-param compiler option.
|
|
||||||
* Copyright (C) 2002-2003 GDT, Yannis Mitsos <gmitsos@telecom.ntua.gr>
|
|
||||||
* George Thanos <gthanos@telecom.ntua.gr>
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
.align 2
|
|
||||||
.global _strcmp
|
|
||||||
;ENTRY(_strcmp)
|
|
||||||
_strcmp:
|
|
||||||
FRAME L8,L2
|
|
||||||
CMPBI L1, 3 # check for word alignment
|
|
||||||
BNZ str_except
|
|
||||||
CMPBI L0, 3 # check for word alignment
|
|
||||||
BNZ str_except
|
|
||||||
|
|
||||||
start:
|
|
||||||
LDD.P L1, L4 # post inc mode
|
|
||||||
LDD.P L0, L6 # post inc mode
|
|
||||||
CMPBI L4, ANYBZ
|
|
||||||
BE correct1
|
|
||||||
CMP L4, L6
|
|
||||||
BNE correct1
|
|
||||||
CMP L5, L7
|
|
||||||
BNE correct
|
|
||||||
CMPBI L5, ANYBZ
|
|
||||||
BE correct
|
|
||||||
CMPBI L6, ANYBZ
|
|
||||||
BE correct1
|
|
||||||
CMPBI L7, ANYBZ
|
|
||||||
BNE start
|
|
||||||
|
|
||||||
correct: MASK L4, L5, 0xff000000
|
|
||||||
MASK L6, L7, 0xff000000
|
|
||||||
CMP L4, L6
|
|
||||||
BNE Exit
|
|
||||||
SHLI L5, 8
|
|
||||||
CMPI L4, 0
|
|
||||||
DBNE correct
|
|
||||||
SHLI L7, 8
|
|
||||||
MOV L1, L4
|
|
||||||
RET PC, L2
|
|
||||||
|
|
||||||
Exit: SUB L4, L6 # Subtract chars
|
|
||||||
SARI L4, 24
|
|
||||||
MOV L1, L4
|
|
||||||
RET PC, L2
|
|
||||||
|
|
||||||
correct1: MASK L5, L4, 0xff000000
|
|
||||||
MASK L7, L6, 0xff000000
|
|
||||||
CMP L5, L7
|
|
||||||
BNE Exit1
|
|
||||||
SHLI L4, 8
|
|
||||||
CMPI L5, 0
|
|
||||||
DBNE correct1
|
|
||||||
SHLI L6, 8
|
|
||||||
MOV L1, L5
|
|
||||||
RET PC, L2
|
|
||||||
Exit1: SUB L5, L7 # Subtract chars
|
|
||||||
SARI L5, 24
|
|
||||||
MOV L1, L5
|
|
||||||
RET PC, L2
|
|
||||||
|
|
||||||
testzero: CMPI L4, 0
|
|
||||||
BE L_5
|
|
||||||
str_except:
|
|
||||||
LDBU.N L1, L4, 1 # Load *s1, compare bytes
|
|
||||||
LDBU.N L0, L5, 1 # Load *s2, compare bytes
|
|
||||||
CMP L4, L5
|
|
||||||
BE testzero
|
|
||||||
SUB L4, L5 # Subtract chars
|
|
||||||
L_5: MOV L1, L4
|
|
||||||
RET PC, L2
|
|
||||||
.END
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
#ifndef ETHERBOOT_BITS_BYTESWAP_H
|
|
||||||
#define ETHERBOOT_BITS_BYTESWAP_H
|
|
||||||
|
|
||||||
/* We do not have byte swap functions ... We are
|
|
||||||
* RISC processor ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline unsigned short __swap16(volatile unsigned short v)
|
|
||||||
{
|
|
||||||
return ((v << 8) | (v >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int __swap32(volatile unsigned long v)
|
|
||||||
{
|
|
||||||
return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __bswap_constant_16(x) \
|
|
||||||
((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
|
|
||||||
(((uint16_t)(x) & 0xff00) >> 8)))
|
|
||||||
|
|
||||||
#define __bswap_constant_32(x) \
|
|
||||||
((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
|
|
||||||
(((uint32_t)(x) & 0x0000ff00U) << 8) | \
|
|
||||||
(((uint32_t)(x) & 0x00ff0000U) >> 8) | \
|
|
||||||
(((uint32_t)(x) & 0xff000000U) >> 24)))
|
|
||||||
|
|
||||||
#define __bswap_16(x) \
|
|
||||||
(__builtin_constant_p(x) ? \
|
|
||||||
__bswap_constant_16(x) : \
|
|
||||||
__swap16(x))
|
|
||||||
|
|
||||||
|
|
||||||
#define __bswap_32(x) \
|
|
||||||
(__builtin_constant_p(x) ? \
|
|
||||||
__bswap_constant_32(x) : \
|
|
||||||
__swap32(x))
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_BYTESWAP_H */
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef E1_BITS_CPU_H
|
|
||||||
#define E1_BITS_CPU_H
|
|
||||||
|
|
||||||
#define cpu_setup() do {} while(0)
|
|
||||||
|
|
||||||
#endif /* E1_BITS_CPU_H */
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef E1_BITS_ELF_H
|
|
||||||
#define E1_BITS_ELF_H
|
|
||||||
|
|
||||||
/* dummy file, needed for the compilation of core/nic.c */
|
|
||||||
|
|
||||||
#endif /* E1_BITS_ELF_H */
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef ETHERBOOT_BITS_ENDIAN_H
|
|
||||||
#define ETHERBOOT_BITS_ENDIAN_H
|
|
||||||
|
|
||||||
#define __BYTE_ORDER __BIG_ENDIAN
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_ENDIAN_H */
|
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef ETHERBOOT_BITS_STRING_H
|
|
||||||
#define ETHERBOOT_BITS_STRING_H
|
|
||||||
|
|
||||||
/* define inline optimized string functions here */
|
|
||||||
|
|
||||||
#define __HAVE_ARCH_MEMCPY
|
|
||||||
//extern void * memcpy(const void *d, const void *s, size_t count);
|
|
||||||
|
|
||||||
#define __HAVE_ARCH_MEMCMP
|
|
||||||
//extern int memcmp(const void * s ,const void * d ,size_t );
|
|
||||||
|
|
||||||
#define __HAVE_ARCH_MEMSET
|
|
||||||
//extern void * memset(const void * s, int c, size_t count);
|
|
||||||
|
|
||||||
#define __HAVE_ARCH_MEMMOVE
|
|
||||||
static inline void *memmove(void *s1, const void *s2, size_t n) {
|
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
char *tmp = s1;
|
|
||||||
char *cs2 = (char *) s2;
|
|
||||||
|
|
||||||
if (tmp < cs2) {
|
|
||||||
for(i=0; i<n; ++i, ++tmp, ++cs2)
|
|
||||||
*tmp = *cs2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tmp += n - 1;
|
|
||||||
cs2 += n - 1;
|
|
||||||
for(i=0; i<n; ++i, --tmp, --cs2)
|
|
||||||
*tmp = *cs2;
|
|
||||||
}
|
|
||||||
return(s1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_STRING_H */
|
|
|
@ -1,22 +0,0 @@
|
||||||
#ifndef __E132_XS_BOARD_H
|
|
||||||
#define __E132_XS_BOARD_H
|
|
||||||
|
|
||||||
#define CONFIG_HYPERSTONE_OSC_FREQ_MHZ 15
|
|
||||||
|
|
||||||
#define NR_MEMORY_REGNS 3
|
|
||||||
#define BASEMEM 0x0
|
|
||||||
|
|
||||||
/* SDRAM mapping */
|
|
||||||
#define SDRAM_SIZE 0x01000000
|
|
||||||
#define SDRAM_BASEMEM BASEMEM
|
|
||||||
|
|
||||||
/* SRAM mapping */
|
|
||||||
#define SRAM_BASEMEM 0x40000000
|
|
||||||
#define SRAM_SIZE 0x0003FFFF
|
|
||||||
|
|
||||||
/* IRAM mapping */
|
|
||||||
#define IRAM_BASEMEM 0xC0000000
|
|
||||||
#define IRAM_SIZE 0x00003FFF
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __E132_XS_BOARD_H */
|
|
|
@ -1,9 +0,0 @@
|
||||||
#ifndef ETHERBOOT_E1_HOOKS_H
|
|
||||||
#define ETHERBOOT_E1_HOOKS_H
|
|
||||||
|
|
||||||
#define arch_main(data,params) do {} while(0)
|
|
||||||
#define arch_on_exit(status) do {} while(0)
|
|
||||||
#define arch_relocate_to(addr) do {} while(0)
|
|
||||||
#define arch_relocated_from(old_addr) do {} while(0)
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_E1_HOOKS_H */
|
|
|
@ -1,210 +0,0 @@
|
||||||
#ifndef ETHERBOOT_IO_H
|
|
||||||
#define ETHERBOOT_IO_H
|
|
||||||
|
|
||||||
/* Don't require identity mapped physical memory,
|
|
||||||
* osloader.c is the only valid user at the moment.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
static inline unsigned long virt_to_phys(volatile const void *virt_addr)
|
|
||||||
{
|
|
||||||
return ((unsigned long)virt_addr);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static inline void *phys_to_virt(unsigned long phys_addr)
|
|
||||||
{
|
|
||||||
return (void *)(phys_addr);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define phys_to_virt(vaddr) ((void *) (vaddr))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* virt_to_bus converts an addresss inside of etherboot [_start, _end]
|
|
||||||
* into a memory address cards can use.
|
|
||||||
*/
|
|
||||||
#define virt_to_bus virt_to_phys
|
|
||||||
|
|
||||||
/* bus_to_virt reverses virt_to_bus, the address must be output
|
|
||||||
* from virt_to_bus to be valid. This function does not work on
|
|
||||||
* all bus addresses.
|
|
||||||
*/
|
|
||||||
#define bus_to_virt phys_to_virt
|
|
||||||
|
|
||||||
#define iounmap(addr) ((void)0)
|
|
||||||
#define ioremap(physaddr, size) (physaddr)
|
|
||||||
|
|
||||||
#define IORegAddress 13
|
|
||||||
#define IOWait 11
|
|
||||||
#define IOSetupTime 8
|
|
||||||
#define IOAccessTime 5
|
|
||||||
#define IOHoldTime 3
|
|
||||||
|
|
||||||
#define SLOW_IO_ACCESS ( 0x3 << IOSetupTime | 0x0 << IOWait | 7 << IOAccessTime | 3 << IOHoldTime )
|
|
||||||
|
|
||||||
/* The development board can generate up to 15 Chip selects */
|
|
||||||
#define NR_CS 16
|
|
||||||
|
|
||||||
extern unsigned int io_periph[NR_CS];
|
|
||||||
#define ETHERNET_CS 4
|
|
||||||
|
|
||||||
static inline unsigned short _swapw(volatile unsigned short v)
|
|
||||||
{
|
|
||||||
return ((v << 8) | (v >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int _swapl(volatile unsigned long v)
|
|
||||||
{
|
|
||||||
return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define hy_inpw(addr) \
|
|
||||||
({ register unsigned long dummy, dummy1; \
|
|
||||||
dummy = addr; \
|
|
||||||
asm volatile ("LDW.IOD %1, %0, 0" \
|
|
||||||
: "=l" (dummy1) \
|
|
||||||
: "l" (dummy)); dummy1; })
|
|
||||||
|
|
||||||
|
|
||||||
#define hy_outpw(x, addr) \
|
|
||||||
({ register unsigned long dummy0,dummy1; \
|
|
||||||
dummy0 = addr; \
|
|
||||||
dummy1 = x; \
|
|
||||||
asm volatile ("STW.IOD %1, %0, 0" \
|
|
||||||
: "=l" (dummy1) \
|
|
||||||
: "l"(dummy0), "l" (dummy1)); dummy1; })
|
|
||||||
|
|
||||||
#define readb(addr) ({ unsigned char __v = inregb(addr); __v; })
|
|
||||||
#define readw(addr) ({ unsigned short __v = inregw(addr); __v; })
|
|
||||||
#define readl(addr) ({ unsigned long __v = inregl(addr); __v; })
|
|
||||||
|
|
||||||
#define writeb(b,addr) (void)(outreg(b, addr))
|
|
||||||
#define writew(b,addr) (void)(outreg(b, addr))
|
|
||||||
#define writel(b,addr) (void)(outreg(b, addr))
|
|
||||||
|
|
||||||
static inline unsigned long common_io_access(unsigned long addr)
|
|
||||||
{
|
|
||||||
return io_periph[(addr & 0x03C00000) >> 22];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile unsigned char inregb(volatile unsigned long reg)
|
|
||||||
{
|
|
||||||
unsigned char val;
|
|
||||||
|
|
||||||
val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress));
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile unsigned short inregw(volatile unsigned long reg)
|
|
||||||
{
|
|
||||||
unsigned short val;
|
|
||||||
|
|
||||||
val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress));
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline volatile unsigned long inregl(volatile unsigned long reg)
|
|
||||||
{
|
|
||||||
unsigned long val;
|
|
||||||
|
|
||||||
val = hy_inpw(common_io_access(reg) | ((0xf & reg) << IORegAddress));
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void outreg(volatile unsigned long val, volatile unsigned long reg)
|
|
||||||
{
|
|
||||||
|
|
||||||
hy_outpw(val, (common_io_access(reg) | ((0xf & reg) << IORegAddress)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void io_outsb(unsigned int addr, void *buf, int len)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
unsigned char *bp = (unsigned char *) buf;
|
|
||||||
|
|
||||||
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
|
|
||||||
|
|
||||||
while (len--){
|
|
||||||
hy_outpw(_swapw(*bp++), tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void io_outsw(volatile unsigned int addr, void *buf, int len)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
unsigned short *bp = (unsigned short *) buf;
|
|
||||||
|
|
||||||
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
|
|
||||||
|
|
||||||
while (len--){
|
|
||||||
hy_outpw(_swapw(*bp++), tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void io_outsl(volatile unsigned int addr, void *buf, int len)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
unsigned int *bp = (unsigned int *) buf;
|
|
||||||
|
|
||||||
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
|
|
||||||
|
|
||||||
while (len--){
|
|
||||||
hy_outpw(_swapl(*bp++), tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void io_insb(volatile unsigned int addr, void *buf, int len)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
unsigned char *bp = (unsigned char *) buf;
|
|
||||||
|
|
||||||
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
|
|
||||||
|
|
||||||
while (len--)
|
|
||||||
*bp++ = hy_inpw((unsigned char) tmp);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void io_insw(unsigned int addr, void *buf, int len)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
unsigned short *bp = (unsigned short *) buf;
|
|
||||||
|
|
||||||
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
|
|
||||||
|
|
||||||
while (len--)
|
|
||||||
*bp++ = _swapw((unsigned short)hy_inpw(tmp));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void io_insl(unsigned int addr, void *buf, int len)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
unsigned int *bp = (unsigned int *) buf;
|
|
||||||
|
|
||||||
tmp = (common_io_access(addr)) | ((0xf & addr) << IORegAddress);
|
|
||||||
|
|
||||||
while (len--)
|
|
||||||
*bp++ = _swapl((unsigned int)hy_inpw(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define inb(addr) readb(addr)
|
|
||||||
#define inw(addr) readw(addr)
|
|
||||||
#define inl(addr) readl(addr)
|
|
||||||
#define outb(x,addr) ((void) writeb(x,addr))
|
|
||||||
#define outw(x,addr) ((void) writew(x,addr))
|
|
||||||
#define outl(x,addr) ((void) writel(x,addr))
|
|
||||||
|
|
||||||
#define insb(a,b,l) io_insb(a,b,l)
|
|
||||||
#define insw(a,b,l) io_insw(a,b,l)
|
|
||||||
#define insl(a,b,l) io_insl(a,b,l)
|
|
||||||
#define outsb(a,b,l) io_outsb(a,b,l)
|
|
||||||
#define outsw(a,b,l) io_outsw(a,b,l)
|
|
||||||
#define outsl(a,b,l) io_outsl(a,b,l)
|
|
||||||
|
|
||||||
#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
|
|
||||||
#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_IO_H */
|
|
|
@ -1,12 +0,0 @@
|
||||||
#ifndef LATCH_H
|
|
||||||
#define LATCH_H
|
|
||||||
|
|
||||||
//#define TICKS_PER_SEC (1000000UL)
|
|
||||||
#define TICKS_PER_SEC (625000UL)
|
|
||||||
|
|
||||||
/* Fixed timer interval used for calibrating a more precise timer */
|
|
||||||
//#define LATCHES_PER_SEC 10
|
|
||||||
|
|
||||||
void sleep_latch(void);
|
|
||||||
|
|
||||||
#endif /* LATCH_H */
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
/* Project: ANSI C Standard Header Files */
|
|
||||||
/* File: LIMITS.H */
|
|
||||||
/* Edited by: hyperstone electronics GmbH */
|
|
||||||
/* Am Seerhein 8 */
|
|
||||||
/* D-78467 Konstanz, Germany */
|
|
||||||
/* Date: January 30, 1996 */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
/* Purpose: */
|
|
||||||
/* The header file <limits.h> defines limits of ordinal types */
|
|
||||||
/* (char, short, int, long) */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef __LIMITS_H
|
|
||||||
#define __LIMITS_H 1
|
|
||||||
|
|
||||||
#define MB_LEN_MAX 1
|
|
||||||
#define CHAR_BIT 8
|
|
||||||
#define SCHAR_MIN -128L
|
|
||||||
#define SCHAR_MAX 127L
|
|
||||||
#define UCHAR_MAX 255
|
|
||||||
#define CHAR_MIN 0
|
|
||||||
#define CHAR_MAX UCHAR_MAX
|
|
||||||
#define SHRT_MIN -32768
|
|
||||||
#define SHRT_MAX 32767
|
|
||||||
#define USHRT_MAX 65535
|
|
||||||
#define INT_MIN 0x80000000
|
|
||||||
#define INT_MAX 0x7FFFFFFF
|
|
||||||
#define UINT_MAX 0xFFFFFFFFL
|
|
||||||
#define LONG_MIN INT_MIN
|
|
||||||
#define LONG_MAX INT_MAX
|
|
||||||
#define ULONG_MAX UINT_MAX
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,23 +0,0 @@
|
||||||
#ifndef _SETJMP_H
|
|
||||||
#define _SETJMP_H
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned long G3;
|
|
||||||
unsigned long G4;
|
|
||||||
unsigned long SavedSP;
|
|
||||||
unsigned long SavedPC;
|
|
||||||
unsigned long SavedSR;
|
|
||||||
unsigned long ReturnValue;
|
|
||||||
} __jmp_buf[1];
|
|
||||||
|
|
||||||
typedef struct __jmp_buf_tag /* C++ doesn't like tagless structs. */
|
|
||||||
{
|
|
||||||
__jmp_buf __jmpbuf; /* Calling environment. */
|
|
||||||
int __mask_was_saved; /* Saved the signal mask? */
|
|
||||||
} jmp_buf[1];
|
|
||||||
|
|
||||||
void longjmp(jmp_buf state, int value );
|
|
||||||
int setjmp( jmp_buf state);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef STDINT_H
|
|
||||||
#define STDINT_H
|
|
||||||
|
|
||||||
typedef unsigned long size_t;
|
|
||||||
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef unsigned long uint32_t;
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef signed short int16_t;
|
|
||||||
typedef signed int int32_t;
|
|
||||||
typedef signed long long int64_t;
|
|
||||||
|
|
||||||
typedef signed char s8;
|
|
||||||
typedef unsigned char u8;
|
|
||||||
|
|
||||||
typedef signed short s16;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
|
|
||||||
typedef signed long s32;
|
|
||||||
typedef unsigned int u32;
|
|
||||||
|
|
||||||
typedef signed long long s64;
|
|
||||||
typedef unsigned long long u64;
|
|
||||||
|
|
||||||
#endif /* STDINT_H */
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Config for ia64 Etherboot
|
|
||||||
#
|
|
||||||
# Do not delete the tag OptionDescription and /OptionDescription
|
|
||||||
# It is used to automatically generate the documentation.
|
|
||||||
#
|
|
||||||
# @OptionDescrition@
|
|
||||||
#
|
|
||||||
# BIOS interface options:
|
|
||||||
#
|
|
||||||
# -DCONFIG_EFI
|
|
||||||
# Compile in support for EFI
|
|
||||||
#
|
|
||||||
# @/OptionDescription@
|
|
||||||
|
|
||||||
CFLAGS+= -DCONSOLE_FIRMWARE
|
|
||||||
CFLAGS+= -DCONFIG_EFI
|
|
||||||
|
|
||||||
CFLAGS+= -fpic -mconstant-gp -mauto-pic
|
|
||||||
ASFLAGS+= -mconstant-gp -mauto-pic
|
|
||||||
|
|
||||||
LDFLAGS+= -static -shared -Bsymbolic --warn-multiple-gp --warn-common
|
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
ARCH_FORMAT= elf64-ia64-little
|
|
||||||
|
|
||||||
LCONFIG+=
|
|
||||||
|
|
||||||
|
|
||||||
BUILD_EFIS= $(patsubst %.img, %.efi, $(IMGS)) $(patsubst %.img, %.zefi, $(IMGS))
|
|
||||||
|
|
||||||
START= $(BIN)/start.o $(BIN)/reloc.o
|
|
||||||
#START+= $(BIN)/efi_main.o
|
|
||||||
|
|
||||||
SRCS+= arch/ia64/prefix/efi_prefix.S arch/ia64/prefix/unnrv2b.S
|
|
||||||
SRCS+= arch/ia64/core/__call.S
|
|
||||||
SRCS+= arch/ia64/core/ia64_timer.c
|
|
||||||
SRCS+= arch/ia64/core/idiv32.S
|
|
||||||
SRCS+= arch/ia64/core/idiv64.S
|
|
||||||
SRCS+= arch/ia64/core/longjmp.S
|
|
||||||
SRCS+= arch/ia64/core/memmove.S
|
|
||||||
SRCS+= arch/ia64/core/memset.S
|
|
||||||
SRCS+= arch/ia64/core/pal.c
|
|
||||||
SRCS+= arch/ia64/core/pci_io.c
|
|
||||||
SRCS+= arch/ia64/core/reloc.S
|
|
||||||
SRCS+= arch/ia64/core/relocate_to.S
|
|
||||||
SRCS+= arch/ia64/core/sal.c
|
|
||||||
SRCS+= arch/ia64/core/setjmp.S
|
|
||||||
SRCS+= arch/ia64/core/start.S
|
|
||||||
SRCS+= arch/ia64/core/efi.c
|
|
||||||
|
|
||||||
ROMLIMIT:=3276800
|
|
||||||
|
|
||||||
include $(BIN)/Roms
|
|
||||||
|
|
||||||
# We need allefis because $(IMGS) is not defined until
|
|
||||||
# the Makefile fragment "Roms" is read.
|
|
||||||
allefis: $(BUILD_EFIS)
|
|
||||||
|
|
||||||
|
|
||||||
#BOBJS+= $(BIN)/acpi.o
|
|
||||||
BOBJS+= $(BIN)/sal.o $(BIN)/pal.o
|
|
||||||
BOBJS+= $(BIN)/efi.o
|
|
||||||
BOBJS+= $(BIN)/memset.o $(BIN)/memmove.o
|
|
||||||
BOBJS+= $(BIN)/setjmp.o $(BIN)/longjmp.o
|
|
||||||
BOBJS+= $(BIN)/relocate_to.o $(BIN)/__call.o
|
|
||||||
BOBJS+= $(BIN)/pci_io.o $(BIN)/ia64_timer.o
|
|
||||||
BOBJS+= $(BIN)/__divdi3.o $(BIN)/__udivdi3.o $(BIN)/__moddi3.o $(BIN)/__umoddi3.o
|
|
||||||
BOBJS+= $(BIN)/__divsi3.o $(BIN)/__udivsi3.o $(BIN)/__modsi3.o $(BIN)/__umodsi3.o
|
|
||||||
|
|
||||||
|
|
||||||
# IA64 Division routines
|
|
||||||
$(BIN)/__divdi3.o: arch/ia64/core/idiv64.S
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/__udivdi3.o: arch/ia64/core/idiv64.S
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY -DUNSIGNED $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/__moddi3.o: arch/ia64/core/idiv64.S
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY -DMODULO $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/__umoddi3.o: arch/ia64/core/idiv64.S
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY -DUNSIGNED -DMODULO $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/__divsi3.o: arch/ia64/core/idiv32.S
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/__udivsi3.o: arch/ia64/core/idiv32.S
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY -DUNSIGNED $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/__modsi3.o: arch/ia64/core/idiv32.S
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY -DMODULO $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/__umodsi3.o: arch/ia64/core/idiv32.S
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY -DUNSIGNED -DMODULO $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Utilities
|
|
||||||
$(BIN)/nrv2b: util/nrv2b.c
|
|
||||||
$(HOST_CC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG -DBITSIZE=64 -DENDIAN=0 -o $@ $<
|
|
||||||
|
|
||||||
# Pattern Rules
|
|
||||||
|
|
||||||
# General for compiling assembly source files
|
|
||||||
$(BIN)/%.o: arch/ia64/core/%.c $(MAKEDEPS)
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
$(BIN)/%.o: arch/ia64/prefix/%.S $(MAKEDEPS)
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/%.o: arch/ia64/core/%.S $(MAKEDEPS)
|
|
||||||
$(CPP) $(CFLAGS) -DASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
|
|
||||||
|
|
||||||
$(BIN)/%.o: $(BIN)/%.s
|
|
||||||
$(AS) $(ASFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
# General rules for bootable images
|
|
||||||
|
|
||||||
# Rules for nrv2b compressed images
|
|
||||||
$(BIN)/unnrv2b.tmp: $(BIN)/unnrv2b.o arch/ia64/prefix/unnrv2b.lds $(MAKEDEPS)
|
|
||||||
$(LD) -T arch/ia64/prefix/unnrv2b.lds $< -o $@
|
|
||||||
|
|
||||||
$(BIN)/unnrv2b: $(BIN)/unnrv2b.tmp $(MAKEDEPS)
|
|
||||||
$(OBJCOPY) -O binary $< $@
|
|
||||||
|
|
||||||
$(BIN)/%.zimg: $(BIN)/%.z $(BIN)/unnrv2b arch/ia64/prefix/apply_unnrv2b_prefix.pl $(MAKEDEPS)
|
|
||||||
$(PERL) arch/ia64/prefix/apply_unnrv2b_prefix.pl $(BIN)/unnrv2b $< > $@
|
|
||||||
|
|
||||||
# Placeholder; add no extra symbols to %.sym
|
|
||||||
$(BIN)/%.zsym: $(BIN)/%.sym $(MAKEDEPS)
|
|
||||||
cp -f $< $@
|
|
||||||
|
|
||||||
# rules to generate efi loadable image
|
|
||||||
SUFFIXES += efi zefi
|
|
||||||
$(BIN)/efi_prefix.tmp: $(BIN)/efi_prefix.o arch/ia64/prefix/efi_prefix.lds $(MAKEDEPS)
|
|
||||||
$(LD) -T arch/ia64/prefix/efi_prefix.lds $< -o $@
|
|
||||||
|
|
||||||
$(BIN)/efi_prefix: $(BIN)/efi_prefix.tmp $(MAKEDEPS)
|
|
||||||
$(OBJCOPY) -O binary $< $@
|
|
||||||
|
|
||||||
$(BIN)/%.efi: $(BIN)/%.img $(BIN)/%.tmp $(BIN)/efi_prefix arch/ia64/prefix/apply_efi_prefix.pl $(MAKEDEPS)
|
|
||||||
@$(SIZE) $(BIN)/$(*).tmp | (read l1; read d1 d2 bss rest ; echo $$bss )
|
|
||||||
$(PERL) arch/ia64/prefix/apply_efi_prefix.pl $(BIN)/efi_prefix $< `$(SIZE) $(BIN)/$(*).tmp | (read l1; read d1 d2 bss rest ; echo $$bss )` > $@
|
|
||||||
|
|
||||||
$(BIN)/%.zefi: $(BIN)/%.zimg $(BIN)/%.tmp $(BIN)/efi_prefix arch/ia64/prefix/apply_efi_prefix.pl $(MAKEDEPS)
|
|
||||||
@$(SIZE) $(BIN)/$(*).tmp | (read l1; read d1 d2 d3 size rest ; echo $$size )
|
|
||||||
$(PERL) arch/ia64/prefix/apply_efi_prefix.pl $(BIN)/efi_prefix $< `$(SIZE) $(BIN)/$(*).tmp | (read l1; read d1 d2 d3 size rest ; echo $$size )` > $@
|
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
/* Trampoline for calling outside of etherboot */
|
|
||||||
|
|
||||||
.text
|
|
||||||
.globl __call
|
|
||||||
.proc __call
|
|
||||||
__call:
|
|
||||||
alloc loc0=ar.pfs,8,3,8,0 /* in, local, out, rotating */
|
|
||||||
mov loc1=rp
|
|
||||||
mov loc2=gp
|
|
||||||
ld8 r14=[in0],8
|
|
||||||
;;
|
|
||||||
ld8 gp=[in0]
|
|
||||||
mov r28=in1 /* So we can use stacked pal calling conventions */
|
|
||||||
mov out0=in1
|
|
||||||
mov out1=in2
|
|
||||||
mov out2=in3
|
|
||||||
mov out3=in4
|
|
||||||
mov out4=in5
|
|
||||||
mov out5=in6
|
|
||||||
mov out6=in7
|
|
||||||
mov out7=0 /* So we can work with sal calling conventions */
|
|
||||||
|
|
||||||
mov b6=r14
|
|
||||||
;;
|
|
||||||
br.call.sptk.few rp=b6
|
|
||||||
;;
|
|
||||||
rsm psr.i /* disable interrupts */
|
|
||||||
;;
|
|
||||||
mov gp=loc2
|
|
||||||
mov rp=loc1
|
|
||||||
;;
|
|
||||||
mov ar.pfs=loc0
|
|
||||||
br.ret.sptk.many rp
|
|
||||||
|
|
||||||
.size __call, . - __call
|
|
||||||
.endp __call
|
|
||||||
|
|
||||||
|
|
||||||
.text
|
|
||||||
.globl pal_call
|
|
||||||
.proc pal_call
|
|
||||||
pal_call:
|
|
||||||
alloc loc0 = ar.pfs,4,3,0,0 /* in, local, out, rotating */
|
|
||||||
mov loc1 = rp
|
|
||||||
mov loc2 = gp
|
|
||||||
add r8 = @gprel(pal_entry),gp
|
|
||||||
add r9 = @gprel(pal_ret),gp
|
|
||||||
;;
|
|
||||||
ld8 r14 = [r8]
|
|
||||||
;;
|
|
||||||
mov r28 = in0
|
|
||||||
mov r29 = in1
|
|
||||||
mov r30 = in2
|
|
||||||
mov r31 = in3
|
|
||||||
mov b6 = r14
|
|
||||||
mov rp = r9
|
|
||||||
rsm psr.i /* disable interrupts */
|
|
||||||
;;
|
|
||||||
br.sptk.few b6
|
|
||||||
;;
|
|
||||||
pal_ret:
|
|
||||||
rsm psr.i /* disable interrupts */
|
|
||||||
;;
|
|
||||||
mov gp=loc2
|
|
||||||
mov rp=loc1
|
|
||||||
;;
|
|
||||||
mov ar.pfs=loc0
|
|
||||||
br.ret.sptk.many rp
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,82 +0,0 @@
|
||||||
OUTPUT_FORMAT("elf64-ia64-little")
|
|
||||||
|
|
||||||
OUTPUT_ARCH(ia64)
|
|
||||||
|
|
||||||
ENTRY(_start)
|
|
||||||
SECTIONS {
|
|
||||||
. = 0;
|
|
||||||
__gp = . + 0x200000;
|
|
||||||
_virt_start = .;
|
|
||||||
_text = . ;
|
|
||||||
.text : {
|
|
||||||
/* Start address of etherboot in the virtual address space */
|
|
||||||
*(.text)
|
|
||||||
*(.text.*)
|
|
||||||
_etext = . ;
|
|
||||||
|
|
||||||
_rodata = . ;
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.rodata)
|
|
||||||
*(.rodata.*)
|
|
||||||
*(.srodata)
|
|
||||||
. = ALIGN(16);
|
|
||||||
pci_drivers = . ;
|
|
||||||
*(.drivers.pci);
|
|
||||||
pci_drivers_end = . ;
|
|
||||||
. = ALIGN(16);
|
|
||||||
isa_drivers = . ;
|
|
||||||
*(.drivers.isa);
|
|
||||||
isa_drivers_end = . ;
|
|
||||||
. = ALIGN(16);
|
|
||||||
|
|
||||||
. = ALIGN(16);
|
|
||||||
_rela = . ;
|
|
||||||
*(.rela.text)
|
|
||||||
*(.rela.rodata)
|
|
||||||
*(.rela.drivers.pci)
|
|
||||||
*(.rela.drivers.isa)
|
|
||||||
*(.rela.drivers.efi)
|
|
||||||
*(.rela.data)
|
|
||||||
*(.rela.sdata)
|
|
||||||
*(.rela.got)
|
|
||||||
_erela = . ;
|
|
||||||
. = ALIGN(16);
|
|
||||||
_erodata = . ;
|
|
||||||
}
|
|
||||||
_rela_size = _erela - _rela ;
|
|
||||||
.data : {
|
|
||||||
_data = . ;
|
|
||||||
*(.data)
|
|
||||||
*(.got.plt)
|
|
||||||
*(.got)
|
|
||||||
*(.sdata)
|
|
||||||
*(.sbss)
|
|
||||||
*(.scommon)
|
|
||||||
*(.data.*)
|
|
||||||
*(.data1)
|
|
||||||
. = ALIGN(16);
|
|
||||||
_edata = . ;
|
|
||||||
}
|
|
||||||
_bss = . ;
|
|
||||||
.bss : {
|
|
||||||
*(.sbss)
|
|
||||||
*(.scommon)
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss)
|
|
||||||
*(COMMON)
|
|
||||||
}
|
|
||||||
_ebss = .;
|
|
||||||
_end = .;
|
|
||||||
/DISCARD/ : {
|
|
||||||
*(.comment)
|
|
||||||
*(.note)
|
|
||||||
*(.hash)
|
|
||||||
*(.dynstr)
|
|
||||||
*(.dynsym)
|
|
||||||
*(.IA_64.unwind)
|
|
||||||
*(.IA_64.unwind_info)
|
|
||||||
*(.IA64_unwind)
|
|
||||||
*(.IA64_unwind_info)
|
|
||||||
*(.dynamic)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
#include "etherboot.h"
|
|
||||||
#include "timer.h"
|
|
||||||
#include "sal.h"
|
|
||||||
#include "pal.h"
|
|
||||||
#include "init.h"
|
|
||||||
|
|
||||||
static inline unsigned long get_cycles(void)
|
|
||||||
{
|
|
||||||
unsigned long result;
|
|
||||||
__asm__ __volatile__(";;mov %0=ar.itc;;" : "=r"(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------ Calibrate the TSC -------
|
|
||||||
* Time how long it takes to excute a loop that runs in known time.
|
|
||||||
* And find the convertion needed to get to CLOCK_TICK_RATE
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned long calibrate_cycles(void)
|
|
||||||
{
|
|
||||||
unsigned long platform_ticks_per_second, drift_info;
|
|
||||||
struct pal_freq_ratio itc_ratio;
|
|
||||||
long result;
|
|
||||||
result = sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_ticks_per_second, &drift_info);
|
|
||||||
if (result != 0) {
|
|
||||||
printf("sal_freq_base failed: %lx\n",result);
|
|
||||||
exit(1);
|
|
||||||
} else {
|
|
||||||
result = pal_freq_ratios(0,0,&itc_ratio);
|
|
||||||
if (result != 0) {
|
|
||||||
printf("pal_freq_ratios failed: %lx\n", result);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Avoid division by zero */
|
|
||||||
if (itc_ratio.den == 0)
|
|
||||||
itc_ratio.den = 1;
|
|
||||||
|
|
||||||
return (platform_ticks_per_second *itc_ratio.num)/(itc_ratio.den*TICKS_PER_SEC);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long clocks_per_tick;
|
|
||||||
static void setup_timers(void)
|
|
||||||
{
|
|
||||||
if (!clocks_per_tick) {
|
|
||||||
clocks_per_tick = calibrate_cycles();
|
|
||||||
/* Display the CPU Mhz to easily test if the calibration was bad */
|
|
||||||
printf("ITC %ld Mhz\n", (clocks_per_tick/1000 * TICKS_PER_SEC)/1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long currticks(void)
|
|
||||||
{
|
|
||||||
return get_cycles()/clocks_per_tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long timer_timeout;
|
|
||||||
static int __timer_running(void)
|
|
||||||
{
|
|
||||||
return get_cycles() < timer_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void udelay(unsigned int usecs)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
now = get_cycles();
|
|
||||||
timer_timeout = now + usecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000));
|
|
||||||
while(__timer_running());
|
|
||||||
}
|
|
||||||
void ndelay(unsigned int nsecs)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
now = get_cycles();
|
|
||||||
timer_timeout = now + nsecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000*1000));
|
|
||||||
while(__timer_running());
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_timer2(unsigned int timer2_ticks)
|
|
||||||
{
|
|
||||||
unsigned long now;
|
|
||||||
unsigned long clocks;
|
|
||||||
now = get_cycles();
|
|
||||||
clocks = timer2_ticks * ((clocks_per_tick * TICKS_PER_SEC)/CLOCK_TICK_RATE);
|
|
||||||
timer_timeout = now + clocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
int timer2_running(void)
|
|
||||||
{
|
|
||||||
return __timer_running();
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );
|
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2000 Hewlett-Packard Co
|
|
||||||
* Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
|
|
||||||
*
|
|
||||||
* 32-bit integer division.
|
|
||||||
*
|
|
||||||
* This code is based on the application note entitled "Divide, Square Root
|
|
||||||
* and Remainder Algorithms for the IA-64 Architecture". This document
|
|
||||||
* is available as Intel document number 248725-002 or via the web at
|
|
||||||
* http://developer.intel.com/software/opensource/numerics/
|
|
||||||
*
|
|
||||||
* For more details on the theory behind these algorithms, see "IA-64
|
|
||||||
* and Elementary Functions" by Peter Markstein; HP Professional Books
|
|
||||||
* (http://www.hp.com/go/retailbooks/)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef MODULO
|
|
||||||
# define OP mod
|
|
||||||
#else
|
|
||||||
# define OP div
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSIGNED
|
|
||||||
# define SGN u
|
|
||||||
# define EXTEND zxt4
|
|
||||||
# define INT_TO_FP(a,b) fcvt.xuf.s1 a=b
|
|
||||||
# define FP_TO_INT(a,b) fcvt.fxu.trunc.s1 a=b
|
|
||||||
#else
|
|
||||||
# define SGN
|
|
||||||
# define EXTEND sxt4
|
|
||||||
# define INT_TO_FP(a,b) fcvt.xf a=b
|
|
||||||
# define FP_TO_INT(a,b) fcvt.fx.trunc.s1 a=b
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PASTE1(a,b) a##b
|
|
||||||
#define PASTE(a,b) PASTE1(a,b)
|
|
||||||
#define NAME PASTE(PASTE(__,SGN),PASTE(OP,si3))
|
|
||||||
|
|
||||||
.text
|
|
||||||
.global NAME
|
|
||||||
.proc NAME
|
|
||||||
NAME :
|
|
||||||
.regstk 2,0,0,0
|
|
||||||
// Transfer inputs to FP registers.
|
|
||||||
mov r2 = 0xffdd // r2 = -34 + 65535 (fp reg format bias)
|
|
||||||
EXTEND in0 = in0 // in0 = a
|
|
||||||
EXTEND in1 = in1 // in1 = b
|
|
||||||
;;
|
|
||||||
setf.sig f8 = in0
|
|
||||||
setf.sig f9 = in1
|
|
||||||
#ifdef MODULO
|
|
||||||
sub in1 = r0, in1 // in1 = -b
|
|
||||||
#endif
|
|
||||||
;;
|
|
||||||
// Convert the inputs to FP, to avoid FP software-assist faults.
|
|
||||||
INT_TO_FP(f8, f8)
|
|
||||||
INT_TO_FP(f9, f9)
|
|
||||||
;;
|
|
||||||
setf.exp f7 = r2 // f7 = 2^-34
|
|
||||||
frcpa.s1 f6, p6 = f8, f9 // y0 = frcpa(b)
|
|
||||||
;;
|
|
||||||
(p6) fmpy.s1 f8 = f8, f6 // q0 = a*y0
|
|
||||||
(p6) fnma.s1 f6 = f9, f6, f1 // e0 = -b*y0 + 1
|
|
||||||
;;
|
|
||||||
#ifdef MODULO
|
|
||||||
setf.sig f9 = in1 // f9 = -b
|
|
||||||
#endif
|
|
||||||
(p6) fma.s1 f8 = f6, f8, f8 // q1 = e0*q0 + q0
|
|
||||||
(p6) fma.s1 f6 = f6, f6, f7 // e1 = e0*e0 + 2^-34
|
|
||||||
;;
|
|
||||||
#ifdef MODULO
|
|
||||||
setf.sig f7 = in0
|
|
||||||
#endif
|
|
||||||
(p6) fma.s1 f6 = f6, f8, f8 // q2 = e1*q1 + q1
|
|
||||||
;;
|
|
||||||
FP_TO_INT(f6, f6) // q = trunc(q2)
|
|
||||||
;;
|
|
||||||
#ifdef MODULO
|
|
||||||
xma.l f6 = f6, f9, f7 // r = q*(-b) + a
|
|
||||||
;;
|
|
||||||
#endif
|
|
||||||
getf.sig r8 = f6 // transfer result to result register
|
|
||||||
br.ret.sptk.many rp
|
|
||||||
|
|
||||||
.size NAME, . - NAME
|
|
||||||
.endp NAME
|
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
|
|
||||||
* Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
|
|
||||||
*
|
|
||||||
* 64-bit integer division.
|
|
||||||
*
|
|
||||||
* This code is based on the application note entitled "Divide, Square Root
|
|
||||||
* and Remainder Algorithms for the IA-64 Architecture". This document
|
|
||||||
* is available as Intel document number 248725-002 or via the web at
|
|
||||||
* http://developer.intel.com/software/opensource/numerics/
|
|
||||||
*
|
|
||||||
* For more details on the theory behind these algorithms, see "IA-64
|
|
||||||
* and Elementary Functions" by Peter Markstein; HP Professional Books
|
|
||||||
* (http://www.hp.com/go/retailbooks/)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef MODULO
|
|
||||||
# define OP mod
|
|
||||||
#else
|
|
||||||
# define OP div
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSIGNED
|
|
||||||
# define SGN u
|
|
||||||
# define INT_TO_FP(a,b) fcvt.xuf.s1 a=b
|
|
||||||
# define FP_TO_INT(a,b) fcvt.fxu.trunc.s1 a=b
|
|
||||||
#else
|
|
||||||
# define SGN
|
|
||||||
# define INT_TO_FP(a,b) fcvt.xf a=b
|
|
||||||
# define FP_TO_INT(a,b) fcvt.fx.trunc.s1 a=b
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PASTE1(a,b) a##b
|
|
||||||
#define PASTE(a,b) PASTE1(a,b)
|
|
||||||
#define NAME PASTE(PASTE(__,SGN),PASTE(OP,di3))
|
|
||||||
|
|
||||||
.text
|
|
||||||
.global NAME
|
|
||||||
.proc NAME
|
|
||||||
NAME :
|
|
||||||
.prologue
|
|
||||||
.regstk 2,0,0,0
|
|
||||||
// Transfer inputs to FP registers.
|
|
||||||
setf.sig f8 = in0
|
|
||||||
setf.sig f9 = in1
|
|
||||||
;;
|
|
||||||
.fframe 16
|
|
||||||
.save.f 0x20
|
|
||||||
stf.spill [sp] = f17,-16
|
|
||||||
|
|
||||||
// Convert the inputs to FP, to avoid FP software-assist faults.
|
|
||||||
INT_TO_FP(f8, f8)
|
|
||||||
;;
|
|
||||||
|
|
||||||
.save.f 0x10
|
|
||||||
stf.spill [sp] = f16
|
|
||||||
.body
|
|
||||||
INT_TO_FP(f9, f9)
|
|
||||||
;;
|
|
||||||
frcpa.s1 f17, p6 = f8, f9 // y0 = frcpa(b)
|
|
||||||
;;
|
|
||||||
(p6) fmpy.s1 f7 = f8, f17 // q0 = a*y0
|
|
||||||
(p6) fnma.s1 f6 = f9, f17, f1 // e0 = -b*y0 + 1
|
|
||||||
;;
|
|
||||||
(p6) fma.s1 f16 = f7, f6, f7 // q1 = q0*e0 + q0
|
|
||||||
(p6) fmpy.s1 f7 = f6, f6 // e1 = e0*e0
|
|
||||||
;;
|
|
||||||
#ifdef MODULO
|
|
||||||
sub in1 = r0, in1 // in1 = -b
|
|
||||||
#endif
|
|
||||||
(p6) fma.s1 f16 = f16, f7, f16 // q2 = q1*e1 + q1
|
|
||||||
(p6) fma.s1 f6 = f17, f6, f17 // y1 = y0*e0 + y0
|
|
||||||
;;
|
|
||||||
(p6) fma.s1 f6 = f6, f7, f6 // y2 = y1*e1 + y1
|
|
||||||
(p6) fnma.s1 f7 = f9, f16, f8 // r = -b*q2 + a
|
|
||||||
;;
|
|
||||||
#ifdef MODULO
|
|
||||||
setf.sig f8 = in0 // f8 = a
|
|
||||||
setf.sig f9 = in1 // f9 = -b
|
|
||||||
#endif
|
|
||||||
(p6) fma.s1 f17 = f7, f6, f16 // q3 = r*y2 + q2
|
|
||||||
;;
|
|
||||||
.restore sp
|
|
||||||
ldf.fill f16 = [sp], 16
|
|
||||||
FP_TO_INT(f17, f17) // q = trunc(q3)
|
|
||||||
;;
|
|
||||||
#ifdef MODULO
|
|
||||||
xma.l f17 = f17, f9, f8 // r = q*(-b) + a
|
|
||||||
;;
|
|
||||||
#endif
|
|
||||||
getf.sig r8 = f17 // transfer result to result register
|
|
||||||
ldf.fill f17 = [sp]
|
|
||||||
br.ret.sptk.many rp
|
|
||||||
|
|
||||||
.size NAME, . - NAME
|
|
||||||
.endp NAME
|
|
|
@ -1,163 +0,0 @@
|
||||||
/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
|
||||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the GNU C Library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
||||||
02111-1307 USA.
|
|
||||||
|
|
||||||
Note that __sigsetjmp() did NOT flush the register stack. Instead,
|
|
||||||
we do it here since __longjmp() is usually much less frequently
|
|
||||||
invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp()
|
|
||||||
didn't (and wouldn't be able to) save ar.rnat either. This is a problem
|
|
||||||
because if we're not careful, we could end up loading random NaT bits.
|
|
||||||
There are two cases:
|
|
||||||
|
|
||||||
(i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
|
||||||
ar.rnat contains the desired bits---preserve ar.rnat
|
|
||||||
across loadrs and write to ar.bspstore
|
|
||||||
|
|
||||||
(ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
|
||||||
The desired ar.rnat is stored in
|
|
||||||
ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those
|
|
||||||
bits into ar.rnat after setting ar.bspstore. */
|
|
||||||
|
|
||||||
|
|
||||||
# define pPos p6 /* is rotate count positive? */
|
|
||||||
# define pNeg p7 /* is rotate count negative? */
|
|
||||||
|
|
||||||
|
|
||||||
/* longjmp(__jmp_buf buf, int val) */
|
|
||||||
|
|
||||||
.text
|
|
||||||
.global longjmp
|
|
||||||
.proc longjmp
|
|
||||||
longjmp:
|
|
||||||
|
|
||||||
alloc r8=ar.pfs,2,1,0,0
|
|
||||||
mov r27=ar.rsc
|
|
||||||
add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
|
|
||||||
;;
|
|
||||||
ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr
|
|
||||||
mov r10=ar.bsp
|
|
||||||
and r11=~0x3,r27 // clear ar.rsc.mode
|
|
||||||
;;
|
|
||||||
flushrs // flush dirty regs to backing store (must be first in insn grp)
|
|
||||||
ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp
|
|
||||||
sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf
|
|
||||||
;;
|
|
||||||
ld8 r25=[r2] // r25 <- jmpbuf.ar_unat
|
|
||||||
extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f
|
|
||||||
;;
|
|
||||||
cmp.lt pNeg,pPos=r8,r0
|
|
||||||
mov r2=in0
|
|
||||||
;;
|
|
||||||
(pPos) mov r16=r8
|
|
||||||
(pNeg) add r16=64,r8
|
|
||||||
(pPos) sub r17=64,r8
|
|
||||||
(pNeg) sub r17=r0,r8
|
|
||||||
;;
|
|
||||||
mov ar.rsc=r11 // put RSE in enforced lazy mode
|
|
||||||
shr.u r8=r25,r16
|
|
||||||
add r3=8,in0 // r3 <- &jmpbuf.r1
|
|
||||||
shl r9=r25,r17
|
|
||||||
;;
|
|
||||||
or r25=r8,r9
|
|
||||||
;;
|
|
||||||
mov r26=ar.rnat
|
|
||||||
mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12)
|
|
||||||
;;
|
|
||||||
ld8.fill.nta sp=[r2],16 // r12 (sp)
|
|
||||||
ld8.fill.nta gp=[r3],16 // r1 (gp)
|
|
||||||
dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
|
||||||
;;
|
|
||||||
ld8.nta r16=[r2],16 // caller's unat
|
|
||||||
ld8.nta r17=[r3],16 // fpsr
|
|
||||||
;;
|
|
||||||
ld8.fill.nta r4=[r2],16 // r4
|
|
||||||
ld8.fill.nta r5=[r3],16 // r5 (gp)
|
|
||||||
cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp)
|
|
||||||
;;
|
|
||||||
ld8.fill.nta r6=[r2],16 // r6
|
|
||||||
ld8.fill.nta r7=[r3],16 // r7
|
|
||||||
;;
|
|
||||||
mov ar.unat=r16 // restore caller's unat
|
|
||||||
mov ar.fpsr=r17 // restore fpsr
|
|
||||||
;;
|
|
||||||
ld8.nta r16=[r2],16 // b0
|
|
||||||
ld8.nta r17=[r3],16 // b1
|
|
||||||
;;
|
|
||||||
(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
|
||||||
mov ar.bspstore=r23 // restore ar.bspstore
|
|
||||||
;;
|
|
||||||
ld8.nta r18=[r2],16 // b2
|
|
||||||
ld8.nta r19=[r3],16 // b3
|
|
||||||
;;
|
|
||||||
ld8.nta r20=[r2],16 // b4
|
|
||||||
ld8.nta r21=[r3],16 // b5
|
|
||||||
;;
|
|
||||||
ld8.nta r11=[r2],16 // ar.pfs
|
|
||||||
ld8.nta r22=[r3],56 // ar.lc
|
|
||||||
;;
|
|
||||||
ld8.nta r24=[r2],32 // pr
|
|
||||||
mov b0=r16
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f2=[r2],32
|
|
||||||
ldf.fill.nta f3=[r3],32
|
|
||||||
mov b1=r17
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f4=[r2],32
|
|
||||||
ldf.fill.nta f5=[r3],32
|
|
||||||
mov b2=r18
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f16=[r2],32
|
|
||||||
ldf.fill.nta f17=[r3],32
|
|
||||||
mov b3=r19
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f18=[r2],32
|
|
||||||
ldf.fill.nta f19=[r3],32
|
|
||||||
mov b4=r20
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f20=[r2],32
|
|
||||||
ldf.fill.nta f21=[r3],32
|
|
||||||
mov b5=r21
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f22=[r2],32
|
|
||||||
ldf.fill.nta f23=[r3],32
|
|
||||||
mov ar.lc=r22
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f24=[r2],32
|
|
||||||
ldf.fill.nta f25=[r3],32
|
|
||||||
cmp.eq p8,p9=0,in1
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f26=[r2],32
|
|
||||||
ldf.fill.nta f27=[r3],32
|
|
||||||
mov ar.pfs=r11
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f28=[r2],32
|
|
||||||
ldf.fill.nta f29=[r3],32
|
|
||||||
;;
|
|
||||||
ldf.fill.nta f30=[r2]
|
|
||||||
ldf.fill.nta f31=[r3]
|
|
||||||
(p8) mov r8=1
|
|
||||||
|
|
||||||
mov ar.rnat=r26 // restore ar.rnat
|
|
||||||
;;
|
|
||||||
mov ar.rsc=r27 // restore ar.rsc
|
|
||||||
(p9) mov r8=in1
|
|
||||||
|
|
||||||
invala // virt. -> phys. regnum mapping may change
|
|
||||||
mov pr=r24,-1
|
|
||||||
br.ret.sptk.few b0
|
|
||||||
.size longjmp, . - longjmp
|
|
||||||
.endp longjmp
|
|
|
@ -1,244 +0,0 @@
|
||||||
/* Optimized version of the standard memmove() function.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
|
||||||
Contributed by Dan Pop <Dan.Pop@cern.ch>.
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the GNU C Library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
||||||
02111-1307 USA. */
|
|
||||||
|
|
||||||
/* Return: dest
|
|
||||||
|
|
||||||
Inputs:
|
|
||||||
in0: dest
|
|
||||||
in1: src
|
|
||||||
in2: byte count
|
|
||||||
|
|
||||||
The core of the function is the memcpy implementation used in memcpy.S.
|
|
||||||
When bytes have to be copied backwards, only the easy case, when
|
|
||||||
all arguments are multiples of 8, is optimised.
|
|
||||||
|
|
||||||
In this form, it assumes little endian mode. For big endian mode,
|
|
||||||
sh1 must be computed using an extra instruction: sub sh1 = 64, sh1
|
|
||||||
or the UM.be bit should be cleared at the beginning and set at the end. */
|
|
||||||
|
|
||||||
|
|
||||||
#define OP_T_THRES 16
|
|
||||||
#define OPSIZ 8
|
|
||||||
|
|
||||||
#define adest r15
|
|
||||||
#define saved_pr r17
|
|
||||||
#define saved_lc r18
|
|
||||||
#define dest r19
|
|
||||||
#define src r20
|
|
||||||
#define len r21
|
|
||||||
#define asrc r22
|
|
||||||
#define tmp2 r23
|
|
||||||
#define tmp3 r24
|
|
||||||
#define tmp4 r25
|
|
||||||
#define ptable r26
|
|
||||||
#define ploop56 r27
|
|
||||||
#define loopaddr r28
|
|
||||||
#define sh1 r29
|
|
||||||
#define loopcnt r30
|
|
||||||
#define value r31
|
|
||||||
|
|
||||||
#define LOOP(shift) \
|
|
||||||
.align 32 ; \
|
|
||||||
.loop##shift##: \
|
|
||||||
(p[0]) ld8 r[0] = [asrc], 8 ; /* w1 */ \
|
|
||||||
(p[MEMLAT+1]) st8 [dest] = value, 8 ; \
|
|
||||||
(p[MEMLAT]) shrp value = r[MEMLAT], r[MEMLAT+1], shift ; \
|
|
||||||
nop.b 0 ; \
|
|
||||||
nop.b 0 ; \
|
|
||||||
br.ctop.sptk .loop##shift ; \
|
|
||||||
br.cond.sptk .cpyfew ; /* deal with the remaining bytes */
|
|
||||||
|
|
||||||
#define MEMLAT 21
|
|
||||||
#define Nrot (((2*MEMLAT+3) + 7) & ~7)
|
|
||||||
|
|
||||||
.text
|
|
||||||
.global memmove, memcpy
|
|
||||||
.proc memove
|
|
||||||
memcpy:
|
|
||||||
memmove:
|
|
||||||
.prologue
|
|
||||||
alloc r2 = ar.pfs, 3, Nrot - 3, 0, Nrot
|
|
||||||
.rotr r[MEMLAT + 2], q[MEMLAT + 1]
|
|
||||||
.rotp p[MEMLAT + 2]
|
|
||||||
mov ret0 = in0 // return value = dest
|
|
||||||
.save pr, saved_pr
|
|
||||||
mov saved_pr = pr // save the predicate registers
|
|
||||||
.save ar.lc, saved_lc
|
|
||||||
mov saved_lc = ar.lc // save the loop counter
|
|
||||||
.body
|
|
||||||
or tmp3 = in0, in1 ;; // tmp3 = dest | src
|
|
||||||
or tmp3 = tmp3, in2 // tmp3 = dest | src | len
|
|
||||||
mov dest = in0 // dest
|
|
||||||
mov src = in1 // src
|
|
||||||
mov len = in2 // len
|
|
||||||
sub tmp2 = r0, in0 // tmp2 = -dest
|
|
||||||
cmp.eq p6, p0 = in2, r0 // if (len == 0)
|
|
||||||
(p6) br.cond.spnt .restore_and_exit;;// return dest;
|
|
||||||
and tmp4 = 7, tmp3 // tmp4 = (dest | src | len) & 7
|
|
||||||
cmp.le p6, p0 = dest, src // if dest <= src it's always safe
|
|
||||||
(p6) br.cond.spnt .forward // to copy forward
|
|
||||||
add tmp3 = src, len;;
|
|
||||||
cmp.lt p6, p0 = dest, tmp3 // if dest > src && dest < src + len
|
|
||||||
(p6) br.cond.spnt .backward // we have to copy backward
|
|
||||||
|
|
||||||
.forward:
|
|
||||||
shr.u loopcnt = len, 4 ;; // loopcnt = len / 16
|
|
||||||
cmp.ne p6, p0 = tmp4, r0 // if ((dest | src | len) & 7 != 0)
|
|
||||||
(p6) br.cond.sptk .next // goto next;
|
|
||||||
|
|
||||||
// The optimal case, when dest, src and len are all multiples of 8
|
|
||||||
|
|
||||||
and tmp3 = 0xf, len
|
|
||||||
mov pr.rot = 1 << 16 // set rotating predicates
|
|
||||||
mov ar.ec = MEMLAT + 1 ;; // set the epilog counter
|
|
||||||
cmp.ne p6, p0 = tmp3, r0 // do we have to copy an extra word?
|
|
||||||
adds loopcnt = -1, loopcnt;; // --loopcnt
|
|
||||||
(p6) ld8 value = [src], 8;;
|
|
||||||
(p6) st8 [dest] = value, 8 // copy the "odd" word
|
|
||||||
mov ar.lc = loopcnt // set the loop counter
|
|
||||||
cmp.eq p6, p0 = 8, len
|
|
||||||
(p6) br.cond.spnt .restore_and_exit;;// the one-word special case
|
|
||||||
adds adest = 8, dest // set adest one word ahead of dest
|
|
||||||
adds asrc = 8, src ;; // set asrc one word ahead of src
|
|
||||||
nop.b 0 // get the "golden" alignment for
|
|
||||||
nop.b 0 // the next loop
|
|
||||||
.l0:
|
|
||||||
(p[0]) ld8 r[0] = [src], 16
|
|
||||||
(p[0]) ld8 q[0] = [asrc], 16
|
|
||||||
(p[MEMLAT]) st8 [dest] = r[MEMLAT], 16
|
|
||||||
(p[MEMLAT]) st8 [adest] = q[MEMLAT], 16
|
|
||||||
br.ctop.dptk .l0 ;;
|
|
||||||
|
|
||||||
mov pr = saved_pr, -1 // restore the predicate registers
|
|
||||||
mov ar.lc = saved_lc // restore the loop counter
|
|
||||||
br.ret.sptk.many b0
|
|
||||||
.next:
|
|
||||||
cmp.ge p6, p0 = OP_T_THRES, len // is len <= OP_T_THRES
|
|
||||||
and loopcnt = 7, tmp2 // loopcnt = -dest % 8
|
|
||||||
(p6) br.cond.spnt .cpyfew // copy byte by byte
|
|
||||||
;;
|
|
||||||
cmp.eq p6, p0 = loopcnt, r0
|
|
||||||
(p6) br.cond.sptk .dest_aligned
|
|
||||||
sub len = len, loopcnt // len -= -dest % 8
|
|
||||||
adds loopcnt = -1, loopcnt // --loopcnt
|
|
||||||
;;
|
|
||||||
mov ar.lc = loopcnt
|
|
||||||
.l1: // copy -dest % 8 bytes
|
|
||||||
ld1 value = [src], 1 // value = *src++
|
|
||||||
;;
|
|
||||||
st1 [dest] = value, 1 // *dest++ = value
|
|
||||||
br.cloop.dptk .l1
|
|
||||||
.dest_aligned:
|
|
||||||
and sh1 = 7, src // sh1 = src % 8
|
|
||||||
and tmp2 = -8, len // tmp2 = len & -OPSIZ
|
|
||||||
and asrc = -8, src // asrc = src & -OPSIZ -- align src
|
|
||||||
shr.u loopcnt = len, 3 // loopcnt = len / 8
|
|
||||||
and len = 7, len;; // len = len % 8
|
|
||||||
adds loopcnt = -1, loopcnt // --loopcnt
|
|
||||||
addl tmp4 = @ltoff(.table), gp
|
|
||||||
addl tmp3 = @ltoff(.loop56), gp
|
|
||||||
mov ar.ec = MEMLAT + 1 // set EC
|
|
||||||
mov pr.rot = 1 << 16;; // set rotating predicates
|
|
||||||
mov ar.lc = loopcnt // set LC
|
|
||||||
cmp.eq p6, p0 = sh1, r0 // is the src aligned?
|
|
||||||
(p6) br.cond.sptk .src_aligned
|
|
||||||
add src = src, tmp2 // src += len & -OPSIZ
|
|
||||||
shl sh1 = sh1, 3 // sh1 = 8 * (src % 8)
|
|
||||||
ld8 ploop56 = [tmp3] // ploop56 = &loop56
|
|
||||||
ld8 ptable = [tmp4];; // ptable = &table
|
|
||||||
add tmp3 = ptable, sh1;; // tmp3 = &table + sh1
|
|
||||||
mov ar.ec = MEMLAT + 1 + 1 // one more pass needed
|
|
||||||
ld8 tmp4 = [tmp3];; // tmp4 = loop offset
|
|
||||||
sub loopaddr = ploop56,tmp4 // loopadd = &loop56 - loop offset
|
|
||||||
ld8 r[1] = [asrc], 8;; // w0
|
|
||||||
mov b6 = loopaddr;;
|
|
||||||
br b6 // jump to the appropriate loop
|
|
||||||
|
|
||||||
LOOP(8)
|
|
||||||
LOOP(16)
|
|
||||||
LOOP(24)
|
|
||||||
LOOP(32)
|
|
||||||
LOOP(40)
|
|
||||||
LOOP(48)
|
|
||||||
LOOP(56)
|
|
||||||
|
|
||||||
.src_aligned:
|
|
||||||
.l3:
|
|
||||||
(p[0]) ld8 r[0] = [src], 8
|
|
||||||
(p[MEMLAT]) st8 [dest] = r[MEMLAT], 8
|
|
||||||
br.ctop.dptk .l3
|
|
||||||
.cpyfew:
|
|
||||||
cmp.eq p6, p0 = len, r0 // is len == 0 ?
|
|
||||||
adds len = -1, len // --len;
|
|
||||||
(p6) br.cond.spnt .restore_and_exit ;;
|
|
||||||
mov ar.lc = len
|
|
||||||
.l4:
|
|
||||||
ld1 value = [src], 1
|
|
||||||
;;
|
|
||||||
st1 [dest] = value, 1
|
|
||||||
br.cloop.dptk .l4 ;;
|
|
||||||
.restore_and_exit:
|
|
||||||
mov pr = saved_pr, -1 // restore the predicate registers
|
|
||||||
mov ar.lc = saved_lc // restore the loop counter
|
|
||||||
br.ret.sptk.many b0
|
|
||||||
|
|
||||||
// In the case of a backward copy, optimise only the case when everything
|
|
||||||
// is a multiple of 8, otherwise copy byte by byte. The backward copy is
|
|
||||||
// used only when the blocks are overlapping and dest > src.
|
|
||||||
|
|
||||||
.backward:
|
|
||||||
shr.u loopcnt = len, 3 // loopcnt = len / 8
|
|
||||||
add src = src, len // src points one byte past the end
|
|
||||||
add dest = dest, len ;; // dest points one byte past the end
|
|
||||||
mov ar.ec = MEMLAT + 1 // set the epilog counter
|
|
||||||
mov pr.rot = 1 << 16 // set rotating predicates
|
|
||||||
adds loopcnt = -1, loopcnt // --loopcnt
|
|
||||||
cmp.ne p6, p0 = tmp4, r0 // if ((dest | src | len) & 7 != 0)
|
|
||||||
(p6) br.cond.sptk .bytecopy ;; // copy byte by byte backward
|
|
||||||
adds src = -8, src // src points to the last word
|
|
||||||
adds dest = -8, dest // dest points to the last word
|
|
||||||
mov ar.lc = loopcnt;; // set the loop counter
|
|
||||||
.l5:
|
|
||||||
(p[0]) ld8 r[0] = [src], -8
|
|
||||||
(p[MEMLAT]) st8 [dest] = r[MEMLAT], -8
|
|
||||||
br.ctop.dptk .l5
|
|
||||||
br.cond.sptk .restore_and_exit
|
|
||||||
.bytecopy:
|
|
||||||
adds src = -1, src // src points to the last byte
|
|
||||||
adds dest = -1, dest // dest points to the last byte
|
|
||||||
adds loopcnt = -1, len;; // loopcnt = len - 1
|
|
||||||
mov ar.lc = loopcnt;; // set the loop counter
|
|
||||||
.l6:
|
|
||||||
(p[0]) ld1 r[0] = [src], -1
|
|
||||||
(p[MEMLAT]) st1 [dest] = r[MEMLAT], -1
|
|
||||||
br.ctop.dptk .l6
|
|
||||||
br.cond.sptk .restore_and_exit
|
|
||||||
.table:
|
|
||||||
data8 0 // dummy entry
|
|
||||||
data8 .loop56 - .loop8
|
|
||||||
data8 .loop56 - .loop16
|
|
||||||
data8 .loop56 - .loop24
|
|
||||||
data8 .loop56 - .loop32
|
|
||||||
data8 .loop56 - .loop40
|
|
||||||
data8 .loop56 - .loop48
|
|
||||||
data8 .loop56 - .loop56
|
|
||||||
|
|
||||||
.size memmove, . - memove
|
|
||||||
.endp memmove
|
|
|
@ -1,133 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 1999-2002 Hewlett-Packard Co.
|
|
||||||
* Contributed by Stephane Eranian <eranian@hpl.hp.com>
|
|
||||||
*
|
|
||||||
* This file is part of the ELILO, the EFI Linux boot loader.
|
|
||||||
*
|
|
||||||
* ELILO is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* ELILO is distributed in the hope that 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 ELILO; see the file COPYING. If not, write to the Free
|
|
||||||
* Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
* 02111-1307, USA.
|
|
||||||
*
|
|
||||||
* Please check out the elilo.txt for complete documentation on how
|
|
||||||
* to use this program.
|
|
||||||
*
|
|
||||||
* This code is derived from the Linux/ia64 source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Optimized version of the standard memset() function
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*
|
|
||||||
* Inputs:
|
|
||||||
* in0: address of buffer
|
|
||||||
* in1: byte value to use for storing
|
|
||||||
* in2: length of the buffer
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// arguments
|
|
||||||
//
|
|
||||||
#define buf r32
|
|
||||||
#define val r33
|
|
||||||
#define len r34
|
|
||||||
|
|
||||||
//
|
|
||||||
// local registers
|
|
||||||
//
|
|
||||||
#define saved_pfs r14
|
|
||||||
#define cnt r18
|
|
||||||
#define buf2 r19
|
|
||||||
#define saved_lc r20
|
|
||||||
#define tmp r21
|
|
||||||
.text
|
|
||||||
.global memset
|
|
||||||
.proc memset
|
|
||||||
memset:
|
|
||||||
.prologue
|
|
||||||
.save ar.pfs, saved_pfs
|
|
||||||
alloc saved_pfs=ar.pfs,3,0,0,0 // cnt is sink here
|
|
||||||
cmp.eq p8,p0=r0,len // check for zero length
|
|
||||||
.save ar.lc, saved_lc
|
|
||||||
mov saved_lc=ar.lc // preserve ar.lc (slow)
|
|
||||||
;;
|
|
||||||
|
|
||||||
.body
|
|
||||||
|
|
||||||
adds tmp=-1,len // br.ctop is repeat/until
|
|
||||||
tbit.nz p6,p0=buf,0 // odd alignment
|
|
||||||
(p8) br.ret.spnt.few rp
|
|
||||||
|
|
||||||
cmp.lt p7,p0=16,len // if len > 16 then long memset
|
|
||||||
mux1 val=val,@brcst // prepare value
|
|
||||||
(p7) br.cond.dptk.few long_memset
|
|
||||||
;;
|
|
||||||
mov ar.lc=tmp // initialize lc for small count
|
|
||||||
;; // avoid RAW and WAW on ar.lc
|
|
||||||
1: // worst case 15 cyles, avg 8 cycles
|
|
||||||
st1 [buf]=val,1
|
|
||||||
br.cloop.dptk.few 1b
|
|
||||||
;; // avoid RAW on ar.lc
|
|
||||||
mov ar.lc=saved_lc
|
|
||||||
mov ar.pfs=saved_pfs
|
|
||||||
br.ret.sptk.few rp // end of short memset
|
|
||||||
|
|
||||||
// at this point we know we have more than 16 bytes to copy
|
|
||||||
// so we focus on alignment
|
|
||||||
long_memset:
|
|
||||||
(p6) st1 [buf]=val,1 // 1-byte aligned
|
|
||||||
(p6) adds len=-1,len;; // sync because buf is modified
|
|
||||||
tbit.nz p6,p0=buf,1
|
|
||||||
;;
|
|
||||||
(p6) st2 [buf]=val,2 // 2-byte aligned
|
|
||||||
(p6) adds len=-2,len;;
|
|
||||||
tbit.nz p6,p0=buf,2
|
|
||||||
;;
|
|
||||||
(p6) st4 [buf]=val,4 // 4-byte aligned
|
|
||||||
(p6) adds len=-4,len;;
|
|
||||||
tbit.nz p6,p0=buf,3
|
|
||||||
;;
|
|
||||||
(p6) st8 [buf]=val,8 // 8-byte aligned
|
|
||||||
(p6) adds len=-8,len;;
|
|
||||||
shr.u cnt=len,4 // number of 128-bit (2x64bit) words
|
|
||||||
;;
|
|
||||||
cmp.eq p6,p0=r0,cnt
|
|
||||||
adds tmp=-1,cnt
|
|
||||||
(p6) br.cond.dpnt.few .dotail // we have less than 16 bytes left
|
|
||||||
;;
|
|
||||||
adds buf2=8,buf // setup second base pointer
|
|
||||||
mov ar.lc=tmp
|
|
||||||
;;
|
|
||||||
2: // 16bytes/iteration
|
|
||||||
st8 [buf]=val,16
|
|
||||||
st8 [buf2]=val,16
|
|
||||||
br.cloop.dptk.few 2b
|
|
||||||
;;
|
|
||||||
.dotail: // tail correction based on len only
|
|
||||||
tbit.nz p6,p0=len,3
|
|
||||||
;;
|
|
||||||
(p6) st8 [buf]=val,8 // at least 8 bytes
|
|
||||||
tbit.nz p6,p0=len,2
|
|
||||||
;;
|
|
||||||
(p6) st4 [buf]=val,4 // at least 4 bytes
|
|
||||||
tbit.nz p6,p0=len,1
|
|
||||||
;;
|
|
||||||
(p6) st2 [buf]=val,2 // at least 2 bytes
|
|
||||||
tbit.nz p6,p0=len,0
|
|
||||||
mov ar.lc=saved_lc
|
|
||||||
;;
|
|
||||||
(p6) st1 [buf]=val // only 1 byte left
|
|
||||||
br.ret.dptk.few rp
|
|
||||||
.endp memset
|
|
|
@ -1,84 +0,0 @@
|
||||||
#include "etherboot.h"
|
|
||||||
#include "sal.h"
|
|
||||||
#include "pal.h"
|
|
||||||
|
|
||||||
struct fptr pal_entry;
|
|
||||||
/*
|
|
||||||
* Note that some of these calls use a static-register only calling
|
|
||||||
* convention which has nothing to do with the regular calling
|
|
||||||
* convention.
|
|
||||||
*/
|
|
||||||
#define PAL_CACHE_FLUSH 1 /* flush i/d cache */
|
|
||||||
#define PAL_CACHE_INFO 2 /* get detailed i/d cache info */
|
|
||||||
#define PAL_CACHE_INIT 3 /* initialize i/d cache */
|
|
||||||
#define PAL_CACHE_SUMMARY 4 /* get summary of cache heirarchy */
|
|
||||||
#define PAL_MEM_ATTRIB 5 /* list supported memory attributes */
|
|
||||||
#define PAL_PTCE_INFO 6 /* purge TLB info */
|
|
||||||
#define PAL_VM_INFO 7 /* return supported virtual memory features */
|
|
||||||
#define PAL_VM_SUMMARY 8 /* return summary on supported vm features */
|
|
||||||
#define PAL_BUS_GET_FEATURES 9 /* return processor bus interface features settings */
|
|
||||||
#define PAL_BUS_SET_FEATURES 10 /* set processor bus features */
|
|
||||||
#define PAL_DEBUG_INFO 11 /* get number of debug registers */
|
|
||||||
#define PAL_FIXED_ADDR 12 /* get fixed component of processors's directed address */
|
|
||||||
#define PAL_FREQ_BASE 13 /* base frequency of the platform */
|
|
||||||
#define PAL_FREQ_RATIOS 14 /* ratio of processor, bus and ITC frequency */
|
|
||||||
#define PAL_PERF_MON_INFO 15 /* return performance monitor info */
|
|
||||||
#define PAL_PLATFORM_ADDR 16 /* set processor interrupt block and IO port space addr */
|
|
||||||
#define PAL_PROC_GET_FEATURES 17 /* get configurable processor features & settings */
|
|
||||||
#define PAL_PROC_SET_FEATURES 18 /* enable/disable configurable processor features */
|
|
||||||
#define PAL_RSE_INFO 19 /* return rse information */
|
|
||||||
#define PAL_VERSION 20 /* return version of PAL code */
|
|
||||||
#define PAL_MC_CLEAR_LOG 21 /* clear all processor log info */
|
|
||||||
#define PAL_MC_DRAIN 22 /* drain operations which could result in an MCA */
|
|
||||||
#define PAL_MC_EXPECTED 23 /* set/reset expected MCA indicator */
|
|
||||||
#define PAL_MC_DYNAMIC_STATE 24 /* get processor dynamic state */
|
|
||||||
#define PAL_MC_ERROR_INFO 25 /* get processor MCA info and static state */
|
|
||||||
#define PAL_MC_RESUME 26 /* Return to interrupted process */
|
|
||||||
#define PAL_MC_REGISTER_MEM 27 /* Register memory for PAL to use during MCAs and inits */
|
|
||||||
#define PAL_HALT 28 /* enter the low power HALT state */
|
|
||||||
#define PAL_HALT_LIGHT 29 /* enter the low power light halt state*/
|
|
||||||
#define PAL_COPY_INFO 30 /* returns info needed to relocate PAL */
|
|
||||||
#define PAL_CACHE_LINE_INIT 31 /* init tags & data of cache line */
|
|
||||||
#define PAL_PMI_ENTRYPOINT 32 /* register PMI memory entry points with the processor */
|
|
||||||
#define PAL_ENTER_IA_32_ENV 33 /* enter IA-32 system environment */
|
|
||||||
#define PAL_VM_PAGE_SIZE 34 /* return vm TC and page walker page sizes */
|
|
||||||
|
|
||||||
#define PAL_MEM_FOR_TEST 37 /* get amount of memory needed for late processor test */
|
|
||||||
#define PAL_CACHE_PROT_INFO 38 /* get i/d cache protection info */
|
|
||||||
#define PAL_REGISTER_INFO 39 /* return AR and CR register information*/
|
|
||||||
#define PAL_SHUTDOWN 40 /* enter processor shutdown state */
|
|
||||||
#define PAL_PREFETCH_VISIBILITY 41
|
|
||||||
|
|
||||||
#define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */
|
|
||||||
#define PAL_HALT_INFO 257 /* return the low power capabilities of processor */
|
|
||||||
#define PAL_TEST_PROC 258 /* perform late processor self-test */
|
|
||||||
#define PAL_CACHE_READ 259 /* read tag & data of cacheline for diagnostic testing */
|
|
||||||
#define PAL_CACHE_WRITE 260 /* write tag & data of cacheline for diagnostic testing */
|
|
||||||
#define PAL_VM_TR_READ 261 /* read contents of translation register */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the ratios for processor frequency, bus frequency and interval timer to
|
|
||||||
* to base frequency of the platform
|
|
||||||
*/
|
|
||||||
long pal_freq_ratios(struct pal_freq_ratio *proc_ratio,
|
|
||||||
struct pal_freq_ratio *bus_ratio, struct pal_freq_ratio *itc_ratio)
|
|
||||||
{
|
|
||||||
struct freq_ratios {
|
|
||||||
long status;
|
|
||||||
struct pal_freq_ratio proc_ratio;
|
|
||||||
struct pal_freq_ratio bus_ratio;
|
|
||||||
struct pal_freq_ratio itc_ratio;
|
|
||||||
};
|
|
||||||
struct freq_ratios result;
|
|
||||||
extern struct freq_ratios pal_call(unsigned long which, ...);
|
|
||||||
result = pal_call(PAL_FREQ_RATIOS, 0, 0, 0);
|
|
||||||
if (proc_ratio)
|
|
||||||
*proc_ratio = result.proc_ratio;
|
|
||||||
if (bus_ratio)
|
|
||||||
*bus_ratio = result.bus_ratio;
|
|
||||||
if (itc_ratio)
|
|
||||||
*itc_ratio = result.itc_ratio;
|
|
||||||
return result.status;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
#include "etherboot.h"
|
|
||||||
#include "pci.h"
|
|
||||||
#include "sal.h"
|
|
||||||
|
|
||||||
int pcibios_read_config_byte(unsigned int bus, unsigned int devfn, unsigned int reg, uint8_t *rvalue)
|
|
||||||
{
|
|
||||||
unsigned long value;
|
|
||||||
long result;
|
|
||||||
result = sal_pci_config_read(PCI_SAL_ADDRESS(0,bus, 0, devfn, reg), 1, &value);
|
|
||||||
*rvalue = value;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
int pcibios_read_config_word(unsigned int bus, unsigned int devfn, unsigned int reg, uint16_t *rvalue)
|
|
||||||
{
|
|
||||||
unsigned long value;
|
|
||||||
long result;
|
|
||||||
result = sal_pci_config_read(PCI_SAL_ADDRESS(0,bus, 0, devfn, reg), 2, &value);
|
|
||||||
*rvalue = value;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
int pcibios_read_config_dword(unsigned int bus, unsigned int devfn, unsigned int reg, uint32_t *rvalue)
|
|
||||||
{
|
|
||||||
unsigned long value;
|
|
||||||
long result;
|
|
||||||
result = sal_pci_config_read(PCI_SAL_ADDRESS(0,bus, 0, devfn, reg), 4, &value);
|
|
||||||
*rvalue = value;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pcibios_write_config_byte(unsigned int bus, unsigned int devfn, unsigned int reg, uint8_t value)
|
|
||||||
{
|
|
||||||
return sal_pci_config_write(PCI_SAL_ADDRESS(0,bus, 0, devfn, reg), 1, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int pcibios_write_config_word(unsigned int bus, unsigned int devfn, unsigned int reg, uint16_t value)
|
|
||||||
{
|
|
||||||
return sal_pci_config_write(PCI_SAL_ADDRESS(0,bus, 0, devfn, reg), 2, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int pcibios_write_config_dword(unsigned int bus, unsigned int devfn, unsigned int reg, uint32_t value)
|
|
||||||
{
|
|
||||||
return sal_pci_config_write(PCI_SAL_ADDRESS(0,bus, 0, devfn, reg), 4, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* So far I have not see a non-zero PCI_BUS_OFFSET
|
|
||||||
* and an AML parser to get it much to much trouble.
|
|
||||||
*/
|
|
||||||
#ifndef PCI_BUS_OFFSET
|
|
||||||
#define PCI_BUS_OFFSET 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned long pcibios_bus_base(unsigned int bus)
|
|
||||||
{
|
|
||||||
return PCI_BUS_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_pci(int type, struct pci_device *dev)
|
|
||||||
{
|
|
||||||
/* Should I check for sal functions being present? */
|
|
||||||
return scan_pci_bus(type, dev);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
/* reloc.S - position independent IA-64 ELF shared object relocator
|
|
||||||
Copyright (C) 1999 Hewlett-Packard Co.
|
|
||||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
|
||||||
Copyright (C) 2002 Eric Biederman sponsored by Linux Networx
|
|
||||||
|
|
||||||
This file is part of etherboot.
|
|
||||||
This file was derived from reloc_ia64.S from GNU-EFI, the GNU EFI development environment.
|
|
||||||
|
|
||||||
GNU EFI is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
GNU EFI is distributed in the hope that 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 GNU EFI; see the file COPYING. If not, write to the Free
|
|
||||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is written in assembly because the entire code needs to be position
|
|
||||||
* independent. Note that the compiler does not generate code that's position
|
|
||||||
* independent by itself because it relies on the global offset table being
|
|
||||||
* relocated.
|
|
||||||
*
|
|
||||||
* This code assumes the code was compiled with -mconstant-gp -mauto-pic -static -shared
|
|
||||||
* Which generates position independent code, but not position indepedent data.
|
|
||||||
* This code assumes in the linker script the rela entries are bracked with:
|
|
||||||
* _rela, _erela and _rela_size gives the total size of the rela entries.
|
|
||||||
* This gives a much smaller binary than when compiled as a true shared object.
|
|
||||||
*
|
|
||||||
* This code assumes the original shared object was initially relocated,
|
|
||||||
* So that it only needs to apply changes for the new address the code is linked
|
|
||||||
* at.
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
.psr abi64
|
|
||||||
.psr lsb
|
|
||||||
.lsb
|
|
||||||
|
|
||||||
|
|
||||||
#define ST_VALUE_OFF 8 /* offset of st_value in elf sym */
|
|
||||||
|
|
||||||
#define RET_SUCCESS 0
|
|
||||||
#define RET_LOAD_ERROR 1
|
|
||||||
|
|
||||||
#define R_IA64_NONE 0
|
|
||||||
#define R_IA64_REL64MSB 0x6e
|
|
||||||
#define R_IA64_REL64LSB 0x6f
|
|
||||||
#define R_IA64_DIR64MSB 0x26
|
|
||||||
#define R_IA64_DIR64LSB 0x27
|
|
||||||
#define R_IA64_FPTR64MSB 0x46
|
|
||||||
#define R_IA64_FPTR64LSB 0x47
|
|
||||||
|
|
||||||
#define delta in0 /* Chaing in load address (address of .text) */
|
|
||||||
|
|
||||||
#define ldbase r15
|
|
||||||
#define target r16
|
|
||||||
#define val r17
|
|
||||||
#define rela r18
|
|
||||||
#define relasz r19
|
|
||||||
#define relaent r20
|
|
||||||
#define addr r21
|
|
||||||
#define r_info r22
|
|
||||||
#define r_offset r23
|
|
||||||
#define r_type r25
|
|
||||||
|
|
||||||
#define Pmore p6
|
|
||||||
|
|
||||||
#define Pnone p6
|
|
||||||
#define Prel p7
|
|
||||||
#define Pdir p8
|
|
||||||
|
|
||||||
|
|
||||||
.global _relocate
|
|
||||||
_relocate:
|
|
||||||
alloc r2=ar.pfs,1,0,0,0
|
|
||||||
add rela=@gprel(_rela),gp
|
|
||||||
add ldbase=@gprel(_text),gp
|
|
||||||
add r3=@ltoff(_rela_size),gp
|
|
||||||
;;
|
|
||||||
ld8 relasz = [r3]
|
|
||||||
mov relaent=24
|
|
||||||
br.sptk.few apply_relocs
|
|
||||||
|
|
||||||
apply_loop:
|
|
||||||
ld8 r_offset = [rela]
|
|
||||||
add addr = 8,rela
|
|
||||||
sub relasz = relasz,relaent
|
|
||||||
|
|
||||||
;;
|
|
||||||
ld8 r_info = [addr], 8
|
|
||||||
;;
|
|
||||||
add target = ldbase, r_offset
|
|
||||||
add rela = rela,relaent
|
|
||||||
extr.u r_type = r_info, 0, 32
|
|
||||||
;;
|
|
||||||
cmp.eq Pnone,p0 = R_IA64_NONE, r_type
|
|
||||||
cmp.eq Prel,p0 = R_IA64_REL64LSB, r_type
|
|
||||||
cmp.eq Pdir,p0 = R_IA64_DIR64LSB, r_type /* Needed? */
|
|
||||||
;;
|
|
||||||
(Pnone) br.cond.sptk.few apply_relocs
|
|
||||||
(Prel) br.cond.sptk.few apply_REL64
|
|
||||||
(Pdir) br.cond.sptk.few apply_DIR64 /* Needed? */
|
|
||||||
;;
|
|
||||||
|
|
||||||
apply_error:
|
|
||||||
mov r8 = RET_LOAD_ERROR
|
|
||||||
br.ret.sptk.few rp
|
|
||||||
|
|
||||||
apply_REL64:
|
|
||||||
apply_DIR64:
|
|
||||||
ld8 val = [target]
|
|
||||||
;;
|
|
||||||
add val = val, delta
|
|
||||||
;;
|
|
||||||
st8 [target] = val
|
|
||||||
;;
|
|
||||||
/* fall through to apply_relocs */
|
|
||||||
apply_relocs:
|
|
||||||
cmp.ltu Pmore,p0=0,relasz
|
|
||||||
(Pmore) br.cond.sptk.few apply_loop
|
|
||||||
;;
|
|
||||||
|
|
||||||
mov r8 = RET_SUCCESS
|
|
||||||
br.ret.sptk.few rp
|
|
||||||
|
|
||||||
.size _relocate, . - _relocate
|
|
||||||
.endp _relocate
|
|
|
@ -1,92 +0,0 @@
|
||||||
/* Temporarily ignore the stack, as I am still using efi's stack */
|
|
||||||
|
|
||||||
#define newbase in0
|
|
||||||
#define base loc2
|
|
||||||
#define newgp loc3
|
|
||||||
#define len loc4
|
|
||||||
|
|
||||||
.explicit
|
|
||||||
.globl relocate_to
|
|
||||||
.proc relocate_to
|
|
||||||
relocate_to:
|
|
||||||
/* In incoming variable the new base addres of etherboot. */
|
|
||||||
alloc loc0=ar.pfs,1,5,3,0 /* in, local, out, rotating */
|
|
||||||
mov loc1=rp
|
|
||||||
|
|
||||||
/* Compute the current location of _text */
|
|
||||||
/* Compute the new gp value */
|
|
||||||
add base=@gprel(_text),gp
|
|
||||||
add len =@gprel(_end),gp
|
|
||||||
movl newgp=@gprel(_text)
|
|
||||||
;;
|
|
||||||
sub newgp=newbase,newgp /* gp = _text - @gprel(_text) */
|
|
||||||
sub len=len,base
|
|
||||||
;;
|
|
||||||
|
|
||||||
/* Copy etherboot to the new location */
|
|
||||||
mov out0=newbase
|
|
||||||
mov out1=base
|
|
||||||
mov out2=len
|
|
||||||
br.call.sptk.few rp=memcpy
|
|
||||||
;;
|
|
||||||
|
|
||||||
/* Jump to my __relocate_to in the new location */
|
|
||||||
movl r14=@gprel(__relocate_to)
|
|
||||||
;;
|
|
||||||
add r14=r14,newgp
|
|
||||||
;;
|
|
||||||
mov b6=r14
|
|
||||||
;;
|
|
||||||
br.cond.sptk.few b6
|
|
||||||
;;
|
|
||||||
__relocate_to:
|
|
||||||
/* I am at the new location set the newgp as the default */
|
|
||||||
mov gp=newgp
|
|
||||||
;;
|
|
||||||
/* New apply relocations to the new copy */
|
|
||||||
sub out0=newbase,base
|
|
||||||
br.call.sptk.few rp=_relocate
|
|
||||||
;;
|
|
||||||
|
|
||||||
/* Lookup restart_etherboot */
|
|
||||||
add out0=@gprel(restart_etherboot),gp
|
|
||||||
;;
|
|
||||||
|
|
||||||
/* Adjust the gp and return address.
|
|
||||||
* NOTE: This only works when the setjmp can modify it's caller's gp
|
|
||||||
* address. Essentially this means etherboot must be compiled with
|
|
||||||
* compiled with -mconstant-gp, though an inline version of setjmp might work.
|
|
||||||
*/
|
|
||||||
add r14=0x40,out0
|
|
||||||
add r16=0x08,out0
|
|
||||||
;;
|
|
||||||
ld8 r15=[r14]
|
|
||||||
ld8 r17=[r16]
|
|
||||||
;;
|
|
||||||
sub r15=r15,base
|
|
||||||
sub r17=r17,base
|
|
||||||
;;
|
|
||||||
add r15=r15,newbase
|
|
||||||
add r17=r17,newbase
|
|
||||||
;;
|
|
||||||
st8 [r14]=r15
|
|
||||||
st8 [r16]=r17
|
|
||||||
;;
|
|
||||||
mov out1=256
|
|
||||||
br.call.sptk.few rp=longjmp
|
|
||||||
|
|
||||||
/* And just in case lonjmp returns... */
|
|
||||||
|
|
||||||
|
|
||||||
/* Adjust my return address and return */
|
|
||||||
sub loc1=loc1,base
|
|
||||||
;;
|
|
||||||
add loc1=loc1,newbase
|
|
||||||
;;
|
|
||||||
mov ar.pfs=loc0
|
|
||||||
mov rp=loc1
|
|
||||||
;;
|
|
||||||
br.ret.sptk.few rp
|
|
||||||
|
|
||||||
.size relocate_to, . - relocate_to
|
|
||||||
.endp relocate_to
|
|
|
@ -1,278 +0,0 @@
|
||||||
#include "etherboot.h"
|
|
||||||
#include "sal.h"
|
|
||||||
|
|
||||||
struct sal_entry_base {
|
|
||||||
uint8_t entry_type;
|
|
||||||
#define SAL_TYPE_ENTRYPOINT 0
|
|
||||||
#define SAL_TYPE_MEMORY 1
|
|
||||||
#define SAL_TYPE_PLATFORM_FEATURES 2
|
|
||||||
#define SAL_TYPE_TRANSLATION_REGISTER 3
|
|
||||||
#define SAL_TYPE_PURGE_DOMAIN 4
|
|
||||||
#define SAL_TYPE_AP_WAKEUP 5
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sal_entry_point_descriptor {
|
|
||||||
uint8_t entry_type;
|
|
||||||
uint8_t reserved[7];
|
|
||||||
uint64_t pal_proc;
|
|
||||||
uint64_t sal_proc;
|
|
||||||
uint64_t sal_gp;
|
|
||||||
uint8_t reserved2[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sal_memory_descriptor {
|
|
||||||
uint8_t entry_type;
|
|
||||||
uint8_t sal_needs_virt_mapping;
|
|
||||||
uint8_t mem_attr;
|
|
||||||
#define MEM_ATTR_WB 0
|
|
||||||
#define MEM_ATTR_UC 8
|
|
||||||
#define MEM_ATTR_UCE 9
|
|
||||||
#define MEM_ATTR_WC 10
|
|
||||||
uint8_t access_rights;
|
|
||||||
uint8_t mem_attr_support;
|
|
||||||
#define MEM_ATTR_SUPPORTS_WB 1
|
|
||||||
#define MEM_ATTR_SUPPORTS_UC 2
|
|
||||||
#define MEM_ATTR_SUPPORTS_UCE 4
|
|
||||||
#define MEM_ATTR_SUPPORTS_WC 8
|
|
||||||
uint8_t reserved;
|
|
||||||
uint8_t mem_type;
|
|
||||||
#define MEM_TYPE_RAM 0
|
|
||||||
#define MEM_TYPE_MIO 1
|
|
||||||
#define MEM_TYPE_SAPIC 2
|
|
||||||
#define MEM_TYPE_PIO 3
|
|
||||||
#define MEM_TYPE_FIRMWARE 4
|
|
||||||
#define MEM_TYPE_BAD_RAM 9
|
|
||||||
#define MEM_TYPE_BLACK_HOLE 10
|
|
||||||
uint8_t mem_usage;
|
|
||||||
#define MEM_USAGE_UNSPECIFIED 0
|
|
||||||
#define MEM_USAGE_PAL_CODE 1
|
|
||||||
#define MEM_USAGE_BOOT_SERVICES_CODE 2
|
|
||||||
#define MEM_USAGE_BOOT_SERVICES_DATA 3
|
|
||||||
#define MEM_USAGE_RUNTIME_SERVICES_CODE 4
|
|
||||||
#define MEM_USAGE_RUNTIME_SERVICES_DATA 5
|
|
||||||
#define MEM_USAGE_IA32_OPTION_ROM 6
|
|
||||||
#define MEM_USAGE_IA32_SYSTEM_ROM 7
|
|
||||||
#define MEM_USAGE_ACPI_RECLAIM_MEMORY 8
|
|
||||||
#define MEM_USAGE_ACPI_NVS_MEMORY 9
|
|
||||||
#define MEM_USAGE_SAL_PMI_CODE 10
|
|
||||||
#define MEM_USAGE_SAL_PMI_DATA 11
|
|
||||||
#define MEM_USAGE_FIRMWARE_RESERVED_RAM 12
|
|
||||||
|
|
||||||
#define MEM_USAGE_CPU_TO_IO 0
|
|
||||||
uint64_t phys_address;
|
|
||||||
uint32_t pages; /* In 4k pages */
|
|
||||||
uint32_t reserved2;
|
|
||||||
uint8_t oem_reserved[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sal_platform_features {
|
|
||||||
uint8_t entry_type;
|
|
||||||
uint8_t feature_list;
|
|
||||||
#define SAL_FEATURE_BUS_LOCK 1
|
|
||||||
#define SAL_FEATURE_PLATFORM_REDIRECTION_HINT 2
|
|
||||||
#define SAL_FEATURE_PROCESSOR_REDIRECTION_HINT 3
|
|
||||||
uint8_t reserved[14];
|
|
||||||
};
|
|
||||||
struct sal_translation_register {
|
|
||||||
uint8_t entry_type;
|
|
||||||
uint8_t tr_type;
|
|
||||||
#define SAL_ITR 0
|
|
||||||
#define SAL_DTR 1
|
|
||||||
uint8_t tr_number;
|
|
||||||
uint8_t reserved[5];
|
|
||||||
uint64_t virtual_address;
|
|
||||||
uint64_t page_size;
|
|
||||||
uint8_t reserved2[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sal_purge_translation_cache_coherency_domain {
|
|
||||||
uint8_t entry_type;
|
|
||||||
uint8_t reserved[3];
|
|
||||||
uint32_t coherence_domain_count;
|
|
||||||
uint64_t coherence_domain_addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sal_ap_wakeup_descriptor {
|
|
||||||
uint8_t entry_type;
|
|
||||||
uint8_t wakeup_mechanism;
|
|
||||||
uint8_t reserved[6];
|
|
||||||
uint64_t interrupt;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sal_entry {
|
|
||||||
union {
|
|
||||||
struct sal_entry_base base;
|
|
||||||
struct sal_entry_point_descriptor entry_point;
|
|
||||||
struct sal_memory_descriptor mem;
|
|
||||||
struct sal_platform_features features;
|
|
||||||
struct sal_translation_register tr;
|
|
||||||
struct sal_purge_translation_cache_coherency_domain purge;
|
|
||||||
struct sal_ap_wakeup_descriptor ap_wakeup;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sal_system_table {
|
|
||||||
uint8_t signature[4]; /* SST_ */
|
|
||||||
uint32_t table_length;
|
|
||||||
|
|
||||||
uint16_t sal_rev;
|
|
||||||
uint16_t entry_count;
|
|
||||||
uint8_t checksum;
|
|
||||||
uint8_t reserved1[7];
|
|
||||||
uint16_t sal_a_version;
|
|
||||||
uint16_t sal_b_version;
|
|
||||||
|
|
||||||
uint8_t oem_id[32];
|
|
||||||
uint8_t product_id[32];
|
|
||||||
uint8_t reserved2[8];
|
|
||||||
struct sal_entry entry[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sal_system_table *sal;
|
|
||||||
struct fptr sal_entry;
|
|
||||||
|
|
||||||
int parse_sal_system_table(void *table)
|
|
||||||
{
|
|
||||||
struct sal_system_table *salp = table;
|
|
||||||
uint8_t *ptr;
|
|
||||||
uint8_t checksum;
|
|
||||||
struct sal_entry *entry;
|
|
||||||
unsigned i;
|
|
||||||
if (memcmp(salp->signature, "SST_", 4) != 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ptr = table;
|
|
||||||
checksum = 0;
|
|
||||||
for(i = 0; i < salp->table_length; i++) {
|
|
||||||
checksum += ptr[i];
|
|
||||||
}
|
|
||||||
if (checksum != 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
printf("SALA: %hx SALB: %hx\n",
|
|
||||||
salp->sal_a_version,
|
|
||||||
salp->sal_b_version);
|
|
||||||
printf("SAL OEM: ");
|
|
||||||
for(i = 0; i < sizeof(salp->oem_id); i++) {
|
|
||||||
uint8_t ch = salp->oem_id[i];
|
|
||||||
if (ch == 0)
|
|
||||||
break;
|
|
||||||
printf("%c", ch);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("SAL PRODUCT: ");
|
|
||||||
for(i = 0; i < sizeof(salp->product_id); i++) {
|
|
||||||
uint8_t ch = salp->product_id[i];
|
|
||||||
if (ch == 0)
|
|
||||||
break;
|
|
||||||
printf("%c", ch);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
sal = salp;
|
|
||||||
pal_entry.entry = 0;
|
|
||||||
pal_entry.gp = 0;
|
|
||||||
sal_entry.entry = 0;
|
|
||||||
sal_entry.gp = 0;
|
|
||||||
entry = sal->entry;
|
|
||||||
i = 0;
|
|
||||||
while(i < salp->entry_count) {
|
|
||||||
unsigned long size = 0;
|
|
||||||
|
|
||||||
switch(entry->base.entry_type) {
|
|
||||||
case SAL_TYPE_ENTRYPOINT:
|
|
||||||
size = sizeof(entry->entry_point);
|
|
||||||
pal_entry.entry = entry->entry_point.pal_proc;
|
|
||||||
sal_entry.entry = entry->entry_point.sal_proc;
|
|
||||||
sal_entry.gp = entry->entry_point.sal_gp;
|
|
||||||
break;
|
|
||||||
case SAL_TYPE_MEMORY:
|
|
||||||
size = sizeof(entry->mem);
|
|
||||||
break;
|
|
||||||
case SAL_TYPE_PLATFORM_FEATURES:
|
|
||||||
size = sizeof(entry->features);
|
|
||||||
break;
|
|
||||||
case SAL_TYPE_TRANSLATION_REGISTER:
|
|
||||||
size = sizeof(entry->tr);
|
|
||||||
break;
|
|
||||||
case SAL_TYPE_PURGE_DOMAIN:
|
|
||||||
size = sizeof(entry->purge);
|
|
||||||
break;
|
|
||||||
case SAL_TYPE_AP_WAKEUP:
|
|
||||||
size = sizeof(entry->ap_wakeup);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
entry = (struct sal_entry *)(((char *)entry) + size);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SAL_SET_VECTORS 0x01000000
|
|
||||||
#define SAL_GET_STATE_INFO 0x01000001
|
|
||||||
#define SAL_GET_STATE_INFO_SIZE 0x01000002
|
|
||||||
#define SAL_CLEAR_STATE_INFO 0x01000003
|
|
||||||
#define SAL_MC_RENDEZ 0x01000004
|
|
||||||
#define SAL_MC_SET_PARAMS 0x01000005
|
|
||||||
#define SAL_REGISTER_PHYSICAL_ADDR 0x01000006
|
|
||||||
|
|
||||||
#define SAL_CACHE_FLUSH 0x01000008
|
|
||||||
#define SAL_CACHE_INIT 0x01000009
|
|
||||||
#define SAL_PCI_CONFIG_READ 0x01000010
|
|
||||||
#define SAL_PCI_CONFIG_WRITE 0x01000011
|
|
||||||
#define SAL_FREQ_BASE 0x01000012
|
|
||||||
|
|
||||||
#define SAL_UPDATE_PAL 0x01000020
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now define a couple of inline functions for improved type checking
|
|
||||||
* and convenience.
|
|
||||||
*/
|
|
||||||
long sal_freq_base (unsigned long which, unsigned long *ticks_per_second,
|
|
||||||
unsigned long *drift_info)
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
long status;
|
|
||||||
unsigned long ticks_per_second;
|
|
||||||
unsigned long drift_info;
|
|
||||||
} result, __call(void *,...);
|
|
||||||
|
|
||||||
result = __call(&sal_entry, SAL_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
*ticks_per_second = result.ticks_per_second;
|
|
||||||
*drift_info = result.drift_info;
|
|
||||||
return result.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Read from PCI configuration space */
|
|
||||||
long sal_pci_config_read (
|
|
||||||
unsigned long pci_config_addr, unsigned long size, unsigned long *value)
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
long status;
|
|
||||||
unsigned long value;
|
|
||||||
} result, __call(void *,...);
|
|
||||||
|
|
||||||
result = __call(&sal_entry, SAL_PCI_CONFIG_READ, pci_config_addr, size, 0, 0, 0, 0, 0);
|
|
||||||
if (value)
|
|
||||||
*value = result.value;
|
|
||||||
return result.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write to PCI configuration space */
|
|
||||||
long sal_pci_config_write (
|
|
||||||
unsigned long pci_config_addr, unsigned long size, unsigned long value)
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
long status;
|
|
||||||
} result, __call(void *,...);
|
|
||||||
|
|
||||||
result = __call(&sal_entry, SAL_PCI_CONFIG_WRITE, pci_config_addr, size, value, 0, 0, 0, 0);
|
|
||||||
return result.status;
|
|
||||||
}
|
|
|
@ -1,173 +0,0 @@
|
||||||
/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
|
||||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the GNU C Library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
||||||
02111-1307 USA.
|
|
||||||
|
|
||||||
The layout of the jmp_buf is as follows. This is subject to change
|
|
||||||
and user-code should never depend on the particular layout of
|
|
||||||
jmp_buf!
|
|
||||||
|
|
||||||
|
|
||||||
offset: description:
|
|
||||||
------- ------------
|
|
||||||
0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS)
|
|
||||||
0x008 r1 (gp)
|
|
||||||
0x010 caller's unat
|
|
||||||
0x018 fpsr
|
|
||||||
0x020 r4
|
|
||||||
0x028 r5
|
|
||||||
0x030 r6
|
|
||||||
0x038 r7
|
|
||||||
0x040 rp (b0)
|
|
||||||
0x048 b1
|
|
||||||
0x050 b2
|
|
||||||
0x058 b3
|
|
||||||
0x060 b4
|
|
||||||
0x068 b5
|
|
||||||
0x070 ar.pfs
|
|
||||||
0x078 ar.lc
|
|
||||||
0x080 pr
|
|
||||||
0x088 ar.bsp ; unchangeable (see __longjmp.S)
|
|
||||||
0x090 ar.unat
|
|
||||||
0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat)
|
|
||||||
0x0a0 f2
|
|
||||||
0x0b0 f3
|
|
||||||
0x0c0 f4
|
|
||||||
0x0d0 f5
|
|
||||||
0x0e0 f16
|
|
||||||
0x0f0 f17
|
|
||||||
0x100 f18
|
|
||||||
0x110 f19
|
|
||||||
0x120 f20
|
|
||||||
0x130 f21
|
|
||||||
0x130 f22
|
|
||||||
0x140 f23
|
|
||||||
0x150 f24
|
|
||||||
0x160 f25
|
|
||||||
0x170 f26
|
|
||||||
0x180 f27
|
|
||||||
0x190 f28
|
|
||||||
0x1a0 f29
|
|
||||||
0x1b0 f30
|
|
||||||
0x1c0 f31 */
|
|
||||||
|
|
||||||
|
|
||||||
/* The following two entry points are the traditional entry points: */
|
|
||||||
|
|
||||||
.text
|
|
||||||
.global setjmp
|
|
||||||
.proc setjmp
|
|
||||||
setjmp:
|
|
||||||
alloc r8=ar.pfs,2,0,0,0
|
|
||||||
mov in1=1
|
|
||||||
br.cond.sptk.many __sigsetjmp
|
|
||||||
.size setjmp, . - setjmp
|
|
||||||
.endp setjmp
|
|
||||||
|
|
||||||
/* __sigsetjmp(__jmp_buf buf, int savemask) */
|
|
||||||
|
|
||||||
__sigsetjmp:
|
|
||||||
#if 0
|
|
||||||
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
|
|
||||||
#endif
|
|
||||||
alloc loc1=ar.pfs,2,2,2,0
|
|
||||||
mov r16=ar.unat
|
|
||||||
;;
|
|
||||||
mov r17=ar.fpsr
|
|
||||||
mov r2=in0
|
|
||||||
add r3=8,in0
|
|
||||||
;;
|
|
||||||
st8.spill.nta [r2]=sp,16 // r12 (sp)
|
|
||||||
st8.spill.nta [r3]=gp,16 // r1 (gp)
|
|
||||||
;;
|
|
||||||
st8.nta [r2]=r16,16 // save caller's unat
|
|
||||||
st8.nta [r3]=r17,16 // save fpsr
|
|
||||||
add r8=0xa0,in0
|
|
||||||
;;
|
|
||||||
st8.spill.nta [r2]=r4,16 // r4
|
|
||||||
st8.spill.nta [r3]=r5,16 // r5
|
|
||||||
add r9=0xb0,in0
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f2,32
|
|
||||||
stf.spill.nta [r9]=f3,32
|
|
||||||
mov loc0=rp
|
|
||||||
.body
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f4,32
|
|
||||||
stf.spill.nta [r9]=f5,32
|
|
||||||
mov r17=b1
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f16,32
|
|
||||||
stf.spill.nta [r9]=f17,32
|
|
||||||
mov r18=b2
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f18,32
|
|
||||||
stf.spill.nta [r9]=f19,32
|
|
||||||
mov r19=b3
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f20,32
|
|
||||||
stf.spill.nta [r9]=f21,32
|
|
||||||
mov r20=b4
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f22,32
|
|
||||||
stf.spill.nta [r9]=f23,32
|
|
||||||
mov r21=b5
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f24,32
|
|
||||||
stf.spill.nta [r9]=f25,32
|
|
||||||
mov r22=ar.lc
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f26,32
|
|
||||||
stf.spill.nta [r9]=f27,32
|
|
||||||
mov r24=pr
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f28,32
|
|
||||||
stf.spill.nta [r9]=f29,32
|
|
||||||
;;
|
|
||||||
stf.spill.nta [r8]=f30
|
|
||||||
stf.spill.nta [r9]=f31
|
|
||||||
|
|
||||||
st8.spill.nta [r2]=r6,16 // r6
|
|
||||||
st8.spill.nta [r3]=r7,16 // r7
|
|
||||||
;;
|
|
||||||
mov r23=ar.bsp
|
|
||||||
mov r25=ar.unat
|
|
||||||
mov out0=in0
|
|
||||||
|
|
||||||
st8.nta [r2]=loc0,16 // b0
|
|
||||||
st8.nta [r3]=r17,16 // b1
|
|
||||||
mov out1=in1
|
|
||||||
;;
|
|
||||||
st8.nta [r2]=r18,16 // b2
|
|
||||||
st8.nta [r3]=r19,16 // b3
|
|
||||||
;;
|
|
||||||
st8.nta [r2]=r20,16 // b4
|
|
||||||
st8.nta [r3]=r21,16 // b5
|
|
||||||
;;
|
|
||||||
st8.nta [r2]=loc1,16 // ar.pfs
|
|
||||||
st8.nta [r3]=r22,16 // ar.lc
|
|
||||||
;;
|
|
||||||
st8.nta [r2]=r24,16 // pr
|
|
||||||
st8.nta [r3]=r23,16 // ar.bsp
|
|
||||||
;;
|
|
||||||
st8.nta [r2]=r25 // ar.unat
|
|
||||||
st8.nta [r3]=in0 // &__jmp_buf
|
|
||||||
mov r8=0
|
|
||||||
mov rp=loc0
|
|
||||||
mov ar.pfs=loc1
|
|
||||||
br.ret.sptk.many rp
|
|
||||||
|
|
||||||
.endp __sigsetjmp
|
|
|
@ -1,28 +0,0 @@
|
||||||
.text
|
|
||||||
.align 4
|
|
||||||
.proc _start
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
{
|
|
||||||
alloc loc0 = ar.pfs,1,2,1,0 /* in, local, out, rotating */
|
|
||||||
mov loc1 = rp
|
|
||||||
mov r14 = ip /* Get the address of _start */
|
|
||||||
}
|
|
||||||
movl r15 = @gprel(_start)
|
|
||||||
;;
|
|
||||||
sub gp = r14,r15
|
|
||||||
;;
|
|
||||||
rsm psr.i /* disable interrupts */
|
|
||||||
;;
|
|
||||||
add out0 = @gprel(_text),gp
|
|
||||||
br.call.sptk.few rp = _relocate
|
|
||||||
;;
|
|
||||||
cmp.eq p6,p7 = r0,r8 /* r8 == SUCCESS? */
|
|
||||||
mov ar.pfs = loc0
|
|
||||||
mov rp = loc1
|
|
||||||
;;
|
|
||||||
(p6) br.cond.sptk.few main
|
|
||||||
(p7) br.ret.sptk.few rp
|
|
||||||
|
|
||||||
.size _start, . - _start
|
|
||||||
.endp _start
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,36 +0,0 @@
|
||||||
#ifndef ETHERBOOT_BITS_BYTESWAP_H
|
|
||||||
#define ETHERBOOT_BITS_BYTESWAP_H
|
|
||||||
|
|
||||||
static inline uint64_t __ia64_bswap_64(uint64_t x)
|
|
||||||
{
|
|
||||||
uint64_t result;
|
|
||||||
__asm__ volatile(
|
|
||||||
"mux1 %0=%1,@rev" :
|
|
||||||
"=r" (result)
|
|
||||||
: "r" (x));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __bswap_constant_16(x) \
|
|
||||||
((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
|
|
||||||
(((uint16_t)(x) & 0xff00) >> 8)))
|
|
||||||
|
|
||||||
#define __bswap_constant_32(x) \
|
|
||||||
((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
|
|
||||||
(((uint32_t)(x) & 0x0000ff00U) << 8) | \
|
|
||||||
(((uint32_t)(x) & 0x00ff0000U) >> 8) | \
|
|
||||||
(((uint32_t)(x) & 0xff000000U) >> 24)))
|
|
||||||
|
|
||||||
#define __bswap_16(x) \
|
|
||||||
(__builtin_constant_p(x) ? \
|
|
||||||
__bswap_constant_16(x) : \
|
|
||||||
(__ia64_bswap_64(x) >> 48))
|
|
||||||
|
|
||||||
|
|
||||||
#define __bswap_32(x) \
|
|
||||||
(__builtin_constant_p(x) ? \
|
|
||||||
__bswap_constant_32(x) : \
|
|
||||||
(__ia64_bswap_64(x) >> 32))
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_BYTESWAP_H */
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef IA64_BITS_CPU_H
|
|
||||||
#define IA64_BITS_CPU_H
|
|
||||||
|
|
||||||
#define cpu_setup() do {} while(0)
|
|
||||||
|
|
||||||
#endif /* IA64_BITS_CPU_H */
|
|
|
@ -1,11 +0,0 @@
|
||||||
#ifndef IA64_BITS_ELF_H
|
|
||||||
#define IA64_BITS_ELF_H
|
|
||||||
|
|
||||||
/* ELF Defines for the current architecture */
|
|
||||||
#define EM_CURRENT EM_IA_64
|
|
||||||
#define ELFDATA_CURRENT ELFDATA2LSB
|
|
||||||
|
|
||||||
#define ELF_CHECK_ARCH(x) \
|
|
||||||
((x).e_machine == EM_CURRENT)
|
|
||||||
|
|
||||||
#endif /* IA64_BITS_ELF_H */
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef ETHERBOOT_BITS_ENDIAN_H
|
|
||||||
#define ETHERBOOT_BITS_ENDIAN_H
|
|
||||||
|
|
||||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_ENDIAN_H */
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef ETHERBOOT_BITS_STRING_H
|
|
||||||
#define ETHERBOOT_BITS_STRING_H
|
|
||||||
|
|
||||||
/* define inline optimized string functions here */
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_BITS_STRING_H */
|
|
|
@ -1,12 +0,0 @@
|
||||||
#ifndef ETHERBOOT_IA64_HOOKS_H
|
|
||||||
#define ETHERBOOT_IA64_HOOKS_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
void arch_main(in_call_data_t *data, va_list params);
|
|
||||||
void arch_on_exit(int status);
|
|
||||||
void arch_relocate_to(unsigned long addr);
|
|
||||||
#define arch_relocated_from(old_addr) do {} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_IA64_HOOKS_H */
|
|
|
@ -1,228 +0,0 @@
|
||||||
#ifndef ETHERBOOT_IO_H
|
|
||||||
#define ETHERBOOT_IO_H
|
|
||||||
|
|
||||||
/* Don't require identity mapped physical memory,
|
|
||||||
* osloader.c is the only valid user at the moment.
|
|
||||||
*/
|
|
||||||
static inline unsigned long virt_to_phys(volatile const void *virt_addr)
|
|
||||||
{
|
|
||||||
return ((unsigned long)virt_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *phys_to_virt(unsigned long phys_addr)
|
|
||||||
{
|
|
||||||
return (void *)(phys_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virt_to_bus converts an addresss inside of etherboot [_start, _end]
|
|
||||||
* into a memory address cards can use.
|
|
||||||
*/
|
|
||||||
#define virt_to_bus virt_to_phys
|
|
||||||
|
|
||||||
|
|
||||||
/* bus_to_virt reverses virt_to_bus, the address must be output
|
|
||||||
* from virt_to_bus to be valid. This function does not work on
|
|
||||||
* all bus addresses.
|
|
||||||
*/
|
|
||||||
#define bus_to_virt phys_to_virt
|
|
||||||
|
|
||||||
/* ioremap converts a random 32bit bus address into something
|
|
||||||
* etherboot can access.
|
|
||||||
*/
|
|
||||||
static inline void *ioremap(unsigned long bus_addr, unsigned long length __unused)
|
|
||||||
{
|
|
||||||
return bus_to_virt(bus_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* iounmap cleans up anything ioremap had to setup */
|
|
||||||
static inline void iounmap(void *virt_addr __unused)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In physical mode the offset of uncached pages */
|
|
||||||
#define PHYS_BASE (0x8000000000000000UL)
|
|
||||||
|
|
||||||
/* Memory mapped IO primitives, we avoid the cache... */
|
|
||||||
static inline uint8_t readb(unsigned long addr)
|
|
||||||
{
|
|
||||||
return *((volatile uint8_t *)(PHYS_BASE | addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t readw(unsigned long addr)
|
|
||||||
{
|
|
||||||
return *((volatile uint16_t *)(PHYS_BASE | addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t readl(unsigned long addr)
|
|
||||||
{
|
|
||||||
return *((volatile uint32_t *)(PHYS_BASE | addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t readq(unsigned long addr)
|
|
||||||
{
|
|
||||||
return *((volatile uint64_t *)(PHYS_BASE | addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void writeb(uint8_t val, unsigned long addr)
|
|
||||||
{
|
|
||||||
*((volatile uint8_t *)(PHYS_BASE | addr)) = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void writew(uint16_t val, unsigned long addr)
|
|
||||||
{
|
|
||||||
*((volatile uint16_t *)(PHYS_BASE | addr)) = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void writel(uint32_t val, unsigned long addr)
|
|
||||||
{
|
|
||||||
*((volatile uint32_t *)(PHYS_BASE | addr)) = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void writeq(uint64_t val, unsigned long addr)
|
|
||||||
{
|
|
||||||
*((volatile uint64_t *)(PHYS_BASE | addr)) = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void memcpy_fromio(void *dest, unsigned long src, size_t n)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
uint8_t *dp = dest;
|
|
||||||
for(i = 0; i < n; i++) {
|
|
||||||
*dp = readb(src);
|
|
||||||
dp++;
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void memcpy_toio(unsigned long dest , const void *src, size_t n)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
const uint8_t *sp = src;
|
|
||||||
for(i = 0; i < n; i++) {
|
|
||||||
writeb(*sp, dest);
|
|
||||||
sp++;
|
|
||||||
dest++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IO space IO primitives, Itanium has a strange architectural mapping... */
|
|
||||||
extern unsigned long io_base;
|
|
||||||
#define __ia64_mf_a() __asm__ __volatile__ ("mf.a" ::: "memory")
|
|
||||||
#define __ia64_io_addr(port) ((void *)(PHYS_BASE | io_base | (((port) >> 2) << 12) | ((port) & 0xfff)))
|
|
||||||
|
|
||||||
static inline uint8_t inb(unsigned long port)
|
|
||||||
{
|
|
||||||
uint8_t result;
|
|
||||||
|
|
||||||
result = *((volatile uint8_t *)__ia64_io_addr(port));
|
|
||||||
__ia64_mf_a();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t inw(unsigned long port)
|
|
||||||
{
|
|
||||||
uint8_t result;
|
|
||||||
result = *((volatile uint16_t *)__ia64_io_addr(port));
|
|
||||||
__ia64_mf_a();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t inl(unsigned long port)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
result = *((volatile uint32_t *)__ia64_io_addr(port));
|
|
||||||
__ia64_mf_a();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void outb(uint8_t val, unsigned long port)
|
|
||||||
{
|
|
||||||
*((volatile uint8_t *)__ia64_io_addr(port)) = val;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void outw(uint16_t val, unsigned long port)
|
|
||||||
{
|
|
||||||
*((volatile uint16_t *)__ia64_io_addr(port)) = val;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void outl(uint32_t val, unsigned long port)
|
|
||||||
{
|
|
||||||
*((volatile uint32_t *)__ia64_io_addr(port)) = val;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline void insb(unsigned long port, void *dst, unsigned long count)
|
|
||||||
{
|
|
||||||
volatile uint8_t *addr = __ia64_io_addr(port);
|
|
||||||
uint8_t *dp = dst;
|
|
||||||
__ia64_mf_a();
|
|
||||||
while(count--)
|
|
||||||
*dp++ = *addr;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void insw(unsigned long port, void *dst, unsigned long count)
|
|
||||||
{
|
|
||||||
volatile uint16_t *addr = __ia64_io_addr(port);
|
|
||||||
uint16_t *dp = dst;
|
|
||||||
__ia64_mf_a();
|
|
||||||
while(count--)
|
|
||||||
*dp++ = *addr;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void insl(unsigned long port, void *dst, unsigned long count)
|
|
||||||
{
|
|
||||||
volatile uint32_t *addr = __ia64_io_addr(port);
|
|
||||||
uint32_t *dp = dst;
|
|
||||||
__ia64_mf_a();
|
|
||||||
while(count--)
|
|
||||||
*dp++ = *addr;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void outsb(unsigned long port, void *src, unsigned long count)
|
|
||||||
{
|
|
||||||
const uint8_t *sp = src;
|
|
||||||
volatile uint8_t *addr = __ia64_io_addr(port);
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
*addr = *sp++;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void outsw(unsigned long port, void *src, unsigned long count)
|
|
||||||
{
|
|
||||||
const uint16_t *sp = src;
|
|
||||||
volatile uint16_t *addr = __ia64_io_addr(port);
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
*addr = *sp++;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void outsl(unsigned long port, void *src, unsigned long count)
|
|
||||||
{
|
|
||||||
const uint32_t *sp = src;
|
|
||||||
volatile uint32_t *addr = __ia64_io_addr(port);
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
*addr = *sp++;
|
|
||||||
__ia64_mf_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long ia64_get_kr0(void)
|
|
||||||
{
|
|
||||||
unsigned long r;
|
|
||||||
asm volatile ("mov %0=ar.k0" : "=r"(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_IO_H */
|
|
|
@ -1,11 +0,0 @@
|
||||||
#ifndef LATCH_H
|
|
||||||
#define LATCH_H
|
|
||||||
|
|
||||||
#define TICKS_PER_SEC (1000UL)
|
|
||||||
|
|
||||||
/* Fixed timer interval used for calibrating a more precise timer */
|
|
||||||
#define LATCHES_PER_SEC 10
|
|
||||||
|
|
||||||
void sleep_latch(void);
|
|
||||||
|
|
||||||
#endif /* LATCH_H */
|
|
|
@ -1,57 +0,0 @@
|
||||||
#ifndef LIMITS_H
|
|
||||||
#define LIMITS_H 1
|
|
||||||
|
|
||||||
/* Number of bits in a `char' */
|
|
||||||
#define CHAR_BIT 8
|
|
||||||
|
|
||||||
/* Minimum and maximum values a `signed char' can hold */
|
|
||||||
#define SCHAR_MIN (-128)
|
|
||||||
#define SCHAR_MAX 127
|
|
||||||
|
|
||||||
/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
|
|
||||||
#define UCHAR_MAX 255
|
|
||||||
|
|
||||||
/* Minimum and maximum values a `char' can hold */
|
|
||||||
#define CHAR_MIN SCHAR_MIN
|
|
||||||
#define CHAR_MAX SCHAR_MAX
|
|
||||||
|
|
||||||
/* Minimum and maximum values a `signed short int' can hold */
|
|
||||||
#define SHRT_MIN (-32768)
|
|
||||||
#define SHRT_MAX 32767
|
|
||||||
|
|
||||||
/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */
|
|
||||||
#define USHRT_MAX 65535
|
|
||||||
|
|
||||||
|
|
||||||
/* Minimum and maximum values a `signed int' can hold */
|
|
||||||
#define INT_MIN (-INT_MAX - 1)
|
|
||||||
#define INT_MAX 2147483647
|
|
||||||
|
|
||||||
/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
|
|
||||||
#define UINT_MAX 4294967295U
|
|
||||||
|
|
||||||
|
|
||||||
/* Minimum and maximum values a `signed int' can hold */
|
|
||||||
#define INT_MIN (-INT_MAX - 1)
|
|
||||||
#define INT_MAX 2147483647
|
|
||||||
|
|
||||||
/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
|
|
||||||
#define UINT_MAX 4294967295U
|
|
||||||
|
|
||||||
/* Minimum and maximum values a `signed long' can hold */
|
|
||||||
#define LONG_MAX 9223372036854775807L
|
|
||||||
#define LONG_MIN (-LONG_MAX - 1L)
|
|
||||||
|
|
||||||
/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
|
|
||||||
#define ULONG_MAX 18446744073709551615UL
|
|
||||||
|
|
||||||
/* Minimum and maximum values a `signed long long' can hold */
|
|
||||||
#define LLONG_MAX 9223372036854775807LL
|
|
||||||
#define LLONG_MIN (-LONG_MAX - 1LL)
|
|
||||||
|
|
||||||
|
|
||||||
/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */
|
|
||||||
#define ULLONG_MAX 18446744073709551615ULL
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIMITS_H */
|
|
|
@ -1,11 +0,0 @@
|
||||||
#ifndef IA64_PAL_H
|
|
||||||
#define IA64_PAL_H
|
|
||||||
|
|
||||||
struct pal_freq_ratio {
|
|
||||||
unsigned long den : 32, num : 32; /* numerator & denominator */
|
|
||||||
};
|
|
||||||
extern long pal_freq_ratios(struct pal_freq_ratio *proc_ratio,
|
|
||||||
struct pal_freq_ratio *bus_ratio, struct pal_freq_ratio *itc_ratio);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* IA64_PAL_H */
|
|
|
@ -1,29 +0,0 @@
|
||||||
#ifndef IA64_SAL_H
|
|
||||||
#define IA64_SAL_H
|
|
||||||
|
|
||||||
struct fptr {
|
|
||||||
unsigned long entry;
|
|
||||||
unsigned long gp;
|
|
||||||
};
|
|
||||||
extern struct fptr sal_entry;
|
|
||||||
extern struct fptr pal_entry;
|
|
||||||
extern int parse_sal_system_table(void *table);
|
|
||||||
|
|
||||||
#define SAL_FREQ_BASE_PLATFORM 0
|
|
||||||
#define SAL_FREQ_BASE_INTERVAL_TIMER 1
|
|
||||||
#define SAL_FREQ_BASE_REALTIME_CLOCK 2
|
|
||||||
|
|
||||||
long sal_freq_base (unsigned long which, unsigned long *ticks_per_second,
|
|
||||||
unsigned long *drift_info);
|
|
||||||
|
|
||||||
#define PCI_SAL_ADDRESS(seg, bus, dev, fn, reg) \
|
|
||||||
((unsigned long)(seg << 24) | (unsigned long)(bus << 16) | \
|
|
||||||
(unsigned long)(dev << 11) | (unsigned long)(fn << 8) | \
|
|
||||||
(unsigned long)(reg))
|
|
||||||
|
|
||||||
long sal_pci_config_read (
|
|
||||||
unsigned long pci_config_addr, unsigned long size, unsigned long *value);
|
|
||||||
long sal_pci_config_write (
|
|
||||||
unsigned long pci_config_addr, unsigned long size, unsigned long value);
|
|
||||||
|
|
||||||
#endif /* IA64_SAL_H */
|
|
|
@ -1,13 +0,0 @@
|
||||||
#ifndef ETHERBOOT_SETJMP_H
|
|
||||||
#define ETHERBOOT_SETJMP_H
|
|
||||||
|
|
||||||
|
|
||||||
/* Define a type for use by setjmp and longjmp */
|
|
||||||
#define JBLEN 70
|
|
||||||
|
|
||||||
typedef long jmp_buf[JBLEN] __attribute__ ((aligned (16))); /* guarantees 128-bit alignment! */
|
|
||||||
|
|
||||||
extern int setjmp (jmp_buf env);
|
|
||||||
extern void longjmp (jmp_buf env, int val);
|
|
||||||
|
|
||||||
#endif /* ETHERBOOT_SETJMP_H */
|
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef STDINT_H
|
|
||||||
#define STDINT_H
|
|
||||||
|
|
||||||
typedef unsigned long size_t;
|
|
||||||
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
typedef unsigned long uint64_t;
|
|
||||||
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef signed short int16_t;
|
|
||||||
typedef signed int int32_t;
|
|
||||||
typedef signed long int64_t;
|
|
||||||
|
|
||||||
typedef signed char s8;
|
|
||||||
typedef unsigned char u8;
|
|
||||||
|
|
||||||
typedef signed short s16;
|
|
||||||
typedef unsigned short u16;
|
|
||||||
|
|
||||||
typedef signed int s32;
|
|
||||||
typedef unsigned int u32;
|
|
||||||
|
|
||||||
typedef signed long s64;
|
|
||||||
typedef unsigned long u64;
|
|
||||||
|
|
||||||
#endif /* STDINT_H */
|
|
|
@ -1,63 +0,0 @@
|
||||||
#!/usr/bin/perl -w
|
|
||||||
#
|
|
||||||
# Program to apply an efi header to an ia64 etherboot file.
|
|
||||||
#
|
|
||||||
# GPL Eric Biederman 2002
|
|
||||||
#
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
use bytes;
|
|
||||||
|
|
||||||
main(@ARGV);
|
|
||||||
|
|
||||||
sub usage
|
|
||||||
{
|
|
||||||
my ($err) = @_;
|
|
||||||
print STDERR $err , "\n";
|
|
||||||
die "Usage $0 prrefix file bss_size\n";
|
|
||||||
}
|
|
||||||
sub main
|
|
||||||
{
|
|
||||||
my ($prefix_name, $suffix_name, $bss_size) = @_;
|
|
||||||
usage("No prefix") unless (defined($prefix_name));
|
|
||||||
usage("No suffix") unless (defined($suffix_name));
|
|
||||||
usage("No bss size") unless (defined($bss_size));
|
|
||||||
|
|
||||||
open(PREFIX, "<$prefix_name") or die "Cannot open $prefix_name";
|
|
||||||
open(SUFFIX, "<$suffix_name") or die "Cannot open $suffix_name";
|
|
||||||
|
|
||||||
$/ = undef;
|
|
||||||
my $prefix = <PREFIX>; close(PREFIX);
|
|
||||||
my $suffix = <SUFFIX>; close(SUFFIX);
|
|
||||||
|
|
||||||
# Payload sizes.
|
|
||||||
my $payload_size = length($suffix);
|
|
||||||
my $payload_bss = $bss_size;
|
|
||||||
|
|
||||||
# Update the image size
|
|
||||||
my $hdr_off = unpack("V",substr($prefix, 0x3c, 4));
|
|
||||||
my $image_size_off = 0x050 + $hdr_off;
|
|
||||||
my $img_mem_size_off = 0x0c0 + $hdr_off;
|
|
||||||
my $img_size_off = 0x0c8 + $hdr_off;
|
|
||||||
|
|
||||||
my $image_size = unpack("V", substr($prefix, $image_size_off, 4));
|
|
||||||
my $img_mem_size = unpack("V", substr($prefix, $img_mem_size_off, 4));
|
|
||||||
my $img_size = unpack("V", substr($prefix, $img_size_off, 4));
|
|
||||||
|
|
||||||
$image_size += $payload_size + $payload_bss;
|
|
||||||
$img_mem_size += $payload_size + $payload_bss;
|
|
||||||
$img_size += $payload_size;
|
|
||||||
|
|
||||||
substr($prefix, $image_size_off, 4) = pack("V", $image_size);
|
|
||||||
substr($prefix, $img_mem_size_off, 4) = pack("V", $img_mem_size);
|
|
||||||
substr($prefix, $img_size_off, 4) = pack("V", $img_size);
|
|
||||||
|
|
||||||
#print(STDERR "image_size: $image_size\n");
|
|
||||||
#print(STDERR "img_mem_size: $img_mem_size\n");
|
|
||||||
#print(STDERR "img_size: $img_size\n");
|
|
||||||
|
|
||||||
print $prefix;
|
|
||||||
print $suffix;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,198 +0,0 @@
|
||||||
#!/usr/bin/perl -w
|
|
||||||
#
|
|
||||||
# Program to apply an unnrv2b decompressor header to an ia64 etherboot file.
|
|
||||||
#
|
|
||||||
# GPL Eric Biederman 2002
|
|
||||||
#
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
use bytes;
|
|
||||||
|
|
||||||
main(@ARGV);
|
|
||||||
|
|
||||||
sub usage
|
|
||||||
{
|
|
||||||
my ($err) = @_;
|
|
||||||
print STDERR $err , "\n";
|
|
||||||
die "Usage $0 prefix file\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
sub getbits
|
|
||||||
{
|
|
||||||
my ($bundle, $start, $size) = @_;
|
|
||||||
|
|
||||||
# Compute the mask
|
|
||||||
my $mask = 0xffffffff;
|
|
||||||
$mask = $mask >> (32 - $size);
|
|
||||||
|
|
||||||
# Compute the substring, and shift
|
|
||||||
my ($first, $end, $count, $shift);
|
|
||||||
$first = int($start / 8);
|
|
||||||
$end = int(($start + $size + 7)/8);
|
|
||||||
$count = $end - $first;
|
|
||||||
$shift = $start % 8;
|
|
||||||
|
|
||||||
# Compute the unpack type
|
|
||||||
my $type;
|
|
||||||
if ($count == 1) {
|
|
||||||
$type = "C"
|
|
||||||
}
|
|
||||||
elsif ($count == 2) {
|
|
||||||
$type = "v";
|
|
||||||
}
|
|
||||||
elsif (($count >= 3) && ($count <= 4)) {
|
|
||||||
$type = "V";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
die "bad count $count";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Now compute the value
|
|
||||||
my $val = (unpack($type, substr($bundle, $first, $count)) >> $shift) & $mask;
|
|
||||||
|
|
||||||
# Now return the value
|
|
||||||
return $val;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub putbits
|
|
||||||
{
|
|
||||||
my ($bundle, $start, $size, $val) = @_;
|
|
||||||
|
|
||||||
|
|
||||||
# Compute the mask
|
|
||||||
my $mask = 0xffffffff;
|
|
||||||
$mask >>= 32 - $size;
|
|
||||||
|
|
||||||
# Compute the substring, and shift
|
|
||||||
my ($first, $end, $count, $shift);
|
|
||||||
$first = int($start / 8);
|
|
||||||
$end = int(($start + $size + 7)/8);
|
|
||||||
$count = $end - $first;
|
|
||||||
$shift = $start % 8;
|
|
||||||
|
|
||||||
# Compute the unpack type
|
|
||||||
my $type;
|
|
||||||
if ($count == 1) {
|
|
||||||
$type = "C"
|
|
||||||
}
|
|
||||||
elsif ($count == 2) {
|
|
||||||
$type = "v";
|
|
||||||
}
|
|
||||||
elsif (($count >= 3) && ($count <= 4)) {
|
|
||||||
$type = "V";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
die "bad count $count";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Adjust the mask
|
|
||||||
$mask <<= $shift;
|
|
||||||
|
|
||||||
# Now set the value, preserving the untouched bits
|
|
||||||
substr($bundle, $first, $count) =
|
|
||||||
pack($type,
|
|
||||||
((unpack($type, substr($bundle, $first, $count)) & ~$mask) |
|
|
||||||
(($val << $shift) & $mask)));
|
|
||||||
|
|
||||||
# Now return the new value;
|
|
||||||
return $bundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub main
|
|
||||||
{
|
|
||||||
my ($prefix_name, $suffix_name) = @_;
|
|
||||||
usage("No prefix") unless (defined($prefix_name));
|
|
||||||
usage("No suffix") unless (defined($suffix_name));
|
|
||||||
|
|
||||||
open(PREFIX, "<$prefix_name") or die "Cannot open $prefix_name";
|
|
||||||
open(SUFFIX, "<$suffix_name") or die "Cannot open $suffix_name";
|
|
||||||
|
|
||||||
$/ = undef;
|
|
||||||
my $prefix = <PREFIX>; close(PREFIX);
|
|
||||||
my $suffix = <SUFFIX>; close(SUFFIX);
|
|
||||||
|
|
||||||
# Payload sizes
|
|
||||||
my $prefix_len = length($prefix);
|
|
||||||
my $suffix_len = length($suffix);
|
|
||||||
my $payload_size = $suffix_len;
|
|
||||||
my $uncompressed_offset = ($prefix_len + $suffix_len + 15) & ~15;
|
|
||||||
my $pad = $uncompressed_offset - ($prefix_len + $suffix_len);
|
|
||||||
|
|
||||||
# Itaninum instruction bundle we will be updating
|
|
||||||
# 0 - 4 template == 5
|
|
||||||
# 5 - 45 slot 0 M-Unit
|
|
||||||
# 46 - 86 slot 1 L-Unit
|
|
||||||
# 87 - 127 slot 2 X-Unit
|
|
||||||
# Itaninum instruction format
|
|
||||||
# 40 - 37 Major opcode
|
|
||||||
# ...
|
|
||||||
#
|
|
||||||
|
|
||||||
# slot 1
|
|
||||||
# 0 - 40 [41] imm-41
|
|
||||||
# 10 - 40 [31] imm-41-hi
|
|
||||||
# 0 - 9 [10] imm-41-lo
|
|
||||||
|
|
||||||
# slot 2
|
|
||||||
# 0 - 5 [6] qp
|
|
||||||
# 6 - 12 [7] r1
|
|
||||||
# 13 - 19 [7] imm-7b
|
|
||||||
# 20 [1] vc
|
|
||||||
# 21 [1] immc
|
|
||||||
# 22 - 26 [5] imm-5c
|
|
||||||
# 27 - 35 [9] imm-9d
|
|
||||||
# 36 [1] imm0
|
|
||||||
# 37 - 40 [4] major opcode
|
|
||||||
#
|
|
||||||
|
|
||||||
# major opcode should be 6
|
|
||||||
|
|
||||||
# Update the image size
|
|
||||||
my $uncompressed_offset_bundle_off = 16;
|
|
||||||
my $bundle = substr($prefix, $uncompressed_offset_bundle_off, 16);
|
|
||||||
|
|
||||||
my $template = getbits($bundle, 0, 5);
|
|
||||||
my $op1_base = 46;
|
|
||||||
my $op2_base = 87;
|
|
||||||
my $major_opcode = getbits($bundle, 37 + $op2_base, 4);
|
|
||||||
|
|
||||||
if (($template != 5) ||
|
|
||||||
($major_opcode != 6)) {
|
|
||||||
die "unknown second bundle cannot patch";
|
|
||||||
}
|
|
||||||
|
|
||||||
die "uncompressed_offset to big!\n" if ($uncompressed_offset > 0xffffffff);
|
|
||||||
my $immhi = 0;
|
|
||||||
my $immlo = $uncompressed_offset;
|
|
||||||
|
|
||||||
my $imm0 = ($immhi >> 31) & ((1 << 1) - 1);
|
|
||||||
my $imm41_hi = ($immhi >> 0) & ((1 << 31) - 1);
|
|
||||||
|
|
||||||
my $imm41_lo = ($immlo >> 22) & ((1 << 10) - 1);
|
|
||||||
my $immc = ($immlo >> 21) & ((1 << 1) - 1);
|
|
||||||
my $imm5c = ($immlo >> 16) & ((1 << 5) - 1);
|
|
||||||
my $imm9d = ($immlo >> 7) & ((1 << 9) - 1);
|
|
||||||
my $imm7b = ($immlo >> 0) & ((1 << 7) - 1);
|
|
||||||
|
|
||||||
$bundle = putbits($bundle, 10 + $op1_base, 31, $imm41_hi);
|
|
||||||
$bundle = putbits($bundle, 0 + $op1_base, 10, $imm41_lo);
|
|
||||||
$bundle = putbits($bundle, 36 + $op2_base, 1 , $imm0);
|
|
||||||
$bundle = putbits($bundle, 27 + $op2_base, 9 , $imm9d);
|
|
||||||
$bundle = putbits($bundle, 22 + $op2_base, 5 , $imm5c);
|
|
||||||
$bundle = putbits($bundle, 21 + $op2_base, 1 , $immc);
|
|
||||||
$bundle = putbits($bundle, 13 + $op2_base, 7 , $imm7b);
|
|
||||||
|
|
||||||
substr($prefix, $uncompressed_offset_bundle_off, 16) = $bundle;
|
|
||||||
|
|
||||||
#print (STDERR "prefix: $prefix_len\n");
|
|
||||||
#print (STDERR "suffix: $suffix_len\n");
|
|
||||||
#print (STDERR "pad: $pad\n");
|
|
||||||
#print (STDERR "uncompressed_offset: $uncompressed_offset\n");
|
|
||||||
|
|
||||||
print $prefix;
|
|
||||||
print $suffix;
|
|
||||||
# Pad the resulting image by a few extra bytes...
|
|
||||||
print pack("C", 0) x $pad;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,195 +0,0 @@
|
||||||
#include "elf.h"
|
|
||||||
.explicit
|
|
||||||
|
|
||||||
.section ".hdrs", "a"
|
|
||||||
/* First the DOS file header */
|
|
||||||
|
|
||||||
|
|
||||||
dos_header:
|
|
||||||
.byte 'M', 'Z' /* Signature */
|
|
||||||
.short dos_program_end - dos_program /* Length of image mod 512 bytes*/
|
|
||||||
.short 0x0001 /* Length of image in 512 byte pages */ /* FIXME */
|
|
||||||
.short 0x0000 /* Number of relocation items following header */
|
|
||||||
.short (dos_header_end - dos_header)/16 /* Size of header in 16 byte paragraphs */
|
|
||||||
.short 0x0001 /* Minimum number of paragraphs needed to run image */
|
|
||||||
.short 0x0001 /* Maximum number of paragraphs program would like */
|
|
||||||
.short 0x0000 /* Initial SS */
|
|
||||||
|
|
||||||
.short 0x00b8 /* Initial SP */
|
|
||||||
.short 0x0000 /* Negative checksum of image */
|
|
||||||
.short 0x0000 /* Initial IP */
|
|
||||||
.short 0x0000 /* Initial CS */
|
|
||||||
.short 0x0010 /* Offset in EXEC of first relocation item */
|
|
||||||
.short 0x0000 /* Overlay number */
|
|
||||||
|
|
||||||
.balign 16
|
|
||||||
dos_header_end:
|
|
||||||
dos_program:
|
|
||||||
.byte 0xdb /* retf */
|
|
||||||
.balign 16
|
|
||||||
dos_program_end:
|
|
||||||
.org 0x3c
|
|
||||||
.byte pe_signature - dos_header, 0x00, 0x00, 0x00
|
|
||||||
.org 0x40 /* NOTE: set this to 0x80 for debugging, 0x40 otherwise */
|
|
||||||
pe_signature:
|
|
||||||
.byte 'P', 'E', 0, 0
|
|
||||||
coff_header:
|
|
||||||
#define IMAGE_MACHINE_IA64 0x0200
|
|
||||||
coff_machine: .short IMAGE_MACHINE_IA64
|
|
||||||
coff_nsections: .short (section_headers_end - section_headers)/40
|
|
||||||
coff_timdat: .int 1038168747 /* Sun Nov 24 12:12:27 2002 */
|
|
||||||
coff_symptr: .int 0x00000000
|
|
||||||
|
|
||||||
coff_nsyms: .int 0x00000000
|
|
||||||
coff_opthdr: .short pe_end - pe_header
|
|
||||||
#define CF_RELOC_STRIPPED 0x0001
|
|
||||||
#define CF_EXECUTABLE 0x0002
|
|
||||||
#define CF_LINE_STRIPPED 0x0004
|
|
||||||
#define CF_LOCAL_STRIPPED 0x0008
|
|
||||||
#define CF_DEBUG_STRIPPED 0x0206
|
|
||||||
coff_flags: .short CF_EXECUTABLE | CF_LINE_STRIPPED | CF_LOCAL_STRIPPED | CF_DEBUG_STRIPPED
|
|
||||||
|
|
||||||
/* Option header */
|
|
||||||
pe_header:
|
|
||||||
pe_magic: .short 0x020b /* 020b or 010b? */
|
|
||||||
pe_linker: .byte 0x02, 0x38
|
|
||||||
pe_text_size: .int _text_size
|
|
||||||
pe_data_size: .int _data_size
|
|
||||||
pe_bss_size: .int _bss_size
|
|
||||||
pe_entry: .int _start_plabel_rva
|
|
||||||
pe_text_base: .int _text_rva
|
|
||||||
pe_image_base: .quad _image_base
|
|
||||||
pe_sec_align: .int _sect_align
|
|
||||||
pe_file_align: .int _file_align
|
|
||||||
pe_os_major: .short 0
|
|
||||||
pe_os_minor: .short 0
|
|
||||||
pe_image_major: .short 0
|
|
||||||
pe_image_minro: .short 0
|
|
||||||
pe_sub_major: .short 0
|
|
||||||
pe_sub_minor: .short 0
|
|
||||||
pe_reserved: .int 0
|
|
||||||
pe_image_size: .int _image_size
|
|
||||||
pe_hdrs_size: .int _hdrs_size
|
|
||||||
pe_checksum: .int 0 /* FIXME how do I compute the checksum, unnecessary */
|
|
||||||
#define SUBSYS_EFI_APP 10
|
|
||||||
#define SUBSYS_EFI_BOOT_SERVICE_DRIVER 11
|
|
||||||
#define SUBSYS_EFI_RUNTIME_DRIVER 12
|
|
||||||
pe_subsys: .short SUBSYS_EFI_APP
|
|
||||||
pe_dll_flags: .short 0
|
|
||||||
pe_stack_res: .quad 0
|
|
||||||
pe_stack_commit:.quad 0
|
|
||||||
pe_heap_res: .quad 0
|
|
||||||
pe_heap_commit: .quad 0
|
|
||||||
pe_ld_flags: .int 0
|
|
||||||
pe_rvas: .int (rvas_end - rvas_start)/8
|
|
||||||
|
|
||||||
rvas_start:
|
|
||||||
rva_0_rva: .int 0
|
|
||||||
rva_0_size: .int 0
|
|
||||||
rva_1_rva: .int 0
|
|
||||||
rva_1_size: .int 0
|
|
||||||
rva_2_rva: .int 0
|
|
||||||
rva_2_size: .int 0
|
|
||||||
rva_3_rva: .int 0
|
|
||||||
rva_3_size: .int 0
|
|
||||||
rva_4_rva: .int 0
|
|
||||||
rva_4_size: .int 0
|
|
||||||
rva_5_rva: .int _reloc_rva
|
|
||||||
rva_5_size: .int __reloc_size
|
|
||||||
rvas_end:
|
|
||||||
pe_end:
|
|
||||||
|
|
||||||
section_headers:
|
|
||||||
#define SCN_CNT_CODE 0x00000020
|
|
||||||
#define SCN_CNT_INITIALIZED_DATA 0x00000040
|
|
||||||
#define SCN_CNT_UNINITIALIZED_DATA 0x00000080
|
|
||||||
#define SCN_MEM_DISCARDABLE 0x02000000
|
|
||||||
#define SCN_MEM_SHARED 0x10000000
|
|
||||||
#define SCN_MEM_EXECUTE 0x20000000
|
|
||||||
#define SCN_MEM_READ 0x40000000
|
|
||||||
#define SCN_MEM_WRITE 0x80000000
|
|
||||||
|
|
||||||
sec1_name: .byte '.', 'i', 'm', 'g', 0 , 0, 0, 0
|
|
||||||
sec1_virt_size: .int _img_mem_size
|
|
||||||
sec1_virt_addr: .int _img_rva
|
|
||||||
sec1_file_size: .int _img_size
|
|
||||||
sec1_file_off: .int _img_off
|
|
||||||
sec1_reloc_off: .int 0
|
|
||||||
sec1_line_off: .int 0
|
|
||||||
sec1_reloc_cnt: .short 0
|
|
||||||
sec1_line_cnt: .short 0
|
|
||||||
sec1_flags: .int SCN_CNT_CODE | SCN_CNT_INITIALIZED_DATA \
|
|
||||||
| SCN_MEM_EXECUTE | SCN_MEM_READ | SCN_MEM_WRITE
|
|
||||||
|
|
||||||
section_headers_end:
|
|
||||||
|
|
||||||
.text
|
|
||||||
.psr abi64
|
|
||||||
.psr lsb
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
{
|
|
||||||
alloc r8=ar.pfs,2,0,0,0
|
|
||||||
mov gp=ip /* Get the address of _start/_text/__gp */
|
|
||||||
}
|
|
||||||
;;
|
|
||||||
add r14=@gprel(n1_desc),gp
|
|
||||||
add r15=@gprel(n2_desc),gp
|
|
||||||
add r16=@gprel(bhdr),gp
|
|
||||||
;;
|
|
||||||
st8 [r14]=in0
|
|
||||||
st8 [r15]=in1
|
|
||||||
;;
|
|
||||||
mov ar.pfs=r8
|
|
||||||
;;
|
|
||||||
mov r32=r16
|
|
||||||
;;
|
|
||||||
br.sptk.few _payload_start
|
|
||||||
|
|
||||||
.data
|
|
||||||
.global _start_plabel
|
|
||||||
.balign 16
|
|
||||||
_start_plabel:
|
|
||||||
.quad _start
|
|
||||||
.quad 0 /* I don't need a gp value... */
|
|
||||||
|
|
||||||
/* hand-crafted bhdr and parameters */
|
|
||||||
.balign 16
|
|
||||||
bhdr:
|
|
||||||
b_signature: .int 0x0E1FB007
|
|
||||||
b_size: .int bhdr_end - bhdr
|
|
||||||
b_checksum: .short 0
|
|
||||||
b_records: .short 3
|
|
||||||
/* A NOP note to 64bit align later data */
|
|
||||||
.balign 4
|
|
||||||
n0_namesz: .int 0
|
|
||||||
n0_descsz: .int 0
|
|
||||||
n0_type: .int EBN_NOP
|
|
||||||
.balign 4
|
|
||||||
n1_namesz: .int 10
|
|
||||||
n1_descsz: .int 8
|
|
||||||
n1_type: .int EB_IA64_IMAGE_HANDLE
|
|
||||||
n1_name: .asciz "Etherboot"
|
|
||||||
.balign 4
|
|
||||||
n1_desc: .quad 0
|
|
||||||
.balign 4
|
|
||||||
n2_namesz: .int 10
|
|
||||||
n2_descsz: .int 8
|
|
||||||
n2_type: .int EB_IA64_SYSTAB
|
|
||||||
n2_name: .asciz "Etherboot"
|
|
||||||
.balign 4
|
|
||||||
n2_desc: .quad 0
|
|
||||||
bhdr_end:
|
|
||||||
|
|
||||||
|
|
||||||
/* hand-craft a .reloc section for the plabel */
|
|
||||||
#define IMAGE_REL_BASED_ABS 0
|
|
||||||
#define IMAGE_REL_BASED_DIR64 10
|
|
||||||
|
|
||||||
.section ".reloc", "a"
|
|
||||||
.int _start_plabel_rva // PAGE RVA
|
|
||||||
.int 12 // Block Size (2*4+2*2)
|
|
||||||
.short (IMAGE_REL_BASED_DIR64<<12) + 0 // reloc for plabel's entry point
|
|
||||||
.short (IMAGE_REL_BASED_ABS <<12) + 0 // dummy reloc for good alignment
|
|
||||||
|
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
/* OUTPUT_FORMAT("binary") */
|
|
||||||
OUTPUT_FORMAT("elf64-ia64-little")
|
|
||||||
|
|
||||||
OUTPUT_ARCH(ia64)
|
|
||||||
|
|
||||||
ENTRY(_start_plabel)
|
|
||||||
_sect_align = 16; /* normally 512 */
|
|
||||||
_file_align = 16; /* normally 4096 */
|
|
||||||
/* Symbols for hardcoding the payload and _bss size, with apply_efi_prefix
|
|
||||||
* there is no need to set these, and in will get confused if these are not 0.
|
|
||||||
*/
|
|
||||||
_payload_size = 0;
|
|
||||||
_payload_bss = 0;
|
|
||||||
SECTIONS {
|
|
||||||
/* We can arbitrarily set image base to anything we want,
|
|
||||||
* but efi does not honor it, so it is a pointless exercise.
|
|
||||||
* So we just set the start address to 0.
|
|
||||||
*/
|
|
||||||
. = 0;
|
|
||||||
_link_base = . ;
|
|
||||||
_image_base = . ;
|
|
||||||
.hdrs : {
|
|
||||||
_hdrs = . ;
|
|
||||||
*(.hdrs)
|
|
||||||
. = ALIGN(_file_align) ;
|
|
||||||
_ehdrs = . ;
|
|
||||||
}
|
|
||||||
. = ALIGN(_sect_align);
|
|
||||||
.img : {
|
|
||||||
_img = . ;
|
|
||||||
_text = . ;
|
|
||||||
__gp = . ;
|
|
||||||
*(.text)
|
|
||||||
_etext = .;
|
|
||||||
. = ALIGN(16);
|
|
||||||
_data = . ;
|
|
||||||
*(.data)
|
|
||||||
_edata = .;
|
|
||||||
. = ALIGN(16);
|
|
||||||
_reloc = . ;
|
|
||||||
*(.reloc)
|
|
||||||
__ereloc = . ;
|
|
||||||
_ereloc = . ;
|
|
||||||
. = ALIGN(16);
|
|
||||||
/* . = ALIGN(_file_align) ; */
|
|
||||||
}
|
|
||||||
_payload_start = . ;
|
|
||||||
. = . + _payload_size ;
|
|
||||||
_payload_end = . ;
|
|
||||||
_eimg = . ;
|
|
||||||
. = ALIGN(_sect_align) ;
|
|
||||||
_bss = . ;
|
|
||||||
.bss : {
|
|
||||||
*(.bss)
|
|
||||||
. = . + _payload_bss;
|
|
||||||
}
|
|
||||||
_ebss = . ;
|
|
||||||
_end = . ;
|
|
||||||
/DISCARD/ : {
|
|
||||||
*(*)
|
|
||||||
}
|
|
||||||
|
|
||||||
_hdrs_size = _ehdrs - _hdrs;
|
|
||||||
_hdrs_off = 0;
|
|
||||||
|
|
||||||
_text_size = _etext - _text ;
|
|
||||||
_text_rva = _text - _image_base ;
|
|
||||||
_text_off = _text - _link_base;
|
|
||||||
|
|
||||||
_data_size = _edata - _data ;
|
|
||||||
_data_rva = _data - _image_base;
|
|
||||||
_data_off = _data - _link_base;
|
|
||||||
|
|
||||||
__reloc_size = __ereloc - _reloc ;
|
|
||||||
_reloc_size = _ereloc - _reloc ;
|
|
||||||
_reloc_rva = _reloc - _image_base;
|
|
||||||
_reloc_off = _reloc - _link_base;
|
|
||||||
|
|
||||||
_bss_size = _ebss - _bss;
|
|
||||||
_bss_rva = _bss - _image_base;
|
|
||||||
|
|
||||||
_img_size = _eimg - _img ;
|
|
||||||
_img_rva = _img - _image_base;
|
|
||||||
_img_off = _img - _link_base;
|
|
||||||
|
|
||||||
_img_mem_size = _ebss - _img;
|
|
||||||
|
|
||||||
_image_size = _ebss - _link_base ;
|
|
||||||
|
|
||||||
_start_plabel_rva = _start_plabel - _image_base;
|
|
||||||
}
|
|
|
@ -1,196 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
* Copyright (C) 2002 Eric Biederman
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Originally this code was part of ucl the data compression library
|
|
||||||
* for upx the ``Ultimate Packer of eXecutables''.
|
|
||||||
*
|
|
||||||
* - Converted to gas assembly, and refitted to work with etherboot.
|
|
||||||
* Eric Biederman 20 Aug 2002
|
|
||||||
*
|
|
||||||
* - Converted to functional ia64 assembly (Can this get smaller?)
|
|
||||||
* Eric Biederman 5 Dec 2002
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
/* See where I am running, and compute gp */
|
|
||||||
{
|
|
||||||
/* Do no call alloc here as I do not know how many argument
|
|
||||||
* registers are being passed through the decompressor, and if I report
|
|
||||||
* to few the unreported registers may get stomped.
|
|
||||||
*
|
|
||||||
* Instead just explicitly get the value of ar.pfs.
|
|
||||||
*/
|
|
||||||
mov r17=0
|
|
||||||
mov r8=ar.pfs
|
|
||||||
mov gp = ip /* The linker scripts sets gp at _start */
|
|
||||||
|
|
||||||
}
|
|
||||||
{.mlx
|
|
||||||
movl r9=0x123456789abcdef0 /* Get uncompressed_offset into r9 */
|
|
||||||
}
|
|
||||||
;;
|
|
||||||
{
|
|
||||||
add r14 = @gprel(payload + 4),gp
|
|
||||||
add r15 = r9,gp
|
|
||||||
mov r16=1 /* last_m_off = 1 */
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mov r20 = 0xd00
|
|
||||||
add r21 = r9,gp
|
|
||||||
br.sptk.few decompr_loop_n2b
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------- DECOMPRESSION -------------
|
|
||||||
|
|
||||||
Input:
|
|
||||||
r8 - ar.pfs
|
|
||||||
r14 - source
|
|
||||||
r15 - dest
|
|
||||||
r16 - 1
|
|
||||||
r17 - (buffer) 0
|
|
||||||
r20 - 0xd00 (constant)
|
|
||||||
r21 - start address
|
|
||||||
Usage:
|
|
||||||
r9 - scratch register for memory copies
|
|
||||||
r18 - scratch register for getbit
|
|
||||||
r19 - scratch register for loads and stores
|
|
||||||
Output:
|
|
||||||
r2 - 0
|
|
||||||
r3 - 0
|
|
||||||
*/
|
|
||||||
|
|
||||||
getbit:
|
|
||||||
add r18 = r17,r17
|
|
||||||
;;
|
|
||||||
cmp.ne p8,p0 = r0,r18
|
|
||||||
cmp.leu p6,p7 = r18,r17
|
|
||||||
;;
|
|
||||||
mov r17 = r18
|
|
||||||
(p8) br.cond.sptk.few getbit_end
|
|
||||||
/* Do a unaligned 64bit load */
|
|
||||||
;;
|
|
||||||
ld1 r17 = [r14],1
|
|
||||||
;;
|
|
||||||
ld1 r18 = [r14],1
|
|
||||||
;;
|
|
||||||
dep r17 = r18,r17,8,8
|
|
||||||
ld1 r18 = [r14],1
|
|
||||||
;;
|
|
||||||
dep r17 = r18,r17,16,8
|
|
||||||
ld1 r18 = [r14],1
|
|
||||||
;;
|
|
||||||
dep r17 = r18,r17,24,8
|
|
||||||
ld1 r18 = [r14],1
|
|
||||||
;;
|
|
||||||
dep r17 = r18,r17,32,8
|
|
||||||
ld1 r18 = [r14],1
|
|
||||||
;;
|
|
||||||
dep r17 = r18,r17,40,8
|
|
||||||
ld1 r18 = [r14],1
|
|
||||||
;;
|
|
||||||
dep r17 = r18,r17,48,8
|
|
||||||
ld1 r18 = [r14],1
|
|
||||||
;;
|
|
||||||
dep r17 = r18,r17,56,8
|
|
||||||
;;
|
|
||||||
add r18 = r17,r17,1
|
|
||||||
;;
|
|
||||||
cmp.leu p6,p7=r18,r17
|
|
||||||
;;
|
|
||||||
mov r17=r18
|
|
||||||
;;
|
|
||||||
getbit_end:
|
|
||||||
br.ret.sptk.few b6
|
|
||||||
|
|
||||||
|
|
||||||
decompr_literals_n2b:
|
|
||||||
ld1 r19 = [r14],1
|
|
||||||
;;
|
|
||||||
st1 [r15] = r19,1
|
|
||||||
;;
|
|
||||||
decompr_loop_n2b:
|
|
||||||
br.call.sptk.few b6 = getbit
|
|
||||||
;;
|
|
||||||
(p6) br.cond.sptk.few decompr_literals_n2b
|
|
||||||
(p7) add r2 = 1,r0 /* m_off = 1 */
|
|
||||||
;;
|
|
||||||
loop1_n2b:
|
|
||||||
br.call.sptk.few b6 = getbit
|
|
||||||
;;
|
|
||||||
(p6) add r2 = r2,r2,1 /* m_off = m_off*2 + getbit() */
|
|
||||||
(p7) add r2 = r2,r2
|
|
||||||
br.call.sptk.few b6 = getbit
|
|
||||||
;;
|
|
||||||
(p7) br.cond.sptk.few loop1_n2b /* while(!getbit()) */
|
|
||||||
;;
|
|
||||||
mov r3 = r0
|
|
||||||
cmp.eq p6,p0 = 2,r2
|
|
||||||
add r2 = -3,r2
|
|
||||||
(p6) br.cond.sptk.few decompr_ebpeax_n2b /* if (m_off == 2) goto decompr_ebpeax_n2b ? */
|
|
||||||
;;
|
|
||||||
ld1 r19 = [r14],1
|
|
||||||
shl r2 = r2,8
|
|
||||||
;;
|
|
||||||
dep r2 = r19,r2,0,8 /* m_off = (m_off - 3)*256 + src[ilen++] */
|
|
||||||
;;
|
|
||||||
cmp4.eq p6,p0 = -1,r2 /* if (m_off == 0xffffffff) goto decomp_end_n2b */
|
|
||||||
;;
|
|
||||||
(p6) br.cond.sptk.few decompr_end_n2b
|
|
||||||
mov r16 = r2 /* last_m_off = m_off */
|
|
||||||
;;
|
|
||||||
decompr_ebpeax_n2b:
|
|
||||||
br.call.sptk.few b6 = getbit
|
|
||||||
;;
|
|
||||||
(p6) add r3 = r3,r3,1 /* m_len = getbit() */
|
|
||||||
(p7) add r3 = r3,r3
|
|
||||||
br.call.sptk.few b6 = getbit
|
|
||||||
;;
|
|
||||||
(p6) add r3 = r3,r3,1 /* m_len = m_len*2 + getbit()) */
|
|
||||||
(p7) add r3 = r3,r3
|
|
||||||
;;
|
|
||||||
cmp.ne p6,p0 = r0,r3
|
|
||||||
(p6) br.cond.sptk.few decompr_got_mlen_n2b /* if (m_len == 0) goto decompr_got_mlen_n2b */
|
|
||||||
add r3 = 1,r3 /* m_len++ */
|
|
||||||
;;
|
|
||||||
loop2_n2b:
|
|
||||||
br.call.sptk.few b6 = getbit
|
|
||||||
;;
|
|
||||||
(p6) add r3 = r3,r3,1 /* m_len = m_len*2 + getbit() */
|
|
||||||
(p7) add r3 = r3,r3
|
|
||||||
br.call.sptk.few b6 = getbit
|
|
||||||
;;
|
|
||||||
(p7) br.cond.sptk.few loop2_n2b /* while(!getbit()) */
|
|
||||||
add r3 = 2, r3 /* m_len += 2 */
|
|
||||||
;;
|
|
||||||
decompr_got_mlen_n2b:
|
|
||||||
cmp.gtu p6,p7 = r16, r20
|
|
||||||
;;
|
|
||||||
(p6) add r3 = 2, r3 /* m_len = m_len + 1 + (last_m_off > 0xd00) */
|
|
||||||
(p7) add r3 = 1, r3
|
|
||||||
sub r9 = r15, r16,1 /* m_pos = dst + olen - last_m_off - 1 */
|
|
||||||
;;
|
|
||||||
1:
|
|
||||||
ld1 r19 = [r9],1
|
|
||||||
add r3 = -1,r3
|
|
||||||
;;
|
|
||||||
st1 [r15] = r19,1 /* dst[olen++] = *m_pos++ while(m_len > 0) */
|
|
||||||
cmp.ne p6,p0 = r0,r3
|
|
||||||
(p6) br.cond.sptk.few 1b
|
|
||||||
;;
|
|
||||||
br.cond.sptk.few decompr_loop_n2b
|
|
||||||
decompr_end_n2b:
|
|
||||||
/* Branch to the start address */
|
|
||||||
mov ar.pfs=r8
|
|
||||||
;;
|
|
||||||
mov b6 = r21
|
|
||||||
;;
|
|
||||||
br.sptk.few b6
|
|
||||||
|
|
||||||
payload:
|
|
|
@ -1,28 +0,0 @@
|
||||||
OUTPUT_FORMAT("elf64-ia64-little")
|
|
||||||
|
|
||||||
OUTPUT_ARCH(ia64)
|
|
||||||
|
|
||||||
ENTRY(_start)
|
|
||||||
SECTIONS {
|
|
||||||
. = 0;
|
|
||||||
__gp = .;
|
|
||||||
_text = . ;
|
|
||||||
.text : {
|
|
||||||
*(.text)
|
|
||||||
}
|
|
||||||
/DISCARD/ : {
|
|
||||||
*(.comment)
|
|
||||||
*(.note)
|
|
||||||
*(.hash)
|
|
||||||
*(.data)
|
|
||||||
*(.sbss)
|
|
||||||
*(.bss)
|
|
||||||
*(.dynstr)
|
|
||||||
*(.dynsym)
|
|
||||||
*(.IA_64.unwind)
|
|
||||||
*(.IA_64.unwind_info)
|
|
||||||
*(.IA64_unwind)
|
|
||||||
*(.IA64_unwind_info)
|
|
||||||
*(.dynamic)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue