david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

They can come back when they have someone to support them.

This commit is contained in:
Michael Brown 2006-03-17 14:13:09 +00:00
parent a2b15fd1fe
commit b2909e547d
89 changed files with 0 additions and 8563 deletions

View File

@ -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"

View File

@ -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 $< $@

View File

@ -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 );

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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,
};

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -1 +0,0 @@
/* empty file */

View 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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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'"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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 ! */
}

View File

@ -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 );

View File

@ -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_ ]
}
}

View File

@ -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_
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -1,6 +0,0 @@
#ifndef ETHERBOOT_BITS_ENDIAN_H
#define ETHERBOOT_BITS_ENDIAN_H
#define __BYTE_ORDER __BIG_ENDIAN
#endif /* ETHERBOOT_BITS_ENDIAN_H */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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 )` > $@

View File

@ -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

View File

@ -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)
}
}

View File

@ -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 );

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -1,6 +0,0 @@
#ifndef ETHERBOOT_BITS_ENDIAN_H
#define ETHERBOOT_BITS_ENDIAN_H
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif /* ETHERBOOT_BITS_ENDIAN_H */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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:

View File

@ -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)
}
}