mirror of
https://github.com/xcat2/xNBA.git
synced 2025-03-02 17:20:16 +00:00
They can come back when they have someone to support them.
This commit is contained in:
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…
x
Reference in New Issue
Block a user