Commit d5313e0f authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Linus Torvalds

[PATCH] alpha: bootp fixes

- redefine "printk" as "srm_printk" for bootstrappers;
- fix stack corruption problem with bootp/bootpz loaders and older
  SRM consoles.
parent 99fcf73f
OUTPUT_FORMAT("elf64-alpha")
ENTRY(__start)
printk = srm_printk;
SECTIONS
{
. = 0x20000000;
......
......@@ -26,6 +26,8 @@ extern unsigned long switch_to_osf_pal(unsigned long nr,
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
unsigned long *vptb);
extern void move_stack(unsigned long new_stack);
struct hwrpb_struct *hwrpb = INIT_HWRPB;
static struct pcb_struct pcb_va[1];
......@@ -118,12 +120,10 @@ static inline void
runkernel(void)
{
__asm__ __volatile__(
"bis %1,%1,$30\n\t"
"bis %0,%0,$27\n\t"
"jmp ($27)"
: /* no outputs: it doesn't even return */
: "r" (START_ADDR),
"r" (PAGE_SIZE + INIT_STACK));
: "r" (START_ADDR));
}
extern char _end;
......@@ -147,9 +147,7 @@ start_kernel(void)
*/
static long nbytes;
static char envval[256] __attribute__((aligned(8)));
#ifdef INITRD_IMAGE_SIZE
static unsigned long initrd_start;
#endif
srm_printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
if (INIT_HWRPB->pagesize != 8192) {
......@@ -164,13 +162,20 @@ start_kernel(void)
}
pal_init();
#ifdef INITRD_IMAGE_SIZE
/* The initrd must be page-aligned. See below for the
cause of the magic number 5. */
initrd_start = ((START_ADDR + 5*KERNEL_SIZE) | (PAGE_SIZE-1)) + 1;
initrd_start = ((START_ADDR + 5*KERNEL_SIZE + PAGE_SIZE) |
(PAGE_SIZE-1)) + 1;
#ifdef INITRD_IMAGE_SIZE
srm_printk("Initrd positioned at %#lx\n", initrd_start);
#endif
/*
* Move the stack to a safe place to ensure it won't be
* overwritten by kernel image.
*/
move_stack(initrd_start - PAGE_SIZE);
nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
if (nbytes < 0 || nbytes >= sizeof(envval)) {
nbytes = 0;
......
......@@ -41,9 +41,6 @@
#undef DEBUG_ADDRESSES
#undef DEBUG_LAST_STEPS
#define DEBUG_SP(x) \
{register long sp asm("30"); srm_printk("%s (sp=%lx)\n", x, sp);}
extern unsigned long switch_to_osf_pal(unsigned long nr,
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
unsigned long *vptb);
......@@ -51,6 +48,8 @@ extern unsigned long switch_to_osf_pal(unsigned long nr,
extern int decompress_kernel(void* destination, void *source,
size_t ksize, size_t kzsize);
extern void move_stack(unsigned long new_stack);
struct hwrpb_struct *hwrpb = INIT_HWRPB;
static struct pcb_struct pcb_va[1];
......@@ -163,12 +162,10 @@ static inline void
runkernel(void)
{
__asm__ __volatile__(
"bis %1,%1,$30\n\t"
"bis %0,%0,$27\n\t"
"jmp ($27)"
: /* no outputs: it doesn't even return */
: "r" (START_ADDR),
"r" (PAGE_SIZE + INIT_STACK));
: "r" (START_ADDR));
}
/* Must record the SP (it is virtual) on entry, so we can make sure
......@@ -253,7 +250,9 @@ extern char _end;
for "bootmem" anyway.
*/
#define K_COPY_IMAGE_START NEXT_PAGE(K_KERNEL_IMAGE_END)
#define K_INITRD_START NEXT_PAGE(K_COPY_IMAGE_START + KERNEL_SIZE)
/* Reserve one page below INITRD for the new stack. */
#define K_INITRD_START \
NEXT_PAGE(K_COPY_IMAGE_START + KERNEL_SIZE + PAGE_SIZE)
#define K_COPY_IMAGE_END \
(K_INITRD_START + REAL_INITRD_SIZE + MALLOC_AREA_SIZE)
#define K_COPY_IMAGE_SIZE \
......@@ -419,8 +418,7 @@ start_kernel(void)
initrd_image_start,
INITRD_IMAGE_SIZE);
#endif
memcpy((void *)initrd_image_start,
(void *)V_INITRD_START,
memcpy((void *)initrd_image_start, (void *)V_INITRD_START,
INITRD_IMAGE_SIZE);
#endif /* INITRD_IMAGE_SIZE */
......@@ -436,9 +434,14 @@ start_kernel(void)
K_KERNEL_IMAGE_START,
(unsigned)KERNEL_SIZE);
#endif
/*
* Move the stack to a safe place to ensure it won't be
* overwritten by kernel image.
*/
move_stack(initrd_image_start - PAGE_SIZE);
memcpy((void *)K_KERNEL_IMAGE_START,
(void *)uncompressed_image_start,
KERNEL_SIZE);
(void *)uncompressed_image_start, KERNEL_SIZE);
}
/* Clear the zero page, then move the argument list in. */
......
......@@ -100,3 +100,24 @@ halt:
.prologue 0
call_pal PAL_halt
.end halt
/* $16 - new stack page */
.align 3
.globl move_stack
.ent move_stack
move_stack:
.prologue 0
lda $0, 0x1fff($31)
and $0, $30, $1 /* Stack offset */
or $1, $16, $16 /* New stack pointer */
mov $30, $1
mov $16, $2
1: ldq $3, 0($1) /* Move the stack */
addq $1, 8, $1
stq $3, 0($2)
and $0, $1, $4
addq $2, 8, $2
bne $4, 1b
mov $16, $30
ret ($26)
.end move_stack
......@@ -205,15 +205,3 @@ decompress_kernel(void *output_start,
/* puts(" done, booting the kernel.\n"); */
return output_ptr;
}
/* dummy-up printk */
asmlinkage int printk(const char *fmt, ...)
{
va_list args;
long ret;
va_start(args, fmt);
ret = srm_printk(fmt, args);
va_end(args);
return ret;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment