diff options
Diffstat (limited to 'arch/arm/boot')
-rw-r--r-- | arch/arm/boot/Makefile | 13 | ||||
-rw-r--r-- | arch/arm/boot/bootp/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/boot/bootp/init.S | 67 | ||||
-rw-r--r-- | arch/arm/boot/compressed/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head-ftvpci.S | 7 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head-l7200.S | 13 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head-sa1100.S | 8 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head-shark.S | 121 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head.S | 8 | ||||
-rw-r--r-- | arch/arm/boot/compressed/ofw-shark.c | 216 | ||||
-rw-r--r-- | arch/arm/boot/compressed/setup-sa1100.S | 14 | ||||
-rw-r--r-- | arch/arm/boot/compressed/vmlinux.lds.in | 5 |
12 files changed, 425 insertions, 52 deletions
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index f74033b36..7b13b1bcb 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -83,15 +83,18 @@ ZTEXTADDR = 0xc0008000 ZRELADDR = 0xc0008000 ifeq ($(CONFIG_SA1100_VICTOR),y) ZTEXTADDR = 0x00002000 - ZBSSADDR = 0xc0100000 + ZBSSADDR = 0xc0200000 endif ifeq ($(CONFIG_SA1100_SHERMAN),y) ZTEXTADDR = 0x00050000 - ZBSSADDR = 0xc0100000 + ZBSSADDR = 0xc0200000 endif ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y) ZTEXTADDR = 0xC0200000 endif +ifeq ($(CONFIG_SA1111),y) + ZRELADDR = 0xc0208000 +endif endif # @@ -105,15 +108,15 @@ endif export SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS Image: $(CONFIGURE) $(SYSTEM) - $(OBJCOPY) $(SYSTEM) $@ + $(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) $@ bzImage: zImage zImage: $(CONFIGURE) compressed/vmlinux - $(OBJCOPY) compressed/vmlinux $@ + $(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@ bootpImage: bootp/bootp - $(OBJCOPY) bootp/bootp $@ + $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ compressed/vmlinux: $(TOPDIR)/vmlinux dep @$(MAKE) -C compressed vmlinux diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile index 918e3eb9e..adeeeddc5 100644 --- a/arch/arm/boot/bootp/Makefile +++ b/arch/arm/boot/bootp/Makefile @@ -7,7 +7,8 @@ INITRD =$(ZSYSTEM) ZLDFLAGS =-p -X -T bootp.lds \ --defsym initrd_addr=$(INITRD_PHYS) \ --defsym initrd_virt=$(INITRD_VIRT) \ - --defsym params=$(PARAMS_PHYS) + --defsym params=$(PARAMS_PHYS) \ + --defsym kernel_addr=$(ZTEXTADDR) all: bootp diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S index 2b498b7bb..9963fbc2b 100644 --- a/arch/arm/boot/bootp/init.S +++ b/arch/arm/boot/bootp/init.S @@ -12,33 +12,59 @@ */ .section .start,#alloc,#execinstr .type _entry, #function -_entry: -kernel_addr: adr r10, initdata - ldmia r10, {r11, r12} +_entry: adr r10, initdata + ldr r11, initdata sub r11, r10, r11 @ work out exec offset - add r12, r12, r11 @ correct "splitify" - mov pc, r12 @ jump to splitify + b splitify .size _entry,. - _entry .type initdata, #object initdata: .word initdata @ compiled address of this - .word splitify .size initdata,. - initdata .text splitify: adr r13, data - ldmia r13!, {r4-r6} @ move the kernel + ldmia r13!, {r4-r6} @ move the initrd add r4, r4, r11 @ correction - mov r12, r5 bl move - ldmia r13!, {r4-r6} @ then the initrd + ldmia r13!, {r4-r6} @ then the kernel + mov r12, r5 add r4, r4, r11 @ correction bl move - ldmib r13, {r5,r6,r7} @ get size and addr of initrd - add r7, r7, #16*4 @ offset of initrd_start in param_struct - stmia r7, {r5,r6} @ save in param_struct +/* + * Setup the initrd parameters to pass to the kernel. This can either be + * passed in via a param_struct or a tag list. We spot the param_struct + * method by looking at the first word; this should either indicate a page + * size of 4K, 16K or 32K. + */ + ldmia r13, {r5-r8} @ get size and addr of initrd + @ r5 = ATAG_INITRD + @ r6 = initrd start + @ r7 = initrd end + @ r8 = param_struct address + ldr r9, [r8, #0] @ no param struct? + teq r9, #0x1000 @ 4K? + teqne r9, #0x4000 @ 16K? + teqne r9, #0x8000 @ 32K? + beq no_taglist + +/* + * find the end of the tag list, and then add an INITRD tag on the end. + */ +taglist: ldr r9, [r8, #0] @ tag length + teq r9, #0 @ last tag? + addne r8, r8, r9 + bne taglist + + mov r4, #16 @ length of initrd tag + mov r9, #0 @ end of tag list terminator + stmia r8, {r4, r5, r6, r7, r9} + mov pc, r12 @ call kernel + +no_taglist: add r8, r8, #16*4 + stmia r8, {r6,r7} @ save in param_struct mov pc, r12 @ call kernel move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time @@ -49,17 +75,18 @@ move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time bcs move mov pc, lr -data: .word kernel_start - .word kernel_addr - .word kernel_len - - .word initrd_start +data: .word initrd_start .word initrd_addr .word initrd_len - .word initrd_virt - .word initrd_len - .word params + .word kernel_start + .word kernel_addr + .word kernel_len + + .word 0x54410005 @ r5 = ATAG_INITRD + .word initrd_virt @ r6 + .word initrd_len @ r7 + .word params @ r8 .type kernel_start,#object .type initrd_start,#object diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index bf8f1c947..7f077cd21 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -66,7 +66,7 @@ $(HEAD): $(HEAD:.o=.S) $(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S) piggy.o: $(SYSTEM) - $(OBJCOPY) $(SYSTEM) piggy + $(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) piggy gzip $(GZFLAGS) < piggy > piggy.gz $(LD) -r -o $@ -b binary piggy.gz rm -f piggy piggy.gz diff --git a/arch/arm/boot/compressed/head-ftvpci.S b/arch/arm/boot/compressed/head-ftvpci.S index a8c806ef3..8e10667ca 100644 --- a/arch/arm/boot/compressed/head-ftvpci.S +++ b/arch/arm/boot/compressed/head-ftvpci.S @@ -6,6 +6,13 @@ * Special startup code for FTV PCI board. */ +/* + * This program 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. + */ + .section ".start", #alloc, #execinstr ftv_start: mcr p15, 0, r0, c7, c5, 0 @ flush I cache diff --git a/arch/arm/boot/compressed/head-l7200.S b/arch/arm/boot/compressed/head-l7200.S index ecf4d6881..8ab9eafdb 100644 --- a/arch/arm/boot/compressed/head-l7200.S +++ b/arch/arm/boot/compressed/head-l7200.S @@ -3,7 +3,7 @@ * * Copyright (C) 2000 Steve Hill <sjhill@cotw.com> * - * Some code borrowed from Nicola Pitre's 'head-sa1100.S' file. This + * Some code borrowed from Nicolas Pitre's 'head-sa1100.S' file. This * is merged with head.S by the linker. */ @@ -16,15 +16,14 @@ .section ".start", #alloc, #execinstr __L7200_start: - mov r0, #0x00100000 @ FLASH address of initrd mov r2, #0xf1000000 @ RAM address of initrd - add r1, r2, #0x00700000 @ Size of initrd + add r3, r2, #0x00700000 @ Size of initrd 1: - ldmia r0!, {r3, r4, r5, r6} - stmia r2!, {r3, r4, r5, r6} - cmp r2, r1 + ldmia r0!, {r4, r5, r6, r7} + stmia r2!, {r4, r5, r6, r7} + cmp r2, r3 ble 1b - + mov r8, #0 @ Zero it out mov r7, #19 @ Set architecture ID diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S index 73cef4bd8..f49ceb5e6 100644 --- a/arch/arm/boot/compressed/head-sa1100.S +++ b/arch/arm/boot/compressed/head-sa1100.S @@ -11,10 +11,6 @@ #include <linux/linkage.h> #include <asm/mach-types.h> -#ifndef CONFIG_ARCH_SA1100 -#error What am I doing here... -#endif - .section ".start", #alloc, #execinstr __SA1100_start: @@ -54,6 +50,8 @@ __SA1100_start: bic r0, r0, #0x0d @ clear WB, DC, MMU bic r0, r0, #0x1000 @ clear Icache mcr p15, 0, r0, c1, c0, 0 + +#ifdef CONFIG_ANGELBOOT /* * Pause for a short time so that we give enough time * for the host to start a terminal up. @@ -61,3 +59,5 @@ __SA1100_start: mov r0, #0x00200000 1: subs r0, r0, #1 bne 1b +#endif + diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S new file mode 100644 index 000000000..817b75366 --- /dev/null +++ b/arch/arm/boot/compressed/head-shark.S @@ -0,0 +1,121 @@ +/* The head-file for the Shark + * by Alexander.Schulz@stud.uni-karlsruhe.de + * + * Does the following: + * - get the memory layout from firmware. This can only be done as long as the mmu + * is still on. + * - switch the mmu off, so we have physical addresses + * - copy the kernel to 0x08508000. This is done to have a fixed address where the + * C-parts (misc.c) are executed. This address must be known at compile-time, + * but the load-address of the kernel depends on how much memory is installed. + * - Jump to this location. + * - Set r8 with 0, r7 with the architecture ID for head.S + */ + +#include <linux/linkage.h> + +#include <asm/assembler.h> + + .section ".start", #alloc, #execinstr + + b __beginning + +__serial_addr: .long 0xf7eff3f8 + .long 0 @ space +__ofw_data: .long 0 @ the number of memory blocks + .space 128 @ (startaddr,size) ... + .space 128 @ bootargs + .align + +__beginning: mov r4, r0 @ save the entry to the firmware + + mov r0, #0xC0 @ disable irq and fiq + mov r1, r0 + mrs r3, cpsr_all + bic r2, r3, r0 + eor r2, r2, r1 + msr cpsr_all, r2 + + ldr r0, __serial_addr @ disable serial interrupt + mov r1, #0 @ hangs the machine, I don t know why. + strb r1, [r0, #0x01] + + mov r0, r4 @ get the Memory layout from firmware + adr r1, __ofw_data + add r2, r1, #4 + mov lr, pc + b SYMBOL_NAME(ofw_init) + mov r1, #0 + + adr r2, __mmu_off @ calculate physical address + sub r2, r2, #0xf0000000 @ openprom maps us at f000 virt, 0e50 phys + adr r0, __ofw_data + ldr r0, [r0, #4] + add r2, r2, r0 + add r2, r2, #0x00500000 + + mrc p15, 0, r3, c1, c0 + bic r3, r3, #0xC @ Write Buffer and DCache + bic r3, r3, #0x1000 @ ICache + mcr p15, 0, r3, c1, c0 @ disabled + + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4 + + bic r3, r3, #0x1 @ MMU + mcr p15, 0, r3, c1, c0 @ disabled + + mov pc, r2 + +__copy_target: .long 0x08508000 +__copy_end: .long 0x08608000 + + .word _start + .word __bss_start + + .align +__temp_stack: .space 128 + +__mmu_off: + adr r0, __ofw_data + ldr r0, [r0, #4] + orr r0, r0, #0x00600000 + + ldr r1, __copy_end + ldr r3, __copy_target + +/* r0 = 0x0e600000 (current end of kernelcode) + * r3 = 0x08508000 (where it should begin) + * r1 = 0x08608000 (end of copying area, 1MB) + * The kernel is compressed, so 1 MB should be enough. + * copy the kernel to the beginning of physical memory + * We start from the highest address, so we can copy + * from 0x08500000 to 0x08508000 if we have only 8MB + */ + + +__Copy: ldr r2, [r0], #-4 + str r2, [r1], #-4 + teq r1, r3 + bne __Copy + /* and jump to it */ + adr r2, __go_on + adr r0, __ofw_data + ldr r0, [r0, #4] + sub r2, r2, r0 + sub r2, r2, #0x00500000 + ldr r0, __copy_target + add r2, r2, r0 + mov pc, r2 + +__go_on: + adr sp, __temp_stack + add sp, sp, #128 + adr r0, __ofw_data + mov lr, pc + b SYMBOL_NAME(create_params) + + mov r8, #0 + mov r7, #15 diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 21bdb43c0..0e384ec72 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -112,8 +112,7 @@ start: */ .text -1: mrc p15, 0, r6, c0, c0 @ get processor ID - adr r2, LC0 +1: adr r2, LC0 ldmia r2, {r2, r3, r4, r5, sp} mov r0, #0 @@ -124,14 +123,15 @@ start: cmp r2, r3 blt 1b + mrc p15, 0, r6, c0, c0 @ get processor ID bl cache_on mov r1, sp @ malloc space above stack add r2, sp, #0x10000 @ 64k max teq r4, r5 @ will we overwrite ourselves? - moveq r5, r2 - movne r5, r4 + moveq r5, r2 @ decompress after image + movne r5, r4 @ decompress to final location mov r0, r5 mov r3, r7 diff --git a/arch/arm/boot/compressed/ofw-shark.c b/arch/arm/boot/compressed/ofw-shark.c new file mode 100644 index 000000000..0b4474c59 --- /dev/null +++ b/arch/arm/boot/compressed/ofw-shark.c @@ -0,0 +1,216 @@ +/* + * linux/arch/arm/boot/compressed/ofw-shark.c + * + * by Alexander.Schulz@stud.uni-karlsruhe.de + * + * This file is used to get some basic information + * about the memory layout of the shark we are running + * on. Memory is usually divided in blocks a 8 MB. + * And bootargs are copied from OpenFirmware. + */ + + +#include <linux/kernel.h> +#include <asm/setup.h> +#include <asm/page.h> + + +asmlinkage void +create_params (unsigned long *buffer) +{ + /* Is there a better address? Also change in kernel/arch.c */ + struct param_struct *params = (struct param_struct *) 0x08003000; + int j,i,m,k,nr_banks,size; + + for (j=0;j<256;j++) params->u1.unused[j]=0; + + size=0; + nr_banks=(unsigned int) buffer[0]; + if (nr_banks > NR_BANKS) nr_banks = NR_BANKS; + for (j=0;j<nr_banks;j++){ + /* search the lowest address and put it into the next entry */ + /* not a fast sort algorithm, but there are at most 8 entries */ + /* and this is used only once anyway */ + m=0xffffffff; + for (i=0;i<(unsigned int) buffer[0];i++){ + if (buffer[2*i+1]<m) { + m=buffer[2*i+1]; + k=i; + } + } + + /* using pages_in_bank for startaddress and size */ + /* start is in bytes, size in pages and not bigger than 0x2000 */ + /* This is decoded in fixup_shark in arch/arm/kernel/arch.c */ + params->u1.s.pages_in_bank[j]=buffer[2*k+1]|(buffer[2*k+2]/PAGE_SIZE); + size += buffer[2*k+2]; + + buffer[2*k+1]=0xffffffff; /* mark as copied */ + } + + params->u1.s.page_size = PAGE_SIZE; + params->u1.s.nr_pages = size/PAGE_SIZE; + params->u1.s.flags = FLAG_READONLY; + + /* Copy over the bootargs */ + for (j=0;j<128/4;j++) { + ((unsigned long *) params->commandline)[j]=buffer[33+j]; + } +} + + +typedef int (*ofw_handle_t)(void *); + +/* Everything below is called with a wrong MMU setting. + * This means: no string constants, no initialization of + * arrays, no global variables! This is ugly but I didn't + * want to write this in assembler :-) + */ + +int +of_decode_int(const unsigned char *p) +{ + unsigned int i = *p++ << 8; + i = (i + *p++) << 8; + i = (i + *p++) << 8; + return (i + *p); +} + +int +OF_finddevice(ofw_handle_t openfirmware, char *name) +{ + unsigned int args[8]; + char service[12]; + + service[0]='f'; + service[1]='i'; + service[2]='n'; + service[3]='d'; + service[4]='d'; + service[5]='e'; + service[6]='v'; + service[7]='i'; + service[8]='c'; + service[9]='e'; + service[10]='\0'; + + args[0]=(unsigned int)service; + args[1]=1; + args[2]=1; + args[3]=(unsigned int)name; + + if (openfirmware(args) == -1) + return -1; + return args[4]; +} + +int +OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop) +{ + unsigned int args[8]; + char service[12]; + + service[0]='g'; + service[1]='e'; + service[2]='t'; + service[3]='p'; + service[4]='r'; + service[5]='o'; + service[6]='p'; + service[7]='l'; + service[8]='e'; + service[9]='n'; + service[10]='\0'; + + args[0] = (unsigned int)service; + args[1] = 2; + args[2] = 1; + args[3] = (unsigned int)handle; + args[4] = (unsigned int)prop; + + if (openfirmware(args) == -1) + return -1; + return args[5]; +} + +int +OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen) +{ + unsigned int args[8]; + char service[8]; + + service[0]='g'; + service[1]='e'; + service[2]='t'; + service[3]='p'; + service[4]='r'; + service[5]='o'; + service[6]='p'; + service[7]='\0'; + + args[0] = (unsigned int)service; + args[1] = 4; + args[2] = 1; + args[3] = (unsigned int)handle; + args[4] = (unsigned int)prop; + args[5] = (unsigned int)buf; + args[6] = buflen; + + if (openfirmware(args) == -1) + return -1; + return args[7]; +} + +asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer) +{ + int phandle,i,mem_len,buffer[32]; + char temp[12]; + + temp[0]='/'; + temp[1]='m'; + temp[2]='e'; + temp[3]='m'; + temp[4]='o'; + temp[5]='r'; + temp[6]='y'; + temp[7]='\0'; + + phandle=OF_finddevice(o,temp); + + temp[0]='r'; + temp[1]='e'; + temp[2]='g'; + temp[3]='\0'; + + mem_len = OF_getproplen(o,phandle, temp); + OF_getprop(o,phandle, temp, buffer, mem_len); + *nomr=mem_len >> 3; + + for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]); + + temp[0]='/'; + temp[1]='c'; + temp[2]='h'; + temp[3]='o'; + temp[4]='s'; + temp[5]='e'; + temp[6]='n'; + temp[7]='\0'; + + phandle=OF_finddevice(o,temp); + + temp[0]='b'; + temp[1]='o'; + temp[2]='o'; + temp[3]='t'; + temp[4]='a'; + temp[5]='r'; + temp[6]='g'; + temp[7]='s'; + temp[8]='\0'; + + mem_len = OF_getproplen(o,phandle, temp); + OF_getprop(o,phandle, temp, buffer, mem_len); + for (i=0; i<=mem_len/4; i++) pointer[i+32]=buffer[i]; + +} diff --git a/arch/arm/boot/compressed/setup-sa1100.S b/arch/arm/boot/compressed/setup-sa1100.S index 3babde180..32e77c285 100644 --- a/arch/arm/boot/compressed/setup-sa1100.S +++ b/arch/arm/boot/compressed/setup-sa1100.S @@ -33,13 +33,11 @@ UART3_BASE: .long 0x80050000 #define UTSR0 0x1c #define UTSR1 0x20 -#define BAUD_DIV_230400 0x000 -#define BAUD_DIV_115200 0x001 -#define BAUD_DIV_57600 0x003 -#define BAUD_DIV_38400 0x005 -#define BAUD_DIV_19200 0x00b -#define BAUD_DIV_9600 0x017 -#define BAUD_DIV BAUD_DIV_9600 +#ifndef CONFIG_SA1100_DEFAULT_BAUDRATE +#define CONFIG_SA1100_DEFAULT_BAUDRATE 9600 +#endif + +#define BAUD_DIV ((230400/CONFIG_SA1100_DEFAULT_BAUDRATE)-1) SCR_loc: .long SYMBOL_NAME(SCR_value) #define GPIO_2_9 0x3fc @@ -92,7 +90,7 @@ skip_SCR: bne skip_uart @ UART3 if Assabet is used with Neponset - teq r3, #25 @ if Assabet + teq r3, #MACH_TYPE_ASSABET @ if Assabet tsteq r2, #(1 << 9) @ ... and Neponset present ldreq r0, UART3_BASE beq uart_init diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index 86ed5e6e3..8608996e9 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in @@ -19,12 +19,13 @@ SECTIONS .text : { _start = .; - head.o(.start) *(.start) - head.o(.text) *(.text) *(.fixup) *(.gnu.warning) + *(.rodata) + *(.glue_7) + *(.glue_7t) input_data = .; piggy.o input_data_end = .; |