diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 4205b865141ff2e255fe1d3bd16de18e217ef06a (patch) | |
tree | 37f362d54d4df0567b6ee2ad4526b2a58836232b | |
download | legacy-cdma-import.tar.gz |
Initial Contributionandroid-1.0release-1.0cdma-import
80 files changed, 8392 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..d915837 --- /dev/null +++ b/Android.mk @@ -0,0 +1,22 @@ +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Most of these don't make sense to build unless the board has defined +# a link script. + +ifdef TARGET_BOOTLOADER_LINK_SCRIPT + include $(call all-subdir-makefiles) +endif @@ -0,0 +1,51 @@ + +The bootloader environment consists of a set of libraries that provide +various features and a couple small driver programs that build against +these libraries. The libraries used come from three categories -- +generic (containing code useful to any bootloader), architecture +(containing code useful to a specific cpu, system-on-chip, etc), and +board (containing code useful to a single specific device) + +For the purpose of this discussion, we will involve the fictional +companies Outstanding Electronics Manufacturing (OEM) and Silicon +Engineering Management, Inc (SEMI). OEM produces the quality Brick +mobile device using SEMI's 65002 ARM-based system-on-chip. + +Common bootloader libraries and base architectures: + +boot/include/boot headers +boot/libboot libboot.a +boot/libc libboot_c.a +boot/arch_armv6 libboot_arch_armv6.a + +Architecture-specific libraries for SEMI 65002 SOC: + +partner/semi/boot/include/65002 headers +partner/semi/boot/arch_65002 liboot_arch_65002.a + +Device-specific library for OEM Brick phone: + +partner/oem/brick/product_config.mk configuration +partner/oem/brick/boot libboot_board_brick.a + +The actual bootloader: + +boot/bootloader bootloader + + +The product_config.mk defines three important build variables: + +DEVICE_BOOTLOADER_LIBS := \ + libboot_board_brick.a \ + libboot_arch_65002.a \ + libboot_arch_armv6.a + +DEVICE_BOOTLOADER_LINK_SCRIPT := \ + partner/semi/boot/boot.ld + +DEVICE_BOOTLOADER_INIT := \ + partner/semi/boot/init.S + +Which are used by the bootloader to specify which board and +architecture specific libraries to link against as well as what link +script and init.S to use diff --git a/arch_armv6/Android.mk b/arch_armv6/Android.mk new file mode 100644 index 0000000..7014a68 --- /dev/null +++ b/arch_armv6/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_ARM_MODE := arm + +LOCAL_SRC_FILES := irq.S dcc.S jtag.S misc.S + +LOCAL_C_INCLUDES := $(call include-path-for, bootloader) + +LOCAL_CFLAGS := -O2 -g -W -Wall +LOCAL_CFLAGS += -march=armv6 + +LOCAL_MODULE := libboot_arch_armv6 + +include $(BUILD_RAW_STATIC_LIBRARY)
\ No newline at end of file diff --git a/arch_armv6/dcc.S b/arch_armv6/dcc.S new file mode 100644 index 0000000..c789f94 --- /dev/null +++ b/arch_armv6/dcc.S @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +.global dcc_putc +.global dcc_getc + +dcc_getc: + mrc 14, 0, r0, c0, c1, 0 + tst r0, #(1 << 30) + moveq r0, #-1 + mrcne 14, 0, r0, c0, c5, 0 + bx lr + +dcc_putc: + /* read status to flags */ + mrc 14, 0, r15, c0, c1, 0 + mcrcc 14, 0, r0, c0, c5, 0 + movcc r0, #0 + movcs r0, #-1 + bx lr diff --git a/arch_armv6/irq.S b/arch_armv6/irq.S new file mode 100644 index 0000000..3336b63 --- /dev/null +++ b/arch_armv6/irq.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +.global enable_irq + +enable_irq: + cpsie i + bx lr diff --git a/arch_armv6/jtag.S b/arch_armv6/jtag.S new file mode 100644 index 0000000..fdcaf40 --- /dev/null +++ b/arch_armv6/jtag.S @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +.global jtag_hook, func + +jtag_hook: + bx lr diff --git a/arch_armv6/misc.S b/arch_armv6/misc.S new file mode 100644 index 0000000..1a1acbe --- /dev/null +++ b/arch_armv6/misc.S @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +.global periph_2gb_open +.global periph_2gb_close + +periph_2gb_open: + /* open the peripheral port 2gb */ + /* see 1136trm 3-164 */ + ldr r0, =0x80000016 + mcr p15, 0, r0, c15, c2, 4 + bx lr + +periph_2gb_close: + mov r0, #0 + mcr p15, 0, r0, c15, c2, 4 + bx lr diff --git a/arch_msm7k/Android.mk b/arch_msm7k/Android.mk new file mode 100644 index 0000000..3c787ae --- /dev/null +++ b/arch_msm7k/Android.mk @@ -0,0 +1,25 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_ARM_MODE := arm + +LOCAL_SRC_FILES := \ + clock.c \ + hsusb.c \ + mddi_console.c \ + nand.c \ + uart.c \ + gpio.c \ + mddi.c \ + vic.c \ + shared.c + +LOCAL_C_INCLUDES := $(call include-path-for, bootloader) + +LOCAL_CFLAGS := -O2 -g -W -Wall +LOCAL_CFLAGS += -march=armv6 + +LOCAL_MODULE := libboot_arch_msm7k + +include $(BUILD_RAW_STATIC_LIBRARY) diff --git a/arch_msm7k/clock.c b/arch_msm7k/clock.c new file mode 100644 index 0000000..0bb0926 --- /dev/null +++ b/arch_msm7k/clock.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <msm7k/gpt.h> + +static inline unsigned rd_cycle_count(void) +{ + unsigned cc; + asm volatile ( + "mrc p15, 0, %0, c15, c12, 1\n" : + "=r" (cc) + ); + return cc; +} + +static inline unsigned rd_dtcm(void) +{ + unsigned cc; + asm volatile ( + "mrc p15, 0, %0, c9, c1, 0\n" : + "=r" (cc) + ); + return cc; +} + +static inline unsigned rd_itcm(void) +{ + unsigned cc; + asm volatile ( + "mrc p15, 0, %0, c9, c1, 1\n" : + "=r" (cc) + ); + return cc; +} + +static inline void perf_enable(void) +{ + asm volatile ( + "mcr p15, 0, %0, c15, c12, 0\n" : : "r" (7) + ); +} + +static inline void perf_disable(void) +{ + asm volatile ( + "mcr p15, 0, %0, c15, c12, 0\n" : : "r" (0) + ); +} + +unsigned cycles_per_second(void) +{ + unsigned T0, T1; + + perf_enable(); + + writel(0, GPT_CLEAR); + writel(0, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) != 0) ; + + writel(GPT_ENABLE_EN, GPT_ENABLE); + T0 = rd_cycle_count(); + while(readl(GPT_COUNT_VAL) < 32766) ; + T1 = rd_cycle_count(); + + writel(0, GPT_ENABLE); + writel(0, GPT_CLEAR); + + perf_disable(); + + return T1-T0; +} + +void mdelay(unsigned msecs) +{ + msecs *= 33; + + writel(0, GPT_CLEAR); + writel(0, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) != 0) ; + + writel(GPT_ENABLE_EN, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) < msecs) ; + + writel(0, GPT_ENABLE); + writel(0, GPT_CLEAR); +} + +void udelay(unsigned usecs) +{ + usecs = (usecs * 33 + 1000 - 33) / 1000; + + writel(0, GPT_CLEAR); + writel(0, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) != 0) ; + + writel(GPT_ENABLE_EN, GPT_ENABLE); + while(readl(GPT_COUNT_VAL) < usecs) ; + + writel(0, GPT_ENABLE); + writel(0, GPT_CLEAR); +} + +void print_cpu_speed(void) +{ + unsigned cps = cycles_per_second(); + dprintf("1 second = %d cycles\n%d MHz\n", cps, cps / 1000000); +} + +#define A11S_CLK_CNTL 0xC0100100 +#define A11S_CLK_SEL 0xC0100104 + +#define C A11S_CLK_CNTL +#define S A11S_CLK_SEL + +#if FROM_APPSBOOT_MBN +static unsigned tbl_old[] = { + C, 0x640000, + S, 2, + C, 0x640010, + C, 0x64001F, + S, 3, + C, 0x64101F, + C, 0x64171F, + S, 2, + C, 0x64171F, + C, 0x641715, + S, 3, + S, 5, + C, 0x641715, + C, 0x641315, + S, 4, + S, 6, + C, 0x641315, + C, 0x641312, + S, 7, + C, 0x641312, + C, 0x641112, + S, 6, + 0 +}; +#endif + +static unsigned tbl[] = { +#if EXPLORE + C, 0x640000, S, 2, + C, 0x640001, S, 3, + C, 0x640201, S, 2, + C, 0x640203, S, 3, + C, 0x640403, S, 2, + C, 0x640405, S, 3, + C, 0x640605, S, 2, + C, 0x640607, S, 3, + C, 0x640807, S, 2, + C, 0x640809, S, 3, + C, 0x640A09, S, 2, + C, 0x640A0B, S, 3, + C, 0x640C0B, S, 2, + C, 0x640C0D, S, 3, + C, 0x640E0D, S, 2, + C, 0x640E0F, S, 3, +#endif + C, 0x640000, S, 2, + C, 0x64001F, S, 3, + C, 0x64171F, S, 2, + C, 0x641715, S, 5, + C, 0x641315, S, 6, + C, 0x641312, S, 7, + C, 0x641112, S, 6, + 0 +}; +#undef C +#undef S + +#if TESTCASE +unsigned cc_div[16] = { + 1, 2, 3, 4, 5, 8, 6, 16, + 1, 1, 1, 1, 1, 1, 1, 32 /* guess */ +}; + +unsigned cc_base[4] = { + 19200000, + 245760000, + 800000000, + 0 +}; + +unsigned cs_div[4] = { + 1, 2, 3, 4 +}; + +void info(unsigned c, unsigned s) +{ + unsigned src_sel, src_div; + + if(s & 1) { + /* src1 selected */ + src_sel = (c >> 4) & 0x7; + src_div = c & 0xF; + } else { + /* src0 selected */ + src_sel = (c >> 12) & 0x7; + src_div = (c >> 8) & 0xF; + } + + unsigned src = s & 1; + unsigned pdiv = cs_div[(s >> 1) & 3]; + unsigned div = cc_div[src_div]; + unsigned clk = cc_base[src_sel] / div; + unsigned pclk = clk / pdiv; + + unsigned cps = cycles_per_second(); + + dprintf("CC=0x%x CS=0x%x SRC=%d PDIV=%d SEL=%d DIV=%d CPS=%d ACLK=%d\n", + c, s, src, pdiv, src_sel, div, cps, clk); +} + + +void arm11_clock_test(void) +{ + unsigned c, s; + unsigned *x = tbl; + + while(*x) { + unsigned *ptr = (unsigned*) *x++; + unsigned val = *x++; + *ptr = val; + + if(ptr == ((unsigned*) A11S_CLK_CNTL)) { + c = val; + } else { + s = val; + info(c, s); + } + } +} +#endif + +void arm11_clock_init(void) +{ + unsigned *x = tbl; + while(*x) { + unsigned *ptr = (unsigned*) *x++; + unsigned val = *x++; + *ptr = val; + } +} + + diff --git a/arch_msm7k/gpio.c b/arch_msm7k/gpio.c new file mode 100644 index 0000000..f4b0705 --- /dev/null +++ b/arch_msm7k/gpio.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <msm7k/gpio.h> + +/* gross */ + +typedef struct gpioregs gpioregs; + +struct gpioregs +{ + unsigned out; + unsigned in; + unsigned int_status; + unsigned int_clear; + unsigned int_en; + unsigned int_edge; + unsigned int_pos; + unsigned oe; +}; + +static gpioregs GPIO_REGS[] = { + { + .out = GPIO_OUT_0, + .in = GPIO_IN_0, + .int_status = GPIO_INT_STATUS_0, + .int_clear = GPIO_INT_CLEAR_0, + .int_en = GPIO_INT_EN_0, + .int_edge = GPIO_INT_EDGE_0, + .int_pos = GPIO_INT_POS_0, + .oe = GPIO_OE_0, + }, + { + .out = GPIO_OUT_1, + .in = GPIO_IN_1, + .int_status = GPIO_INT_STATUS_1, + .int_clear = GPIO_INT_CLEAR_1, + .int_en = GPIO_INT_EN_1, + .int_edge = GPIO_INT_EDGE_1, + .int_pos = GPIO_INT_POS_1, + .oe = GPIO_OE_1, + }, + { + .out = GPIO_OUT_2, + .in = GPIO_IN_2, + .int_status = GPIO_INT_STATUS_2, + .int_clear = GPIO_INT_CLEAR_2, + .int_en = GPIO_INT_EN_2, + .int_edge = GPIO_INT_EDGE_2, + .int_pos = GPIO_INT_POS_2, + .oe = GPIO_OE_2, + }, + { + .out = GPIO_OUT_3, + .in = GPIO_IN_3, + .int_status = GPIO_INT_STATUS_3, + .int_clear = GPIO_INT_CLEAR_3, + .int_en = GPIO_INT_EN_3, + .int_edge = GPIO_INT_EDGE_3, + .int_pos = GPIO_INT_POS_3, + .oe = GPIO_OE_3, + }, + { + .out = GPIO_OUT_4, + .in = GPIO_IN_4, + .int_status = GPIO_INT_STATUS_4, + .int_clear = GPIO_INT_CLEAR_4, + .int_en = GPIO_INT_EN_4, + .int_edge = GPIO_INT_EDGE_4, + .int_pos = GPIO_INT_POS_4, + .oe = GPIO_OE_4, + }, +}; + +static gpioregs *find_gpio(unsigned n, unsigned *bit) +{ + if(n > 106) return 0; + if(n > 94) { + *bit = 1 << (n - 95); + return GPIO_REGS + 4; + } + if(n > 67) { + *bit = 1 << (n - 68); + return GPIO_REGS + 3; + } + if(n > 42) { + *bit = 1 << (n - 43); + return GPIO_REGS + 2; + } + if(n > 15) { + *bit = 1 << (n - 16); + return GPIO_REGS + 1; + } + *bit = 1 << n; + return GPIO_REGS + 0; +} + +void gpio_output_enable(unsigned n, unsigned out) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if((r = find_gpio(n, &b)) == 0) return; + + v = readl(r->oe); + if(out) { + writel(v | b, r->oe); + } else { + writel(v & (~b), r->oe); + } +} + +void gpio_write(unsigned n, unsigned on) +{ + gpioregs *r; + unsigned b; + unsigned v; + + if((r = find_gpio(n, &b)) == 0) return; + + v = readl(r->out); + if(on) { + writel(v | b, r->out); + } else { + writel(v & (~b), r->out); + } +} + +int gpio_read(unsigned n) +{ + gpioregs *r; + unsigned b; + + if((r = find_gpio(n, &b)) == 0) return 0; + + return (readl(r->in) & b) ? 1 : 0; +} + +void gpio_dir(int nr, int out) +{ + gpio_output_enable(nr, out); +} + +void gpio_set(int nr, int set) +{ + gpio_write(nr, set); +} + +int gpio_get(int nr) +{ + return gpio_read(nr); +} + + diff --git a/arch_msm7k/hsusb.c b/arch_msm7k/hsusb.c new file mode 100644 index 0000000..bdcedca --- /dev/null +++ b/arch_msm7k/hsusb.c @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <msm7k/hsusb.h> +#include <boot/usb.h> +#include <boot/usb_descriptors.h> + +#if 1 +#define DBG(x...) do {} while(0) +#else +#define DBG(x...) dprintf(x) +#endif + +struct usb_endpoint +{ + struct usb_endpoint *next; + unsigned bit; + struct ept_queue_head *head; + struct usb_request *req; + unsigned char num; + unsigned char in; +}; + +struct usb_endpoint *ept_list = 0; +struct ept_queue_head *epts = 0; + +static int usb_online = 0; +static int usb_highspeed = 0; + +struct usb_endpoint *usb_endpoint_alloc(unsigned num, unsigned in, unsigned max_pkt) +{ + struct usb_endpoint *ept; + unsigned cfg; + + ept = alloc(sizeof(*ept)); + + ept->num = num; + ept->in = !!in; + ept->req = 0; + + cfg = CONFIG_MAX_PKT(max_pkt) | CONFIG_ZLT; + + if(ept->in) { + ept->bit = EPT_TX(ept->num); + } else { + ept->bit = EPT_RX(ept->num); + if(num == 0) + cfg |= CONFIG_IOS; + } + + ept->head = epts + (num * 2) + (ept->in); + ept->head->config = cfg; + + ept->next = ept_list; + ept_list = ept; + + DBG("ept%d %s @%p/%p max=%d bit=%x\n", + num, in ? "in":"out", ept, ept->head, max_pkt, ept->bit); + + return ept; +} + +static void endpoint_enable(struct usb_endpoint *ept, unsigned yes) +{ + unsigned n = readl(USB_ENDPTCTRL(ept->num)); + + if(yes) { + if(ept->in) { + n |= (CTRL_TXE | CTRL_TXR | CTRL_TXT_BULK); + } else { + n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK); + } + + if(ept->num != 0) { + /* XXX should be more dynamic... */ + if(usb_highspeed) { + ept->head->config = CONFIG_MAX_PKT(512) | CONFIG_ZLT; + } else { + ept->head->config = CONFIG_MAX_PKT(64) | CONFIG_ZLT; + } + } + } + writel(n, USB_ENDPTCTRL(ept->num)); +} + +struct usb_request *usb_request_alloc(unsigned bufsiz) +{ + struct usb_request *req; + req = alloc(sizeof(*req)); + req->buf = alloc(bufsiz); + req->item = alloc(32); + return req; +} + +int usb_queue_req(struct usb_endpoint *ept, struct usb_request *req) +{ + struct ept_queue_item *item = req->item; + unsigned phys = (unsigned) req->buf; + + item->next = TERMINATE; + item->info = INFO_BYTES(req->length) | INFO_IOC | INFO_ACTIVE; + item->page0 = phys; + item->page1 = (phys & 0xfffff000) + 0x1000; + + ept->head->next = (unsigned) item; + ept->head->info = 0; + ept->req = req; + + DBG("ept%d %s queue req=%p\n", + ept->num, ept->in ? "in" : "out", req); + + writel(ept->bit, USB_ENDPTPRIME); + return 0; +} + +static void handle_ept_complete(struct usb_endpoint *ept) +{ + struct ept_queue_item *item; + unsigned actual; + int status; + struct usb_request *req; + + DBG("ept%d %s complete req=%p\n", + ept->num, ept->in ? "in" : "out", ept->req); + + req = ept->req; + if(req) { + ept->req = 0; + + item = req->item; + + if(item->info & 0xff) { + actual = 0; + status = -1; + dprintf("EP%d/%s FAIL nfo=%x pg0=%x\n", + ept->num, ept->in ? "in" : "out", item->info, item->page0); + } else { + actual = req->length - ((item->info >> 16) & 0x7fff); + status = 0; + } + if(req->complete) + req->complete(req, actual, status); + } +} + +static const char *reqname(unsigned r) +{ + switch(r) { + case GET_STATUS: return "GET_STATUS"; + case CLEAR_FEATURE: return "CLEAR_FEATURE"; + case SET_FEATURE: return "SET_FEATURE"; + case SET_ADDRESS: return "SET_ADDRESS"; + case GET_DESCRIPTOR: return "GET_DESCRIPTOR"; + case SET_DESCRIPTOR: return "SET_DESCRIPTOR"; + case GET_CONFIGURATION: return "GET_CONFIGURATION"; + case SET_CONFIGURATION: return "SET_CONFIGURATION"; + case GET_INTERFACE: return "GET_INTERFACE"; + case SET_INTERFACE: return "SET_INTERFACE"; + default: return "*UNKNOWN*"; + } +} + +static struct usb_endpoint *ep0in, *ep0out; +static struct usb_request *ep0req; + +static void setup_ack(void) +{ + ep0req->complete = 0; + ep0req->length = 0; + usb_queue_req(ep0in, ep0req); +} + +static void ep0in_complete(struct usb_request *req, unsigned actual, int status) +{ + DBG("ep0in_complete %p %d %d\n", req, actual, status); + if(status == 0) { + req->length = 0; + req->complete = 0; + usb_queue_req(ep0out, req); + } +} + +static void setup_tx(void *buf, unsigned len) +{ + DBG("setup_tx %p %d\n", buf, len); + memcpy(ep0req->buf, buf, len); + ep0req->complete = ep0in_complete; + ep0req->length = len; + usb_queue_req(ep0in, ep0req); +} + +static unsigned char usb_config_value = 0; + +#define SETUP(type,request) (((type) << 8) | (request)) + +static void handle_setup(struct usb_endpoint *ept) +{ + setup_packet s; + + memcpy(&s, ept->head->setup_data, sizeof(s)); + writel(ept->bit, USB_ENDPTSETUPSTAT); + + DBG("handle_setup type=0x%b req=0x%b val=%d idx=%d len=%d (%s)\n", + s.type, s.request, s.value, s.index, s.length, + reqname(s.request)); + + switch(SETUP(s.type,s.request)) { + case SETUP(DEVICE_READ, GET_STATUS): { + unsigned zero = 0; + if(s.length == 2) { + setup_tx(&zero, 2); + return; + } + break; + } + case SETUP(DEVICE_READ, GET_DESCRIPTOR): { + dtable *d = usb_highspeed ? descr_hs : descr_fs; + while(d->data) { + if(s.value == d->id) { + unsigned len = d->length; + if(len > s.length) len = s.length; + setup_tx(d->data, len); + return; + } + d++; + } + break; + } + case SETUP(DEVICE_READ, GET_CONFIGURATION): + /* disabling this causes data transaction failures on OSX. Why? + */ + if((s.value == 0) && (s.index == 0) && (s.length == 1)) { + setup_tx(&usb_config_value, 1); + return; + } + break; + case SETUP(DEVICE_WRITE, SET_CONFIGURATION): + if(s.value == 1) { + struct usb_endpoint *ept; + /* enable endpoints */ + for(ept = ept_list; ept; ept = ept->next){ + if(ept->num == 0) + continue; + endpoint_enable(ept, s.value); + } + usb_config_value = 1; + } else { + writel(0, USB_ENDPTCTRL(1)); + usb_config_value = 0; + } + setup_ack(); + usb_online = s.value ? 1 : 0; + usb_status(s.value ? 1 : 0, usb_highspeed); + return; + case SETUP(DEVICE_WRITE, SET_ADDRESS): + /* write address delayed (will take effect + ** after the next IN txn) + */ + writel((s.value << 25) | (1 << 24), USB_DEVICEADDR); + setup_ack(); + return; + case SETUP(INTERFACE_WRITE, SET_INTERFACE): + /* if we ack this everything hangs */ + /* per spec, STALL is valid if there is not alt func */ + goto stall; + case SETUP(ENDPOINT_WRITE, CLEAR_FEATURE): { + struct usb_endpoint *ept; + unsigned num = s.index & 15; + unsigned in = !!(s.index & 0x80); + + if((s.value == 0) && (s.length == 0)) { + DBG("clr feat %d %d\n", num, in); + for(ept = ept_list; ept; ept = ept->next) { + if((ept->num == num) && (ept->in == in)) { + endpoint_enable(ept, 1); + setup_ack(); + return; + } + } + } + break; + } + } + + dprintf("STALL %s %b %b %d %d %d\n", + reqname(s.request), + s.type, s.request, s.value, s.index, s.length); + +stall: + writel((1<<16) | (1 << 0), USB_ENDPTCTRL(ept->num)); +} + +unsigned ulpi_read(unsigned reg) +{ + /* initiate read operation */ + writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while(readl(USB_ULPI_VIEWPORT) & ULPI_RUN) ; + + return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); +} + +void ulpi_write(unsigned val, unsigned reg) +{ + /* initiate write operation */ + writel(ULPI_RUN | ULPI_WRITE | + ULPI_ADDR(reg) | ULPI_DATA(val), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while(readl(USB_ULPI_VIEWPORT) & ULPI_RUN) ; +} + +void board_usb_init(void); +void board_ulpi_init(void); + +void usb_init(void) +{ + epts = alloc_page_aligned(4096); + + memset(epts, 0, 32 * sizeof(struct ept_queue_head)); + + board_usb_init(); + + /* select ULPI phy */ + writel(0x81000000, USB_PORTSC); + + /* RESET */ + writel(0x00080002, USB_USBCMD); + mdelay(20); + + board_ulpi_init(); + + writel((unsigned) epts, USB_ENDPOINTLISTADDR); + + /* select DEVICE mode */ + writel(0x02, USB_USBMODE); + + writel(0xffffffff, USB_ENDPTFLUSH); + + /* go to RUN mode (D+ pullup enable) */ + writel(0x00080001, USB_USBCMD); + + + ep0out = usb_endpoint_alloc(0, 0, 64); + ep0in = usb_endpoint_alloc(0, 1, 64); + ep0req = usb_request_alloc(4096); +} + +void usb_shutdown(void) +{ + /* disable pullup */ + writel(0x0008000, USB_USBCMD); + mdelay(10); +} + +void usb_poll(void) +{ + struct usb_endpoint *ept; + unsigned n = readl(USB_USBSTS); + writel(n, USB_USBSTS); + + n &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI); + + if(n == 0) return; + + if(n & STS_URI) { + writel(readl(USB_ENDPTCOMPLETE), USB_ENDPTCOMPLETE); + writel(readl(USB_ENDPTSETUPSTAT), USB_ENDPTSETUPSTAT); + writel(0xffffffff, USB_ENDPTFLUSH); + writel(0, USB_ENDPTCTRL(1)); + DBG("-- reset --\n"); + usb_online = 0; + usb_config_value = 0; + + /* error out any pending reqs */ + for(ept = ept_list; ept; ept = ept->next) { + ept->head->info = INFO_ACTIVE; + handle_ept_complete(ept); + } + usb_status(0, usb_highspeed); + } + if(n & STS_SLI) { + DBG("-- suspend --\n"); + } + if(n & STS_PCI) { + DBG("-- portchange --\n"); + unsigned spd = (readl(USB_PORTSC) >> 26) & 3; + if(spd == 2) { + usb_highspeed = 1; + } else { + usb_highspeed = 0; + } + } + if(n & STS_UEI) dprintf("<UEI %x>\n", readl(USB_ENDPTCOMPLETE)); +#if 0 + DBG("STS: "); + if(n & STS_UEI) DBG("ERROR "); + if(n & STS_SLI) DBG("SUSPEND "); + if(n & STS_URI) DBG("RESET "); + if(n & STS_PCI) DBG("PORTCHANGE "); + if(n & STS_UI) DBG("USB "); + DBG("\n"); +#endif + if((n & STS_UI) || (n & STS_UEI)) { + n = readl(USB_ENDPTSETUPSTAT); + if(n & EPT_RX(0)) { + handle_setup(ep0out); + } + + n = readl(USB_ENDPTCOMPLETE); + if(n != 0) { + writel(n, USB_ENDPTCOMPLETE); + } + + for(ept = ept_list; ept; ept = ept->next){ + if(n & ept->bit) { + handle_ept_complete(ept); + } + } + } +// dprintf("@\n"); +} + + diff --git a/arch_msm7k/mddi.c b/arch_msm7k/mddi.c new file mode 100644 index 0000000..4cfd735 --- /dev/null +++ b/arch_msm7k/mddi.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/board.h> +#include <msm7k/mddi.h> + +unsigned fb_width = 0; +unsigned fb_height = 0; + +static unsigned short *FB; +static mddi_llentry *mlist; + +void wr32(void *_dst, unsigned n) +{ + unsigned char *src = (unsigned char*) &n; + unsigned char *dst = _dst; + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; +}; + +void printcaps(mddi_client_caps *c) +{ + if((c->length != 0x4a) || (c->type != 0x42)) { + dprintf("bad caps header\n"); + memset(c, 0, sizeof(*c)); + return; + } + + dprintf("mddi: bm: %d,%d win %d,%d rgb %x\n", + c->bitmap_width, c->bitmap_height, + c->display_window_width, c->display_window_height, + c->rgb_cap); + dprintf("mddi: vend %x prod %x\n", + c->manufacturer_name, c->product_code); + + fb_width = c->bitmap_width; + fb_height = c->bitmap_height; + + panel_init(c); +} + +mddi_llentry *mlist_remote_write = 0; + +void mddi_remote_write(unsigned val, unsigned reg) +{ + mddi_llentry *ll; + mddi_register_access *ra; + unsigned s; + + if(mlist_remote_write == 0) { + mlist_remote_write = alloc(sizeof(mddi_llentry)); + } + + ll = mlist_remote_write; + + ra = &(ll->u.r); + ra->length = 14 + 4; + ra->type = TYPE_REGISTER_ACCESS; + ra->client_id = 0; + ra->rw_info = MDDI_WRITE | 1; + ra->crc = 0; + + wr32(&ra->reg_addr, reg); + wr32(&ra->reg_data, val); + + ll->flags = 1; + ll->header_count = 14; + ll->data_count = 4; + wr32(&ll->data, (unsigned) &ra->reg_data); + wr32(&ll->next, 0); + ll->reserved = 0; + + writel((unsigned) ll, MDDI_PRI_PTR); + + s = readl(MDDI_STAT); + while((s & 0x20) == 0){ + s = readl(MDDI_STAT); + } +} + +void mddi_start_update(void) +{ + writel((unsigned) mlist, MDDI_PRI_PTR); +} + +int mddi_update_done(void) +{ + return !!(readl(MDDI_STAT) & MDDI_STAT_PRI_LINK_LIST_DONE); +} + +void mddi_do_cmd(unsigned cmd) +{ + writel(cmd, MDDI_CMD); + + while (!(readl(MDDI_INT) & MDDI_INT_NO_REQ_PKTS_PENDING)) ; +} + +unsigned char *rev_pkt_buf; + +void mddi_get_caps(void) +{ + unsigned timeout = 100000; + unsigned n; + + memset(rev_pkt_buf, 0xee, 256); + +// writel(CMD_HIBERNATE, MDDI_CMD); +// writel(CMD_LINK_ACTIVE, MDDI_CMD); + + writel(256, MDDI_REV_SIZE); + writel((unsigned) rev_pkt_buf, MDDI_REV_PTR); + mddi_do_cmd(CMD_FORCE_NEW_REV_PTR); + + /* sometimes this will fail -- do it three times for luck... */ + mddi_do_cmd(CMD_RTD_MEASURE); + mdelay(1); + + mddi_do_cmd(CMD_RTD_MEASURE); + mdelay(1); + + mddi_do_cmd(CMD_RTD_MEASURE); + mdelay(1); + + mddi_do_cmd(CMD_GET_CLIENT_CAP); + + do { + n = readl(MDDI_INT); + } while(!(n & MDDI_INT_REV_DATA_AVAIL) && (--timeout)); + + if(timeout == 0) dprintf("timeout\n"); + printcaps((mddi_client_caps*) rev_pkt_buf); +} + + +void mddi_init(void) +{ + unsigned n; + +// dprintf("mddi_init()\n"); + + rev_pkt_buf = alloc(256); + + mddi_do_cmd(CMD_RESET); + + /* disable periodic rev encap */ + mddi_do_cmd(CMD_PERIODIC_REV_ENC | 0); + + writel(0x0001, MDDI_VERSION); + writel(0x3C00, MDDI_BPS); + writel(0x0003, MDDI_SPM); + + writel(0x0005, MDDI_TA1_LEN); + writel(0x000C, MDDI_TA2_LEN); + writel(0x0096, MDDI_DRIVE_HI); + writel(0x0050, MDDI_DRIVE_LO); + writel(0x003C, MDDI_DISP_WAKE); + writel(0x0002, MDDI_REV_RATE_DIV); + + /* needs to settle for 5uS */ + if (readl(MDDI_PAD_CTL) == 0) { + writel(0x08000, MDDI_PAD_CTL); + udelay(5); + } + + writel(0xA850F, MDDI_PAD_CTL); + writel(0x60006, MDDI_DRIVER_START_CNT); + + writel((unsigned) rev_pkt_buf, MDDI_REV_PTR); + writel(256, MDDI_REV_SIZE); + writel(256, MDDI_REV_ENCAP_SZ); + + mddi_do_cmd(CMD_FORCE_NEW_REV_PTR); + + /* disable hibernate */ + mddi_do_cmd(CMD_HIBERNATE | 0); + + panel_backlight(0); + + panel_poweron(); + + mddi_do_cmd(CMD_LINK_ACTIVE); + + do { + n = readl(MDDI_STAT); + } while(!(n & MDDI_STAT_LINK_ACTIVE)); + + /* v > 8? v > 8 && < 0x19 ? */ + writel(2, MDDI_TEST); + +// writel(CMD_PERIODIC_REV_ENC | 0, MDDI_CMD); /* disable */ + + mddi_get_caps(); + +#if 0 + writel(0x5666, MDDI_MDP_VID_FMT_DES); + writel(0x00C3, MDDI_MDP_VID_PIX_ATTR); + writel(0x0000, MDDI_MDP_CLIENTID); +#endif + + dprintf("panel is %d x %d\n", fb_width, fb_height); + + FB = alloc(2 * fb_width * fb_height); + mlist = alloc(sizeof(mddi_llentry) * (fb_height / 8)); + +// dprintf("FB @ %x mlist @ %x\n", (unsigned) FB, (unsigned) mlist); + + for(n = 0; n < (fb_height / 8); n++) { + unsigned y = n * 8; + unsigned pixels = fb_width * 8; + mddi_video_stream *vs = &(mlist[n].u.v); + + vs->length = sizeof(mddi_video_stream) - 2 + (pixels * 2); + vs->type = TYPE_VIDEO_STREAM; + vs->client_id = 0; + vs->format = 0x5565; // FORMAT_16BPP; + vs->pixattr = PIXATTR_BOTH_EYES | PIXATTR_TO_ALL; + + vs->left = 0; + vs->right = fb_width - 1; + vs->top = y; + vs->bottom = y + 7; + + vs->start_x = 0; + vs->start_y = y; + + vs->pixels = pixels; + vs->crc = 0; + vs->reserved = 0; + + mlist[n].header_count = sizeof(mddi_video_stream) - 2; + mlist[n].data_count = pixels * 2; + mlist[n].reserved = 0; + wr32(&mlist[n].data, ((unsigned) FB) + (y * fb_width * 2)); + + mlist[n].flags = 0; + wr32(&mlist[n].next, (unsigned) (mlist + n + 1)); + } + + mlist[n-1].flags = 1; + wr32(&mlist[n-1].next, 0); + + writel(CMD_HIBERNATE, MDDI_CMD); + writel(CMD_LINK_ACTIVE, MDDI_CMD); + + for(n = 0; n < (fb_width * fb_height); n++) FB[n] = 0; + + mddi_start_update(); + + panel_backlight(1); +} + +void *mddi_framebuffer(void) +{ + return FB; +} + diff --git a/arch_msm7k/mddi_console.c b/arch_msm7k/mddi_console.c new file mode 100644 index 0000000..c1389ca --- /dev/null +++ b/arch_msm7k/mddi_console.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/font5x12.h> + +static unsigned short BGCOLOR = 0x001F; +static unsigned short FGCOLOR = 0xFFFF; + +static void drawglyph(unsigned short *pixels, unsigned short paint, + unsigned stride, unsigned *glyph) +{ + unsigned x, y, data; + stride -= 5; + + data = glyph[0]; + for(y = 0; y < 6; y++) { + for(x = 0; x < 5; x++) { + if(data & 1) *pixels = paint; + data >>= 1; + pixels++; + } + pixels += stride; + } + data = glyph[1]; + for(y = 0; y < 6; y++) { + for(x = 0; x < 5; x++) { + if(data & 1) *pixels = paint; + data >>= 1; + pixels++; + } + pixels += stride; + } +} + +#if 0 +static void drawtext(unsigned x, unsigned y, unsigned paint, const char *text) +{ + unsigned short *pixels = mddi_framebuffer(); + unsigned stride = fb_width; + char c; + + while((c = *text++)) { + if((c < ' ') || (c > 127)) continue; + c = (c - 32) * 2; + drawglyph(pixels + y*stride + x, paint, stride, font5x12 + c); + x += 6; + } +} +#endif + +static int cx, cy, cmaxx, cmaxy; + +void console_clear(void) +{ + unsigned short *dst = mddi_framebuffer(); + unsigned count = fb_width * fb_height; + cx = 0; + cy = 0; + while(count--) *dst++ = BGCOLOR; +} + +static void scroll_up(void) +{ + unsigned short *dst = mddi_framebuffer(); + unsigned short *src = dst + (fb_width * 12); + unsigned count = fb_height * (fb_width - 12); + + while(count--) { + *dst++ = *src++; + } + count = fb_width * 12; + while(count--) { + *dst++ = BGCOLOR; + } +} + +void console_putc(unsigned c) +{ + unsigned short *pixels; + + if(c > 127) return; + if(c < 32) { + if(c == '\n') goto newline; + return; + } + + pixels = mddi_framebuffer(); + drawglyph(pixels + cy * 12 * fb_width + cx * 6, FGCOLOR, + fb_width, font5x12 + (c - 32) * 2); + + cx++; + if(cx < cmaxx) return; + +newline: + cy++; + cx = 0; + if(cy >= cmaxy) { + cy = cmaxy - 1; + scroll_up(); + } +} + +void console_flush(void) +{ + mddi_start_update(); + while(!mddi_update_done()) ; +} + +void console_set_colors(unsigned bg, unsigned fg) +{ + BGCOLOR = bg; + FGCOLOR = fg; +} + +void console_init(void) +{ + mddi_init(); + + cmaxx = fb_width / 6; + cmaxy = (fb_height-1) / 12; + cx = 0; + cy = 0; + + console_clear(); + console_flush(); +} + diff --git a/arch_msm7k/nand.c b/arch_msm7k/nand.c new file mode 100644 index 0000000..ea123f0 --- /dev/null +++ b/arch_msm7k/nand.c @@ -0,0 +1,630 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/flash.h> + +#include <msm7k/dmov.h> +#include <msm7k/nand.h> +#include <msm7k/shared.h> + +#define VERBOSE 0 + +typedef struct dmov_ch dmov_ch; +struct dmov_ch +{ + volatile unsigned cmd; + volatile unsigned result; + volatile unsigned status; + volatile unsigned config; +}; + +static void dmov_prep_ch(dmov_ch *ch, unsigned id) +{ + ch->cmd = DMOV_CMD_PTR(id); + ch->result = DMOV_RSLT(id); + ch->status = DMOV_STATUS(id); + ch->config = DMOV_CONFIG(id); +} + +#define SRC_CRCI_NAND_CMD CMD_SRC_CRCI(DMOV_NAND_CRCI_CMD) +#define DST_CRCI_NAND_CMD CMD_DST_CRCI(DMOV_NAND_CRCI_CMD) +#define SRC_CRCI_NAND_DATA CMD_SRC_CRCI(DMOV_NAND_CRCI_DATA) +#define DST_CRCI_NAND_DATA CMD_DST_CRCI(DMOV_NAND_CRCI_DATA) + +static unsigned CFG0, CFG1; + +#define CFG1_WIDE_FLASH (1U << 1) + +#define paddr(n) ((unsigned) (n)) + +static int dmov_exec_cmdptr(unsigned id, unsigned *ptr) +{ + dmov_ch ch; + unsigned n; + + dmov_prep_ch(&ch, id); + + writel(DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(paddr(ptr)), ch.cmd); + + while(!(readl(ch.status) & DMOV_STATUS_RSLT_VALID)) ; + + n = readl(ch.status); + while(DMOV_STATUS_RSLT_COUNT(n)) { + n = readl(ch.result); + if(n != 0x80000002) { + dprintf("ERROR: result: %x\n", n); + dprintf("ERROR: flush: %x %x %x %x\n", + readl(DMOV_FLUSH0(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH1(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH2(DMOV_NAND_CHAN)), + readl(DMOV_FLUSH3(DMOV_NAND_CHAN))); + } + n = readl(ch.status); + } + + return 0; +} + +static unsigned flash_maker = 0; +static unsigned flash_device = 0; + +static void flash_read_id(dmov_s *cmdlist, unsigned *ptrlist) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + + data[0] = 0 | 4; + data[1] = NAND_CMD_FETCH_ID; + data[2] = 1; + data[3] = 0; + data[4] = 0; + + cmd[0].cmd = 0 | CMD_OCB; + cmd[0].src = paddr(&data[0]); + cmd[0].dst = NAND_FLASH_CHIP_SELECT; + cmd[0].len = 4; + + cmd[1].cmd = DST_CRCI_NAND_CMD; + cmd[1].src = paddr(&data[1]); + cmd[1].dst = NAND_FLASH_CMD; + cmd[1].len = 4; + + cmd[2].cmd = 0; + cmd[2].src = paddr(&data[2]); + cmd[2].dst = NAND_EXEC_CMD; + cmd[2].len = 4; + + cmd[3].cmd = SRC_CRCI_NAND_DATA; + cmd[3].src = NAND_FLASH_STATUS; + cmd[3].dst = paddr(&data[3]); + cmd[3].len = 4; + + cmd[4].cmd = CMD_OCU | CMD_LC; + cmd[4].src = NAND_READ_ID; + cmd[4].dst = paddr(&data[4]); + cmd[4].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf("status: %x\n", data[3]); +#endif + dprintf("nandid: %x maker %b device %b\n", + data[4], data[4] & 0xff, (data[4] >> 8) & 0xff); + + flash_maker = data[4] & 0xff; + flash_device = (data[4] >> 8) & 0xff; +} + +static int flash_erase_block(dmov_s *cmdlist, unsigned *ptrlist, unsigned page) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + unsigned *data = ptrlist + 4; + + /* only allow erasing on block boundaries */ + if(page & 63) return -1; + + data[0] = NAND_CMD_BLOCK_ERASE; + data[1] = page; + data[2] = 0; + data[3] = 0 | 4; + data[4] = 1; + data[5] = 0xeeeeeeee; + data[6] = CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */ + data[7] = CFG1; + + cmd[0].cmd = DST_CRCI_NAND_CMD | CMD_OCB; + cmd[0].src = paddr(&data[0]); + cmd[0].dst = NAND_FLASH_CMD; + cmd[0].len = 16; + + cmd[1].cmd = 0; + cmd[1].src = paddr(&data[6]); + cmd[1].dst = NAND_DEV0_CFG0; + cmd[1].len = 8; + + cmd[2].cmd = 0; + cmd[2].src = paddr(&data[4]); + cmd[2].dst = NAND_EXEC_CMD; + cmd[2].len = 4; + + cmd[3].cmd = SRC_CRCI_NAND_DATA | CMD_OCU | CMD_LC; + cmd[3].src = NAND_FLASH_STATUS; + cmd[3].dst = paddr(&data[5]); + cmd[3].len = 4; + + ptr[0] = (paddr(cmd) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf("status: %x\n", data[5]); +#endif + + /* we fail if there was an operation error, a mpu error, or the + ** erase success bit was not set. + */ + if(data[5] & 0x110) return -1; + if(!(data[5] & 0x80)) return -1; + + return 0; +} + +struct data_flash_io { + unsigned cmd; + unsigned addr0; + unsigned addr1; + unsigned chipsel; + unsigned cfg0; + unsigned cfg1; + unsigned exec; + unsigned ecc_cfg; + unsigned ecc_cfg_save; + struct { + unsigned flash_status; + unsigned buffer_status; + } result[4]; +}; + +static int _flash_read_page(dmov_s *cmdlist, unsigned *ptrlist, unsigned page, void *_addr, void *_spareaddr) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_flash_io *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned n; + + data->cmd = NAND_CMD_PAGE_READ_ECC; + data->addr0 = page << 16; + data->addr1 = (page >> 16) & 0xff; + data->chipsel = 0 | 4; /* flash0 + undoc bit */ + + /* GO bit for the EXEC register */ + data->exec = 1; + + data->cfg0 = CFG0; + data->cfg1 = CFG1; + + data->ecc_cfg = 0x203; + + /* save existing ecc config */ + cmd->cmd = CMD_OCB; + cmd->src = NAND_EBI2_ECC_BUF_CFG; + cmd->dst = paddr(&data->ecc_cfg_save); + cmd->len = 4; + cmd++; + + for(n = 0; n < 4; n++) { + /* write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NAND_FLASH_CMD; + cmd->len = ((n == 0) ? 16 : 4); + cmd++; + + if (n == 0) { + /* block on cmd ready, set configuration */ + cmd->cmd = 0; + cmd->src = paddr(&data->cfg0); + cmd->dst = NAND_DEV0_CFG0; + cmd->len = 8; + cmd++; + + /* set our ecc config */ + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + cmd++; + } + /* kick the execute register */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NAND_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* block on data ready, then read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_FLASH_STATUS; + cmd->dst = paddr(&data->result[n]); + cmd->len = 8; + cmd++; + + /* read data block */ + cmd->cmd = 0; + cmd->src = NAND_FLASH_BUFFER; + cmd->dst = addr + n * 516; + cmd->len = ((n < 3) ? 516 : 500); + cmd++; + } + + /* read extra data */ + cmd->cmd = 0; + cmd->src = NAND_FLASH_BUFFER + 500; + cmd->dst = spareaddr; + cmd->len = 16; + cmd++; + + /* restore saved ecc config */ + cmd->cmd = CMD_OCU | CMD_LC; + cmd->src = paddr(&data->ecc_cfg_save); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf("read page %d: status: %x %x %x %x\n", + page, data[5], data[6], data[7], data[8]); + for(n = 0; n < 4; n++) { + ptr = (unsigned*)(addr + 512 * n); + dprintf("data%d: %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + ptr = (unsigned*)(spareaddr + 16 * n); + dprintf("spare data%d %x %x %x %x\n", n, ptr[0], ptr[1], ptr[2], ptr[3]); + } +#endif + + /* if any of the writes failed (0x10), or there was a + ** protection violation (0x100), we lose + */ + for(n = 0; n < 4; n++) { + if (data->result[n].flash_status & 0x110) { + return -1; + } + } + + return 0; +} + +static int _flash_write_page(dmov_s *cmdlist, unsigned *ptrlist, unsigned page, + const void *_addr, const void *_spareaddr) +{ + dmov_s *cmd = cmdlist; + unsigned *ptr = ptrlist; + struct data_flash_io *data = (void*) (ptrlist + 4); + unsigned addr = (unsigned) _addr; + unsigned spareaddr = (unsigned) _spareaddr; + unsigned n; + + data->cmd = NAND_CMD_PRG_PAGE; + data->addr0 = page << 16; + data->addr1 = (page >> 16) & 0xff; + data->chipsel = 0 | 4; /* flash0 + undoc bit */ + + data->cfg0 = CFG0; + data->cfg1 = CFG1; + + /* GO bit for the EXEC register */ + data->exec = 1; + + data->ecc_cfg = 0x203; + + /* save existing ecc config */ + cmd->cmd = CMD_OCB; + cmd->src = NAND_EBI2_ECC_BUF_CFG; + cmd->dst = paddr(&data->ecc_cfg_save); + cmd->len = 4; + cmd++; + + for(n = 0; n < 4; n++) { + /* write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst */ + cmd->cmd = DST_CRCI_NAND_CMD; + cmd->src = paddr(&data->cmd); + cmd->dst = NAND_FLASH_CMD; + cmd->len = ((n == 0) ? 16 : 4); + cmd++; + + if (n == 0) { + /* set configuration */ + cmd->cmd = 0; + cmd->src = paddr(&data->cfg0); + cmd->dst = NAND_DEV0_CFG0; + cmd->len = 8; + cmd++; + + /* set our ecc config */ + cmd->cmd = 0; + cmd->src = paddr(&data->ecc_cfg); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + cmd++; + } + + /* write data block */ + cmd->cmd = 0; + cmd->src = addr + n * 516; + cmd->dst = NAND_FLASH_BUFFER; + cmd->len = ((n < 3) ? 516 : 510); + cmd++; + + if (n == 3) { + /* write extra data */ + cmd->cmd = 0; + cmd->src = spareaddr; + cmd->dst = NAND_FLASH_BUFFER + 500; + cmd->len = 16; + cmd++; + } + + /* kick the execute register */ + cmd->cmd = 0; + cmd->src = paddr(&data->exec); + cmd->dst = NAND_EXEC_CMD; + cmd->len = 4; + cmd++; + + /* block on data ready, then read the status register */ + cmd->cmd = SRC_CRCI_NAND_DATA; + cmd->src = NAND_FLASH_STATUS; + cmd->dst = paddr(&data->result[n]); + cmd->len = 8; + cmd++; + } + + /* restore saved ecc config */ + cmd->cmd = CMD_OCU | CMD_LC; + cmd->src = paddr(&data->ecc_cfg_save); + cmd->dst = NAND_EBI2_ECC_BUF_CFG; + cmd->len = 4; + + ptr[0] = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptr); + +#if VERBOSE + dprintf("write page %d: status: %x %x %x %x\n", + page, data[5], data[6], data[7], data[8]); +#endif + + /* if any of the writes failed (0x10), or there was a + ** protection violation (0x100), or the program success + ** bit (0x80) is unset, we lose + */ + for(n = 0; n < 4; n++) { + if(data->result[n].flash_status & 0x110) return -1; + if(!(data->result[n].flash_status & 0x80)) return -1; + } + + return 0; +} + +unsigned nand_cfg0; +unsigned nand_cfg1; + +static int flash_read_config(dmov_s *cmdlist, unsigned *ptrlist) +{ + cmdlist[0].cmd = CMD_OCB; + cmdlist[0].src = NAND_DEV0_CFG0; + cmdlist[0].dst = paddr(&CFG0); + cmdlist[0].len = 4; + + cmdlist[1].cmd = CMD_OCU | CMD_LC; + cmdlist[1].src = NAND_DEV0_CFG1; + cmdlist[1].dst = paddr(&CFG1); + cmdlist[1].len = 4; + + *ptrlist = (paddr(cmdlist) >> 3) | CMD_PTR_LP; + + dmov_exec_cmdptr(DMOV_NAND_CHAN, ptrlist); + + if((CFG0 == 0) || (CFG1 == 0)) { + return -1; + } + + dprintf("nandcfg: %x %x (initial)\n", CFG0, CFG1); + + CFG0 = (3 << 6) /* 4 codeword per page for 2k nand */ + | (516 << 9) /* 516 user data bytes */ + | (10 << 19) /* 10 parity bytes */ + | (5 << 27) /* 5 address cycles */ + | (1 << 30) /* Read status before data */ + | (1 << 31) /* Send read cmd */ + /* 0 spare bytes for 16 bit nand or 1 spare bytes for 8 bit */ + | ((nand_cfg1 & CFG1_WIDE_FLASH) ? (0 << 23) : (1 << 23)); + CFG1 = (0 << 0) /* Enable ecc */ + | (7 << 2) /* 8 recovery cycles */ + | (0 << 5) /* Allow CS deassertion */ + | (465 << 6) /* Bad block marker location */ + | (0 << 16) /* Bad block in user data area */ + | (2 << 17) /* 6 cycle tWB/tRB */ + | (nand_cfg1 & CFG1_WIDE_FLASH); /* preserve wide flash flag */ + + dprintf("nandcfg: %x %x (used)\n", CFG0, CFG1); + + return 0; +} + +static unsigned *flash_ptrlist; +static dmov_s *flash_cmdlist; +static void *flash_spare; +static void *flash_data; + +int flash_init(void) +{ + flash_ptrlist = alloc(1024); + flash_cmdlist = alloc(1024); + flash_data = alloc(2048); + flash_spare = alloc(64); + + if(flash_read_config(flash_cmdlist, flash_ptrlist)) { + dprintf("ERROR: could not read CFG0/CFG1 state\n"); + for(;;); + } + + flash_read_id(flash_cmdlist, flash_ptrlist); + + return 0; +} + +int flash_erase(ptentry *ptn) +{ + unsigned block = ptn->start; + unsigned count = ptn->length; + + while(count-- > 0) { + if(flash_erase_block(flash_cmdlist, flash_ptrlist, block * 64)) { + dprintf("cannot erase @ %d (bad block?)\n", block); + } + block++; + } + return 0; +} + +int flash_read_ext(ptentry *ptn, unsigned extra_per_page, unsigned offset, void *data, unsigned bytes) +{ + unsigned page = (ptn->start * 64) + (offset / 2048); + unsigned lastpage = (ptn->start + ptn->length) * 64; + unsigned count = (bytes + 2047 + extra_per_page) / (2048 + extra_per_page); + unsigned *spare = (unsigned*) flash_spare; + unsigned errors = 0; + unsigned char *image = data; + + if(offset & 2047) + return -1; + + while(page < lastpage) { + if(count == 0) { + dprintf("flash_read_image: success (%d errors)\n", errors); + return 0; + } + + if(_flash_read_page(flash_cmdlist, flash_ptrlist, page++, image, spare)) { + errors++; + continue; + } + image += 2048; + memcpy(image, spare, extra_per_page); + image += extra_per_page; + count -= 1; + } + + /* could not find enough valid pages before we hit the end */ + dprintf("flash_read_image: failed (%d errors)\n", errors); + return 0xffffffff; +} + +int flash_write(ptentry *ptn, unsigned extra_per_page, const void *data, unsigned bytes) +{ + unsigned page = ptn->start * 64; + unsigned lastpage = (ptn->start + ptn->length) * 64; + unsigned *spare = (unsigned*) flash_spare; + const unsigned char *image = data; + unsigned wsize = 2048 + extra_per_page; + unsigned n; + int r; + + for(n = 0; n < 16; n++) spare[n] = 0xffffffff; + + while(bytes > 0) { + if(bytes < wsize) { + dprintf("flash_write_image: image undersized (%d < %d)\n", bytes, wsize); + return -1; + } + if(page >= lastpage) { + dprintf("flash_write_image: out of space\n"); + return -1; + } + + if((page & 63) == 0) { + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf("flash_write_image: bad block @ %d\n", page >> 6); + page += 64; + continue; + } + } + + if(extra_per_page) { + r = _flash_write_page(flash_cmdlist, flash_ptrlist, page++, image, image + 2048); + } else { + r = _flash_write_page(flash_cmdlist, flash_ptrlist, page++, image, spare); + } + if(r) { + dprintf("flash_write_image: write failure @ page %d (src %d)\n", page, image - (const unsigned char *)data); + image -= (page & 63) * wsize; + bytes += (page & 63) * wsize; + page &= ~63; + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf("flash_write_image: erase failure @ page %d\n", page); + } + dprintf("flash_write_image: restart write @ page %d (src %d)\n", page, image - (const unsigned char *)data); + page += 64; + continue; + } + + image += wsize; + bytes -= wsize; + } + + /* erase any remaining pages in the partition */ + page = (page + 63) & (~63); + while(page < lastpage){ + if(flash_erase_block(flash_cmdlist, flash_ptrlist, page)) { + dprintf("flash_write_image: bad block @ %d\n", page >> 6); + } + page += 64; + } + + dprintf("flash_write_image: success\n"); + return 0; +} + +static int flash_read_page(unsigned page, void *data, void *extra) +{ + return _flash_read_page(flash_cmdlist, flash_ptrlist, + page, data, extra); +} + diff --git a/arch_msm7k/shared.c b/arch_msm7k/shared.c new file mode 100644 index 0000000..0ae8cd4 --- /dev/null +++ b/arch_msm7k/shared.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <msm7k/shared.h> + +static void get_version(char *s, unsigned id) +{ + unsigned *ver = (unsigned*) MSM7K_VERSION; + unsigned n = ver[id]; + + snprintf(s, 32, "%d.%d", n >> 16, n & 0xffff); +} + +void get_version_modem(char *s) +{ + get_version(s, VERSION_MODEM); +} + +void get_version_modem_sbl(char *s) +{ + get_version(s, VERSION_MODEM_SBL); +} + +#define MSM_CSR_BASE 0xC0100000 + +#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) + +static inline void notify_other_proc_comm(void) +{ + writel(1, MSM_A2M_INT(6)); +} + +#define APP_COMMAND (MSM7K_SHARED_PHYS + 0x00) +#define APP_STATUS (MSM7K_SHARED_PHYS + 0x04) +#define APP_DATA1 (MSM7K_SHARED_PHYS + 0x08) +#define APP_DATA2 (MSM7K_SHARED_PHYS + 0x0C) + +#define MDM_COMMAND (MSM7K_SHARED_PHYS + 0x10) +#define MDM_STATUS (MSM7K_SHARED_PHYS + 0x14) +#define MDM_DATA1 (MSM7K_SHARED_PHYS + 0x18) +#define MDM_DATA2 (MSM7K_SHARED_PHYS + 0x1C) + + +enum +{ + PCOM_CMD_IDLE = 0x0, + PCOM_CMD_DONE, + PCOM_RESET_APPS, + PCOM_RESET_CHIP, + PCOM_CONFIG_NAND_MPU, + PCOM_CONFIG_USB_CLKS, + PCOM_GET_POWER_ON_STATUS, + PCOM_GET_WAKE_UP_STATUS, + PCOM_GET_BATT_LEVEL, + PCOM_CHG_IS_CHARGING, + PCOM_POWER_DOWN, + PCOM_USB_PIN_CONFIG, + PCOM_USB_PIN_SEL, + PCOM_SET_RTC_ALARM, + PCOM_NV_READ, + PCOM_NV_WRITE, + PCOM_GET_UUID_HIGH, + PCOM_GET_UUID_LOW, + PCOM_GET_HW_ENTROPY, + PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE, + PCOM_CLKCTL_RPC_ENABLE, + PCOM_CLKCTL_RPC_DISABLE, + PCOM_CLKCTL_RPC_RESET, + PCOM_CLKCTL_RPC_SET_FLAGS, + PCOM_CLKCTL_RPC_SET_RATE, + PCOM_CLKCTL_RPC_MIN_RATE, + PCOM_CLKCTL_RPC_MAX_RATE, + PCOM_CLKCTL_RPC_RATE, + PCOM_CLKCTL_RPC_PLL_REQUEST, + PCOM_CLKCTL_RPC_ENABLED, + PCOM_VREG_SWITCH, + PCOM_VREG_SET_LEVEL, + PCOM_GPIO_TLMM_CONFIG_GROUP, + PCOM_GPIO_TLMM_UNCONFIG_GROUP, + PCOM_NV_READ_HIGH_BITS, + PCOM_NV_WRITE_HIGH_BITS, + PCOM_NUM_CMDS, +}; + +enum +{ + PCOM_INVALID_STATUS = 0x0, + PCOM_READY, + PCOM_CMD_RUNNING, + PCOM_CMD_SUCCESS, + PCOM_CMD_FAIL, +}; + +int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) +{ + int ret = -1; + + while (readl(MDM_STATUS) != PCOM_READY) { + /* XXX check for A9 reset */ + } + + writel(cmd, APP_COMMAND); + if (data1) + writel(*data1, APP_DATA1); + if (data2) + writel(*data2, APP_DATA2); + + notify_other_proc_comm(); + while (readl(APP_COMMAND) != PCOM_CMD_DONE) { + /* XXX check for A9 reset */ + } + + if (readl(APP_STATUS) != PCOM_CMD_FAIL) { + if (data1) + *data1 = readl(APP_DATA1); + if (data2) + *data2 = readl(APP_DATA2); + ret = 0; + } + + return ret; +} + +int clock_enable(unsigned id) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, 0); +} + +int clock_disable(unsigned id) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, 0); +} + +int clock_set_rate(unsigned id, unsigned rate) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); +} + +int clock_get_rate(unsigned id) +{ + if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, 0)) { + return -1; + } else { + return (int) id; + } +} + +void reboot(void) +{ + msm_proc_comm(PCOM_RESET_CHIP, 0, 0); + for (;;) ; +} + +int vreg_enable(unsigned id) +{ + unsigned n = 1; + return msm_proc_comm(PCOM_VREG_SWITCH, &id, &n); +} + +int vreg_disable(unsigned id) +{ + unsigned n = 0; + return msm_proc_comm(PCOM_VREG_SWITCH, &id, &n); +} + +int vreg_set_level(unsigned id, unsigned level) +{ + return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &level); +} + + diff --git a/arch_msm7k/smem.c b/arch_msm7k/smem.c new file mode 100644 index 0000000..c7d0c9b --- /dev/null +++ b/arch_msm7k/smem.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +struct smem_heap_info +{ + unsigned initialized; + unsigned free_offset; + unsigned heap_remaining; + unsigned reserved; +}; + +struct smem_heap_entry +{ + unsigned allocated; + unsigned offset; + unsigned size; + unsigned reserved; +}; + +struct smem_proc_comm +{ + unsigned command; + unsigned status; + unsigned data1; + unsigned data2; +}; + +struct smem_shared +{ + struct smem_proc_comm proc_comm[4]; + unsigned version[32]; + struct smem_heap_info heap_info; + struct smem_heap_entry heap_toc[128]; +}; + +struct smsm_shared +{ + unsigned host; + unsigned state; +}; + +#define SZ_DIAG_ERR_MSG 0xC8 +#define ID_DIAG_ERR_MSG 6 +#define ID_HEAP_INFO 3 +#define ID_SMD_CHANNELS 13 +#define ID_SHARED_STATE 82 + + +void dump_smem_info(void) +{ + unsigned n; + struct smem_heap_entry *he; + struct smem_shared *shared = (void*) 0x01f00000; + dprintf("--- smem info ---\n"); + + dprintf("heap: init=%x free=%x remain=%x\n", + shared->heap_info.initialized, + shared->heap_info.free_offset, + shared->heap_info.heap_remaining); + + he = shared->heap_toc; + for(n = 0; n < 128; n++) { + if(he->allocated) { + dprintf("%x: alloc=%x offset=%x size=%x\n", + n, he->allocated, he->offset, he->size); + } + he++; + } +} diff --git a/arch_msm7k/uart.c b/arch_msm7k/uart.c new file mode 100644 index 0000000..a7be074 --- /dev/null +++ b/arch_msm7k/uart.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/uart.h> +#include <msm7k/uart.h> + +static unsigned uart_base = MSM_UART1_BASE; + +#define uwr(v,a) writel(v, uart_base + (a)) +#define urd(a) readl(uart_base + (a)) + +#define UART_NEED_INIT 1 + +void uart_init(unsigned n) +{ + + switch(n) { + case 0: + uart_base = MSM_UART1_BASE; + break; + case 1: + uart_base = MSM_UART2_BASE; + break; + case 2: + uart_base = MSM_UART3_BASE; + break; + } + +#if UART_NEED_INIT + uwr(0x0A, UART_CR); /* disable TX and RX */ + + uwr(0x30, UART_CR); /* reset error status */ + uwr(0x10, UART_CR); /* reset receiver */ + uwr(0x20, UART_CR); /* reset transmitter */ + + mdelay(100); + + /* configuration for 19.2MHz TCXO */ + uwr(0xC0, UART_MREG); + uwr(0xAF, UART_NREG); + uwr(0x80, UART_DREG); + uwr(0x19, UART_MNDREG); + + uwr(0x10, UART_CR); /* reset RX */ + uwr(0x20, UART_CR); /* reset TX */ + uwr(0x30, UART_CR); /* reset error status */ + uwr(0x40, UART_CR); /* reset RX break */ + uwr(0x70, UART_CR); /* rest? */ + uwr(0xD0, UART_CR); /* reset */ + + uwr(0x7BF, UART_IPR); /* stale timeout = 630 * bitrate */ + uwr(0, UART_IMR); + uwr(115, UART_RFWR); /* RX watermark = 58 * 2 - 1 */ + uwr(10, UART_TFWR); /* TX watermark */ + + uwr(0, UART_RFWR); + + uwr(UART_CSR_115200, UART_CSR); + uwr(0, UART_IRDA); + uwr(0x1E, UART_HCR); +// uwr(0x7F4, UART_MR1); /* RFS/ CTS/ 500chr RFR */ + uwr(16, UART_MR1); + uwr(0x34, UART_MR2); /* 8N1 */ + + mdelay(100); + + uwr(0x05, UART_CR); /* enable TX & RX */ + mdelay(100); +#endif +} + +int uart_getc(void) +{ + if(!(urd(UART_SR) & UART_SR_RX_READY)) + return -1; + return urd(UART_RF); +} + +void uart_putc(unsigned c) +{ + while(!(urd(UART_SR) & UART_SR_TX_READY)) ; + uwr(c, UART_TF); +} + +int uart_tx_ready(void) +{ + return urd(UART_SR) & UART_SR_TX_READY; +} + + +void uart_puts(const char *s) +{ + while(*s) { + if(*s == '\n') uart_putc('\r'); + uart_putc(*s++); + } +} + diff --git a/arch_msm7k/vic.c b/arch_msm7k/vic.c new file mode 100644 index 0000000..a0b820f --- /dev/null +++ b/arch_msm7k/vic.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <msm7k/vic.h> +#include <msm7k/irqs.h> + +extern irq_handler irq_vector_table[NR_IRQS]; + +void unknown_handler(unsigned n) +{ + dprintf("unsolicited irq #%d\n", n); + for(;;); +} + +void irq_init(void) +{ + unsigned n; + + for(n = 0; n < NR_IRQS; n++) { + irq_vector_table[n] = unknown_handler; + } + /* select level interrupts */ + writel(0, VIC_INT_TYPE0); + writel(0, VIC_INT_TYPE1); + + /* select IRQ for all INTs */ + writel(0, VIC_INT_SELECT0); + writel(0, VIC_INT_SELECT1); + + /* clear interrupts */ + writel(0xffffffff, VIC_INT_CLEAR0); + writel(0xffffffff, VIC_INT_CLEAR1); + + /* disable all INTs */ + writel(0, VIC_INT_EN0); + writel(0, VIC_INT_EN1); + + /* don't use 1136 vic */ + writel(0, VIC_CONFIG); + + writel(1, VIC_INT_MASTEREN); + + /* enable IRQs */ + enable_irq(); + + (void) readl(VIC_IRQ_VEC_RD); +} + +void irq_unmask(unsigned n) +{ + unsigned reg, bit; + + reg = n > 31 ? VIC_INT_EN1 : VIC_INT_EN0; + bit = 1 << (n & 31); + + writel(readl(reg) | bit, reg); +} + +void irq_mask(unsigned n) +{ + unsigned reg, bit; + + reg = n > 31 ? VIC_INT_ENCLEAR1 : VIC_INT_ENCLEAR0; + bit = 1 << (n & 31); + + writel(bit, reg); +} + +void irq_install(unsigned n, irq_handler func, int edge) +{ + unsigned reg, bit, tmp; + + reg = n > 31 ? VIC_INT_TYPE1 : VIC_INT_TYPE0; + bit = 1 << (n & 31); + + tmp = readl(reg); + if(edge) { + writel(tmp | bit, reg); + } else { + writel(tmp & (~bit), reg); + } + + irq_vector_table[n] = func; +} + diff --git a/fastboot_protocol.txt b/fastboot_protocol.txt new file mode 100644 index 0000000..2248992 --- /dev/null +++ b/fastboot_protocol.txt @@ -0,0 +1,173 @@ + +FastBoot Version 0.4 +---------------------- + +The fastboot protocol is a mechanism for communicating with bootloaders +over USB. It is designed to be very straightforward to implement, to +allow it to be used across a wide range of devices and from hosts running +Linux, Windows, or OSX. + + +Basic Requirements +------------------ + +* Two bulk endpoints (in, out) are required +* Max packet size must be 64 bytes for full-speed and 512 bytes for + high-speed USB +* The protocol is entirely host-driven and synchronous (unlike the + multi-channel, bi-directional, asynchronous ADB protocol) + + +Transport and Framing +--------------------- + +1. Host sends a command, which is an ascii string in a single + packet no greater than 64 bytes. + +2. Client response with a single packet no greater than 64 bytes. + The first four bytes of the response are "OKAY", "FAIL", "DATA", + or "INFO". Additional bytes may contain an (ascii) informative + message. + + a. INFO -> the remaining 60 bytes are an informative message + (providing progress or diagnostic messages). They should + be displayed and then step #2 repeats + + b. FAIL -> the requested command failed. The remaining 60 bytes + of the response (if present) provide a textual failure message + to present to the user. Stop. + + c. OKAY -> the requested command completed successfully. Go to #5 + + d. DATA -> the requested command is ready for the data phase. + A DATA response packet will be 12 bytes long, in the form of + DATA00000000 where the 8 digit hexidecimal number represents + the total data size to transfer. + +3. Data phase. Depending on the command, the host or client will + send the indicated amount of data. Short packets are always + acceptable and zero-length packets are ignored. This phase continues + until the client has sent or received the number of bytes indicated + in the "DATA" response above. + +4. Client responds with a single packet no greater than 64 bytes. + The first four bytes of the response are "OKAY", "FAIL", or "INFO". + Similar to #2: + + a. INFO -> display the remaining 60 bytes and return to #4 + + b. FAIL -> display the remaining 60 bytes (if present) as a failure + reason and consider the command failed. Stop. + + c. OKAY -> success. Go to #5 + +5. Success. Stop. + + +Example Session +--------------- + +Host: "getvar:version" request version variable + +Client: "OKAY0.4" return version "0.4" + +Host: "getvar:nonexistant" request some undefined variable + +Client: "OKAY" return value "" + +Host: "download:00001234" request to send 0x1234 bytes of data + +Client: "DATA00001234" ready to accept data + +Host: < 0x1234 bytes > send data + +Client: "OKAY" success + +Host: "flash:bootloader" request to flash the data to the bootloader + +Client: "INFOerasing flash" indicate status / progress + "INFOwriting flash" + "OKAY" indicate success + +Host: "powerdown" send a command + +Client: "FAILunknown command" indicate failure + + +Command Reference +----------------- + +* Command parameters are indicated by printf-style escape sequences. + +* Commands are ascii strings and sent without the quotes (which are + for illustration only here) and without a trailing 0 byte. + +* Commands that begin with a lowercase letter are reserved for this + specification. OEM-specific commands should not begin with a + lowercase letter, to prevent incompatibilities with future specs. + + "getvar:%s" Read a config/version variable from the bootloader. + The variable contents will be returned after the + OKAY response. + + "download:%08x" Write data to memory which will be later used + by "boot", "ramdisk", "flash", etc. The client + will reply with "DATA%08x" if it has enough + space in RAM or "FAIL" if not. The size of + the download is remembered. + + "verify:%08x" Send a digital signature to verify the downloaded + data. Required if the bootloader is "secure" + otherwise "flash" and "boot" will be ignored. + + "flash:%s" Write the previously downloaded image to the + named partition (if possible). + + "erase:%s" Erase the indicated partition (clear to 0xFFs) + + "boot" The previously downloaded data is a boot.img + and should be booted according to the normal + procedure for a boot.img + + "continue" Continue booting as normal (if possible) + + "reboot" Reboot the device. + + "reboot-bootloader" Reboot back into the bootloader. + Useful for upgrade processes that require upgrading + the bootloader and then upgrading other partitions + using the new bootloader. + + "powerdown" Power off the device. + + + +Client Variables +---------------- + +The "getvar:%s" command is used to read client variables which +represent various information about the device and the software +on it. + +The various currently defined names are: + + version Version of FastBoot protocol supported. + It should be "0.3" for this document. + + version-bootloader Version string for the Bootloader. + + version-baseband Version string of the Baseband Software + + product Name of the product + + serialno Product serial number + + secure If the value is "yes", this is a secure + bootloader requiring a signature before + it will install or boot images. + +Names starting with a lowercase character are reserved by this +specification. OEM-specific names should not start with lowercase +characters. + + diff --git a/include/boot/arm.h b/include/boot/arm.h new file mode 100644 index 0000000..13b64f2 --- /dev/null +++ b/include/boot/arm.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ARM_H +#define _ARM_H + +#define PSR_N 0x80000000 +#define PSR_C 0x40000000 +#define PSR_Z 0x20000000 +#define PSR_V 0x10000000 + +#define PSR_I 0x00000080 +#define PSR_F 0x00000040 +#define PSR_T 0x00000020 + +#define PSR_MODE_MASK 0x0000001F +#define PSR_USR 0x00000010 +#define PSR_FIQ 0x00000011 +#define PSR_IRQ 0x00000012 +#define PSR_SVC 0x00000013 +#define PSR_ABT 0x00000017 +#define PSR_UND 0x0000001B +#define PSR_SYS 0x0000001F + +#endif diff --git a/include/boot/board.h b/include/boot/board.h new file mode 100644 index 0000000..19b5c5e --- /dev/null +++ b/include/boot/board.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/* low-level init and partition table setup */ +void board_init(void); +void board_reboot(void); +void board_getvar(const char *name, char *value); + +/* keypad init */ +void keypad_init(void); + +/* return a linux kernel commandline */ +const char *board_cmdline(void); +unsigned board_machtype(void); + +/* lcd panel initialization */ +struct mddi_client_caps; + +void panel_poweron(void); +void panel_init(struct mddi_client_caps *caps); +void panel_backlight(int on); + +#endif diff --git a/include/boot/boot.h b/include/boot/boot.h new file mode 100644 index 0000000..d4a4d64 --- /dev/null +++ b/include/boot/boot.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _BOOT_H_ +#define _BOOT_H_ + +static inline void DWB(void) /* drain write buffer */ +{ + asm volatile ( + "mcr p15, 0, %0, c7, c10, 4\n" : : "r" (0) + ); +} + +static inline void writel(unsigned val, unsigned addr) +{ + DWB(); + (*(volatile unsigned *) (addr)) = (val); + DWB(); +} + +static inline void writeb(unsigned val, unsigned addr) +{ + DWB(); + (*(volatile unsigned char *) (addr)) = (val); + DWB(); +} + +static inline unsigned readl(unsigned addr) +{ + return (*(volatile unsigned *) (addr)); +} + +int dcc_putc(unsigned c); +int dcc_getc(); + +void enable_irq(void); + +/* main.c */ +enum boot_keys { + BOOT_KEY_STOP_BOOT = 1, + BOOT_KEY_CONTINUE_BOOT = 2, +}; +extern void key_changed(unsigned int key, unsigned int is_down) __attribute__ ((weak)); + +/* manage a list of functions to call */ +void boot_register_poll_func(void (*func)(void)); +void boot_poll(void); + +/* console.c */ +void dcc_init(); + +void dprintf(const char *fmt, ...); +void dprintf_set_putc(void (*func)(unsigned)); +void dprintf_set_flush(void (*func)(void)); + +/* gpio */ +void gpio_output_enable(unsigned n, unsigned out); +void gpio_write(unsigned n, unsigned on); +int gpio_read(unsigned n); + +/* misc.c */ +void *alloc(unsigned sz); /* alloc 32byte aligned memory */ +void *alloc_page_aligned(unsigned sz); + +void *memcpy(void *dst, const void *src, unsigned len); +void *memset(void *dst, unsigned val, unsigned len); +char *strcpy(char *dst, const char *src); +int strcmp(const char *s1, const char *s2); +int memcmp(const void *a, const void *b, unsigned len); +char *strstr(const char *s1, const char *s2); +int strlen(const char *s); + +/* clock */ +unsigned cycles_per_second(void); +void print_cpu_speed(void); +void arm11_clock_init(void); +void mdelay(unsigned msecs); +void udelay(unsigned usecs); + +/* LCD */ +void console_init(void); +void console_set_colors(unsigned bg, unsigned fg); +void console_clear(void); +void console_putc(unsigned n); +void console_flush(void); + +void cprintf(const char *fmt, ...); + +void mddi_init(void); +void mddi_start_update(void); +int mddi_update_done(void); +void *mddi_framebuffer(void); +void mddi_remote_write(unsigned val, unsigned reg); +extern unsigned fb_width; +extern unsigned fb_height; + +/* provided by board files */ +void set_led(int on); + +/* provided by jtag.c */ +void jtag_okay(const char *msg); +void jtag_fail(const char *msg); +void jtag_dputc(unsigned ch); +void jtag_cmd_loop(void (*do_cmd)(const char *, unsigned, unsigned, unsigned)); + +typedef void (*irq_handler)(unsigned n); + + +#define DIGEST_SIZE 20 +#define SIGNATURE_SIZE 256 + +void compute_digest(void *data, unsigned len, void *digest_out); +int is_signature_okay(void *digest, void *signature, void *pubkey); + +#if 0 +#define __attr_used __attribute__((used)) +#define __attr_init __attribute__((__section__(".init.func.0"))) +#define boot_init_hook(func) \ +static int (*__boot_init_hook__)(void) __attr_used __attr_init = func +#endif + +#endif diff --git a/include/boot/bootimg.h b/include/boot/bootimg.h new file mode 100644 index 0000000..44fde92 --- /dev/null +++ b/include/boot/bootimg.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _BOOT_IMAGE_H_ +#define _BOOT_IMAGE_H_ + +typedef struct boot_img_hdr boot_img_hdr; + +#define BOOT_MAGIC "ANDROID!" +#define BOOT_MAGIC_SIZE 8 +#define BOOT_NAME_SIZE 16 +#define BOOT_ARGS_SIZE 512 + +struct boot_img_hdr +{ + unsigned char magic[BOOT_MAGIC_SIZE]; + + unsigned kernel_size; /* size in bytes */ + unsigned kernel_addr; /* physical load addr */ + + unsigned ramdisk_size; /* size in bytes */ + unsigned ramdisk_addr; /* physical load addr */ + + unsigned second_size; /* size in bytes */ + unsigned second_addr; /* physical load addr */ + + unsigned tags_addr; /* physical addr for kernel tags */ + unsigned page_size; /* flash page size we assume */ + unsigned unused[2]; /* future expansion: should be 0 */ + + unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */ + + unsigned char cmdline[BOOT_ARGS_SIZE]; + + unsigned id[8]; /* timestamp / checksum / sha1 / etc */ +}; + +/* +** +-----------------+ +** | boot header | 1 page +** +-----------------+ +** | kernel | n pages +** +-----------------+ +** | ramdisk | m pages +** +-----------------+ +** | second stage | o pages +** +-----------------+ +** +** n = (kernel_size + page_size - 1) / page_size +** m = (ramdisk_size + page_size - 1) / page_size +** o = (second_size + page_size - 1) / page_size +** +** 0. all entities are page_size aligned in flash +** 1. kernel and ramdisk are required (size != 0) +** 2. second is optional (second_size == 0 -> no second) +** 3. load each element (kernel, ramdisk, second) at +** the specified physical address (kernel_addr, etc) +** 4. prepare tags at tag_addr. kernel_args[] is +** appended to the kernel commandline in the tags. +** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr +** 6. if second_size != 0: jump to second_addr +** else: jump to kernel_addr +*/ + +boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, + void *ramdisk, unsigned ramdisk_size, + void *second, unsigned second_size, + unsigned page_size, + unsigned *bootimg_size); + +void bootimg_set_cmdline(boot_img_hdr *hdr, const char *cmdline); +#endif diff --git a/include/boot/flash.h b/include/boot/flash.h new file mode 100644 index 0000000..c746415 --- /dev/null +++ b/include/boot/flash.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _INCLUDE_BOOT_FLASH_H_ +#define _INCLUDE_BOOT_FLASH_H_ + +typedef struct flash_ops flash_ops; +typedef struct ptentry ptentry; + +/* flash partitions are defined in terms of blocks +** (flash erase units) +*/ +struct ptentry +{ + char name[16]; + unsigned start; + unsigned length; + unsigned flags; +}; + +/* tools to populate and query the partition table */ +void flash_add_ptn(ptentry *ptn); +ptentry *flash_find_ptn(const char *name); +ptentry *flash_get_ptn(unsigned n); +unsigned flash_get_ptn_count(void); +void flash_dump_ptn(void); + +int flash_init(void); +int flash_erase(ptentry *ptn); +int flash_read_ext(ptentry *ptn, unsigned extra_per_page, unsigned offset, + void *data, unsigned bytes); +#define flash_read(ptn, offset, data, bytes) flash_read_ext(ptn, 0, offset, data, bytes) +int flash_write(ptentry *ptn, unsigned extra_per_page, + const void *data, unsigned bytes); +#endif diff --git a/include/boot/font5x12.h b/include/boot/font5x12.h new file mode 100644 index 0000000..e033bf6 --- /dev/null +++ b/include/boot/font5x12.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +unsigned font5x12[] = { + 0x00000000, 0x00000000, + 0x08421080, 0x00020084, + 0x00052940, 0x00000000, + 0x15f52800, 0x0000295f, + 0x1c52f880, 0x00023e94, + 0x08855640, 0x0004d542, + 0x04528800, 0x000b2725, + 0x00021080, 0x00000000, + 0x04211088, 0x00821042, + 0x10841082, 0x00221108, + 0x09575480, 0x00000000, + 0x3e420000, 0x00000084, + 0x00000000, 0x00223000, + 0x3e000000, 0x00000000, + 0x00000000, 0x00471000, + 0x08844200, 0x00008442, + 0x2318a880, 0x00022a31, + 0x08429880, 0x000f9084, + 0x1108c5c0, 0x000f8444, + 0x1c4443e0, 0x00074610, + 0x14a62100, 0x000423e9, + 0x26d087e0, 0x00074610, + 0x1e10c5c0, 0x00074631, + 0x088443e0, 0x00010844, + 0x1d18c5c0, 0x00074631, + 0x3d18c5c0, 0x00074610, + 0x08e20000, 0x00471000, + 0x08e20000, 0x00223000, + 0x02222200, 0x00082082, + 0x01f00000, 0x000003e0, + 0x20820820, 0x00008888, + 0x1108c5c0, 0x00020084, + 0x2b98c5c0, 0x000f05b5, + 0x2318a880, 0x0008c63f, + 0x1d2949e0, 0x0007ca52, + 0x0210c5c0, 0x00074421, + 0x252949e0, 0x0007ca52, + 0x1e1087e0, 0x000f8421, + 0x1e1087e0, 0x00008421, + 0x0210c5c0, 0x00074639, + 0x3f18c620, 0x0008c631, + 0x084211c0, 0x00071084, + 0x10842380, 0x00032508, + 0x0654c620, 0x0008c525, + 0x02108420, 0x000f8421, + 0x2b5dc620, 0x0008c631, + 0x2b59ce20, 0x0008c739, + 0x2318c5c0, 0x00074631, + 0x1f18c5e0, 0x00008421, + 0x2318c5c0, 0x01075631, + 0x1f18c5e0, 0x0008c525, + 0x1c10c5c0, 0x00074610, + 0x084213e0, 0x00021084, + 0x2318c620, 0x00074631, + 0x1518c620, 0x0002114a, + 0x2b18c620, 0x000556b5, + 0x08a54620, 0x0008c54a, + 0x08a54620, 0x00021084, + 0x088443e0, 0x000f8442, + 0x0421084e, 0x00e10842, + 0x08210420, 0x00084108, + 0x1084210e, 0x00e42108, + 0x0008a880, 0x00000000, + 0x00000000, 0x01f00000, + 0x00000104, 0x00000000, + 0x20e00000, 0x000b663e, + 0x22f08420, 0x0007c631, + 0x22e00000, 0x00074421, + 0x23e84200, 0x000f4631, + 0x22e00000, 0x0007443f, + 0x1e214980, 0x00010842, + 0x22e00000, 0x1d187a31, + 0x26d08420, 0x0008c631, + 0x08601000, 0x00071084, + 0x10c02000, 0x0c94a108, + 0x0a908420, 0x0008a4a3, + 0x084210c0, 0x00071084, + 0x2ab00000, 0x0008d6b5, + 0x26d00000, 0x0008c631, + 0x22e00000, 0x00074631, + 0x22f00000, 0x0210be31, + 0x23e00000, 0x21087a31, + 0x26d00000, 0x00008421, + 0x22e00000, 0x00074506, + 0x04f10800, 0x00064842, + 0x23100000, 0x000b6631, + 0x23100000, 0x00022951, + 0x23100000, 0x000556b5, + 0x15100000, 0x0008a884, + 0x23100000, 0x1d185b31, + 0x11f00000, 0x000f8444, + 0x06421098, 0x01821084, + 0x08421080, 0x00021084, + 0x30421083, 0x00321084, + 0x0004d640, 0x00000000, + 0x00000000, 0x00000000, +}; diff --git a/include/boot/gpio.h b/include/boot/gpio.h new file mode 100644 index 0000000..78db64b --- /dev/null +++ b/include/boot/gpio.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _GPIO_H_ +#define _GPIO_H_ + +void gpio_dir(int nr, int out); +void gpio_set(int nr, int set); +int gpio_get(int nr); + +#endif diff --git a/include/boot/gpio_keypad.h b/include/boot/gpio_keypad.h new file mode 100644 index 0000000..11edf45 --- /dev/null +++ b/include/boot/gpio_keypad.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _GPIO_KEYPAD_H_ +#define _GPIO_KEYPAD_H_ + +typedef struct { + unsigned int *input_gpios; + unsigned int *output_gpios; + unsigned int ninputs; + unsigned int noutputs; + unsigned int *key_map; + unsigned int settle_time; // micro seconds to wait before reading inputs after driving each output + int polarity : 1; // 0: drive active column low, 1: drive active column high + int drive_inactive_outputs : 1; + unsigned long long state; +} gpio_keypad_info; + +int gpio_keypad_init(gpio_keypad_info *keypad); +void gpio_keypad_scan_keys(gpio_keypad_info *keypad); + +#endif diff --git a/include/boot/tags.h b/include/boot/tags.h new file mode 100644 index 0000000..1fc0237 --- /dev/null +++ b/include/boot/tags.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _INCLUDE_BOOT_TAGS_H_ +#define _INCLUDE_BOOT_TAGS_H_ + +/* tools to deal with Linux ARM boot tags */ + +struct tag_handler +{ + unsigned type; + void (*func)(unsigned type, void *data, unsigned bytes, void *cookie); + void *cookie; +}; + +void tags_parse(void *tags, struct tag_handler *h, unsigned count); + +/* convenience function */ +void tags_import_partitions(void *tags); +unsigned tags_get_revision(void *tags); +void tags_get_serialno(void *tags, void *sn); /* sn is 64bits */ +const char *tags_get_cmdline(void *tags); +#endif diff --git a/include/boot/uart.h b/include/boot/uart.h new file mode 100644 index 0000000..90a8a67 --- /dev/null +++ b/include/boot/uart.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _INCLUDE_BOOT_UART_H_ +#define _INCLUDE_BOOT_UART_H_ + +void uart_init(unsigned uart_number); + +void uart_putc(unsigned); +int uart_tx_ready(void); + +/* returns -1 if no character available, otherwise 0x00-0xff */ +int uart_getc(void); + +#endif diff --git a/include/boot/usb.h b/include/boot/usb.h new file mode 100644 index 0000000..73637c2 --- /dev/null +++ b/include/boot/usb.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _USB_COMMON_DEFINES_H +#define _USB_COMMON_DEFINES_H + +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +#define SET_FEATURE 3 +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define SET_DESCRIPTOR 7 +#define GET_CONFIGURATION 8 +#define SET_CONFIGURATION 9 +#define GET_INTERFACE 10 +#define SET_INTERFACE 11 +#define SYNCH_FRAME 12 + +#define TYPE_DEVICE 1 +#define TYPE_CONFIGURATION 2 +#define TYPE_STRING 3 +#define TYPE_INTERFACE 4 +#define TYPE_ENDPOINT 5 + +#define DEVICE_READ 0x80 +#define DEVICE_WRITE 0x00 +#define INTERFACE_READ 0x81 +#define INTERFACE_WRITE 0x01 +#define ENDPOINT_READ 0x82 +#define ENDPOINT_WRITE 0x02 + +typedef struct +{ + unsigned char type; + unsigned char request; + unsigned short value; + unsigned short index; + unsigned short length; +} __attribute__ ((packed)) setup_packet; + + +struct usb_request +{ + struct ept_queue_item *item; + + void *buf; + unsigned length; + + void (*complete)(struct usb_request *req, unsigned actual, int status); + void *context; +}; + +struct usb_request *usb_request_alloc(); +struct usb_endpoint *usb_endpoint_alloc(unsigned num, unsigned in, unsigned maxpkt); +int usb_queue_req(struct usb_endpoint *ept, struct usb_request *req); + +void usb_init(void); +void usb_shutdown(void); +void usb_poll(void); + +/* called to indicate online/offline status */ +void usb_status(unsigned online, unsigned highspeed); + +#endif diff --git a/include/boot/usb_descriptors.h b/include/boot/usb_descriptors.h new file mode 100644 index 0000000..434fcab --- /dev/null +++ b/include/boot/usb_descriptors.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +static unsigned short manufacturer_string[] = { + (TYPE_STRING << 8) | (12 * 2), + 'G', 'o', 'o', 'g', 'l', 'e', ',', ' ', 'I', 'n', 'c', +}; + +static unsigned short product_string[] = { + (TYPE_STRING << 8) | (12 * 2), + 'A', 'n', 'd', 'r', 'o', 'i', 'd', ' ', '1', '.', '0', +}; + +static unsigned short default_string[] = { + (TYPE_STRING << 8) | (8 * 2), + 'd', 'e', 'f', 'a', 'u', 'l', 't', +}; + +static unsigned short language_table[] = { + (TYPE_STRING << 8) | 4, + 0x0409, // LANGID for US English +}; + +static unsigned char device_desc[] = { + 18, // length + TYPE_DEVICE, // type + 0x10, 0x02, // usb spec rev 1.00 + 0x00, // class + 0x00, // subclass + 0x00, // protocol + 0x40, // max packet size + 0xD1, 0x18, // vendor id + 0x0D, 0xD0, // product id + 0x00, 0x01, // version 1.0 + 0x01, // manufacturer str idx + 0x02, // product str idx + 0x00, // serial number index + 0x01, // number of configs, +}; + +static unsigned char config_desc[] = { + 0x09, // length + TYPE_CONFIGURATION, + 0x20, 0x00, // total length + 0x01, // # interfaces + 0x01, // config value + 0x00, // config string + 0x80, // attributes + 0x80, // XXX max power (250ma) + + 0x09, // length + TYPE_INTERFACE, + 0x00, // interface number + 0x00, // alt number + 0x02, // # endpoints + 0xFF, + 0x42, + 0x03, + 0x00, // interface string + + 0x07, // length + TYPE_ENDPOINT, + 0x81, // in, #1 + 0x02, // bulk + 0x00, 0x02, // max packet 512 + 0x00, // interval + + 0x07, // length + TYPE_ENDPOINT, + 0x01, // out, #1 + 0x02, // bulk + 0x00, 0x02, // max packet 512 + 0x01, // interval +}; + +static unsigned char config_desc_fs[] = { + 0x09, // length + TYPE_CONFIGURATION, + 0x20, 0x00, // total length + 0x01, // # interfaces + 0x01, // config value + 0x00, // config string + 0x80, // attributes + 0x80, // XXX max power (250ma) + + 0x09, // length + TYPE_INTERFACE, + 0x00, // interface number + 0x00, // alt number + 0x02, // # endpoints + 0xFF, + 0x42, + 0x03, + 0x00, // interface string + + 0x07, // length + TYPE_ENDPOINT, + 0x81, // in, #1 + 0x02, // bulk + 0x40, 0x00, // max packet 64 + 0x00, // interval + + 0x07, // length + TYPE_ENDPOINT, + 0x01, // out, #1 + 0x02, // bulk + 0x40, 0x00, // max packet 64 + 0x00, // interval +}; + +typedef struct +{ + void *data; + unsigned short length; + unsigned short id; +} dtable; + +#define ID(type,num) ((type << 8) | num) + +static dtable descr_hs[] = { + { device_desc, sizeof(device_desc), ID(TYPE_DEVICE, 0) }, + { config_desc, sizeof(config_desc), ID(TYPE_CONFIGURATION, 0) }, + { manufacturer_string, sizeof(manufacturer_string), ID(TYPE_STRING, 1) }, + { product_string, sizeof(product_string), ID(TYPE_STRING, 2) }, + { default_string, sizeof(default_string), ID(TYPE_STRING, 4) }, + { language_table, sizeof(language_table), ID(TYPE_STRING, 0) }, + { 0, 0, 0 }, +}; + +static dtable descr_fs[] = { + { device_desc, sizeof(device_desc), ID(TYPE_DEVICE, 0) }, + { config_desc_fs, sizeof(config_desc), ID(TYPE_CONFIGURATION, 0) }, + { manufacturer_string, sizeof(manufacturer_string), ID(TYPE_STRING, 1) }, + { product_string, sizeof(product_string), ID(TYPE_STRING, 2) }, + { default_string, sizeof(default_string), ID(TYPE_STRING, 4) }, + { language_table, sizeof(language_table), ID(TYPE_STRING, 0) }, + { 0, 0, 0 }, +}; diff --git a/include/msm7k/dmov.h b/include/msm7k/dmov.h new file mode 100644 index 0000000..b151289 --- /dev/null +++ b/include/msm7k/dmov.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_DMOV_H +#define __ASM_ARCH_MSM7200_DMOV_H + +#define MSM_DMOV_BASE 0xA9700000 + +/* see 80-VA736-2 C pp 415-439 */ + +#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2)) +#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2)) +#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2)) +#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2)) + +/* only security domain 3 is available to the ARM11 +** +** SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM +** +*/ + +#define DMOV_CMD_PTR(ch) DMOV_SD3(0x000, ch) +#define DMOV_CMD_LIST (0 << 29) /* does not work */ +#define DMOV_CMD_PTR_LIST (1 << 29) /* works */ +#define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */ +#define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */ +#define DMOV_CMD_ADDR(addr) ((addr) >> 3) + +#define DMOV_RSLT(ch) DMOV_SD3(0x040, ch) +#define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */ +#define DMOV_RSLT_ERROR (1 << 3) +#define DMOV_RSLT_FLUSH (1 << 2) +#define DMOV_RSLT_DONE (1 << 1) /* top pointer done */ +#define DMOV_RSLT_USER (1 << 0) /* command with FR force result */ + +#define DMOV_FLUSH0(ch) DMOV_SD3(0x080, ch) +#define DMOV_FLUSH1(ch) DMOV_SD3(0x0C0, ch) +#define DMOV_FLUSH2(ch) DMOV_SD3(0x100, ch) +#define DMOV_FLUSH3(ch) DMOV_SD3(0x140, ch) +#define DMOV_FLUSH4(ch) DMOV_SD3(0x180, ch) +#define DMOV_FLUSH5(ch) DMOV_SD3(0x1C0, ch) + +#define DMOV_STATUS(ch) DMOV_SD3(0x200, ch) +#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29)) +#define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3) +#define DMOV_STATUS_RSLT_VALID (1 << 1) +#define DMOV_STATUS_CMD_PTR_RDY (1 << 0) + +#define DMOV_ISR DMOV_SD3(0x380, 0) + +#define DMOV_CONFIG(ch) DMOV_SD3(0x300, ch) +#define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2) +#define DMOV_CONFIG_FOREC_FLUSH_RSLT (1 << 1) +#define DMOV_CONFIG_IRQ_EN (1 << 0) + +/* channel assignments - from qc/dmov_7500.h */ + +#define DMOV_NAND_CHAN 7 +#define DMOV_NAND_CRCI_CMD 5 +#define DMOV_NAND_CRCI_DATA 4 + +#define DMOV_SDC1_CHAN 8 +#define DMOV_SDC1_CRCI 6 + +#define DMOV_SDC2_CHAN 8 +#define DMOV_SDC2_CRCI 7 + +#define DMOV_TSIF_CHAN 10 +#define DMOV_TSIF_CRCI 10 + +#define DMOV_USB_CHAN 11 + +/* no client rate control ifc (eg, ram) */ +#define DMOV_NONE_CRCI 0 + + +/* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover +** is going to walk a list of 32bit pointers as described below. Each +** pointer points to a *array* of dmov_s, etc structs. The last pointer +** in the list is marked with CMD_PTR_LP. The last struct in each array +** is marked with CMD_LC (see below). +*/ +#define CMD_PTR_ADDR(addr) ((addr) >> 3) +#define CMD_PTR_LP (1 << 31) /* last pointer */ +#define CMD_PTR_PT (3 << 29) /* ? */ + + +/* Single Item Mode -- seems to work as expected */ +typedef struct { + unsigned cmd; + unsigned src; + unsigned dst; + unsigned len; +} dmov_s; + +/* Scatter/Gather Mode -- does this work?*/ +typedef struct { + unsigned cmd; + unsigned src_dscr; + unsigned dst_dscr; + unsigned _reserved; +} dmov_sg; + +/* bits for the cmd field of the above structures */ + +#define CMD_LC (1 << 31) /* last command */ +#define CMD_FR (1 << 22) /* force result -- does not work? */ +#define CMD_OCU (1 << 21) /* other channel unblock */ +#define CMD_OCB (1 << 20) /* other channel block */ +#define CMD_TCB (1 << 19) /* ? */ +#define CMD_DAH (1 << 18) /* destination address hold -- does not work?*/ +#define CMD_SAH (1 << 17) /* source address hold -- does not work? */ + +#define CMD_MODE_SINGLE (0 << 0) /* dmov_s structure used */ +#define CMD_MODE_SG (1 << 0) /* untested */ +#define CMD_MODE_IND_SG (2 << 0) /* untested */ +#define CMD_MODE_BOX (3 << 0) /* untested */ + +#define CMD_DST_SWAP_BYTES (1 << 14) /* exchange each byte n with byte n+1 */ +#define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */ +#define CMD_DST_SWAP_WORDS (1 << 16) /* exchange each word n with word n+1 */ + +#define CMD_SRC_SWAP_BYTES (1 << 11) /* exchange each byte n with byte n+1 */ +#define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */ +#define CMD_SRC_SWAP_WORDS (1 << 13) /* exchange each word n with word n+1 */ + +#define CMD_DST_CRCI(n) (((n) & 15) << 7) +#define CMD_SRC_CRCI(n) (((n) & 15) << 3) + + +/* NOTES: +** +** Looks like Channels 4, 5, 6, 7, 8, 10, 11 are available to the ARM11 +** +*/ +#endif diff --git a/include/msm7k/gpio.h b/include/msm7k/gpio.h new file mode 100644 index 0000000..8d56a03 --- /dev/null +++ b/include/msm7k/gpio.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_GPIO_H +#define __ASM_ARCH_MSM7200_GPIO_H + +#define MSM_GPIO1_BASE 0xA9200000 +#define MSM_GPIO2_BASE 0xA9300000 + +/* see 80-VA736-2 Rev C pp 695-751 +** +** These are actually the *shadow* gpio registers, since the +** real ones (which allow full access) are only available to the +** ARM9 side of the world. +** +** Since the _BASE need to be page-aligned when we're mapping them +** to virtual addresses, adjust for the additional offset in these +** macros. +*/ + +#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) + +/* output value */ +#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */ +#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 42-16 */ +#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-43 */ +#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */ +#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */ + +/* same pin map as above, output enable */ +#define GPIO_OE_0 GPIO1_REG(0x10) +#define GPIO_OE_1 GPIO2_REG(0x08) +#define GPIO_OE_2 GPIO1_REG(0x14) +#define GPIO_OE_3 GPIO1_REG(0x18) +#define GPIO_OE_4 GPIO1_REG(0x1C) + +/* same pin map as above, input read */ +#define GPIO_IN_0 GPIO1_REG(0x34) +#define GPIO_IN_1 GPIO2_REG(0x20) +#define GPIO_IN_2 GPIO1_REG(0x38) +#define GPIO_IN_3 GPIO1_REG(0x3C) +#define GPIO_IN_4 GPIO1_REG(0x40) + +/* same pin map as above, 1=edge 0=level interrup */ +#define GPIO_INT_EDGE_0 GPIO1_REG(0x60) +#define GPIO_INT_EDGE_1 GPIO2_REG(0x50) +#define GPIO_INT_EDGE_2 GPIO1_REG(0x64) +#define GPIO_INT_EDGE_3 GPIO1_REG(0x68) +#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C) + +/* same pin map as above, 1=positive 0=negative */ +#define GPIO_INT_POS_0 GPIO1_REG(0x70) +#define GPIO_INT_POS_1 GPIO2_REG(0x58) +#define GPIO_INT_POS_2 GPIO1_REG(0x74) +#define GPIO_INT_POS_3 GPIO1_REG(0x78) +#define GPIO_INT_POS_4 GPIO1_REG(0x7C) + +/* same pin map as above, interrupt enable */ +#define GPIO_INT_EN_0 GPIO1_REG(0x80) +#define GPIO_INT_EN_1 GPIO2_REG(0x60) +#define GPIO_INT_EN_2 GPIO1_REG(0x84) +#define GPIO_INT_EN_3 GPIO1_REG(0x88) +#define GPIO_INT_EN_4 GPIO1_REG(0x8C) + +/* same pin map as above, write 1 to clear interrupt */ +#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90) +#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68) +#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94) +#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98) +#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C) + +/* same pin map as above, 1=interrupt pending */ +#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0) +#define GPIO_INT_STATUS_1 GPIO2_REG(0x70) +#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4) +#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8) +#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC) + +#endif diff --git a/include/msm7k/gpt.h b/include/msm7k/gpt.h new file mode 100644 index 0000000..69211ca --- /dev/null +++ b/include/msm7k/gpt.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_GPT_H +#define __ASM_ARCH_MSM7200_GPT_H + +#define MSM_GPT_BASE 0xC0100000 + +#define GPT_REG(off) (MSM_GPT_BASE + (off)) + +/* See 80-VE113-1 A, pp 229-231 */ + +#define GPT_MATCH_VAL GPT_REG(0x0000) +#define GPT_COUNT_VAL GPT_REG(0x0004) +#define GPT_ENABLE GPT_REG(0x0008) +#define GPT_ENABLE_CLR_ON_MATCH_EN 2 +#define GPT_ENABLE_EN 1 +#define GPT_CLEAR GPT_REG(0x000C) + +#define DGT_MATCH_VAL GPT_REG(0x0010) +#define DGT_COUNT_VAL GPT_REG(0x0014) +#define DGT_ENABLE GPT_REG(0x0018) +#define DGT_ENABLE_CLR_ON_MATCH_EN 2 +#define DGT_ENABLE_EN 1 +#define DGT_CLEAR GPT_REG(0x001C) + +#define CSR_PROTECTION GPT_REG(0x0020) +#define CSR_PROTECTION_EN 1 + +#endif diff --git a/include/msm7k/hsusb.h b/include/msm7k/hsusb.h new file mode 100644 index 0000000..5420d14 --- /dev/null +++ b/include/msm7k/hsusb.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _MSM7200_USB_H_ +#define _MSM7200_USB_H_ + +#define MSM_USB_BASE 0xA0800000 + + +#define USB_ID (MSM_USB_BASE + 0x0000) +#define USB_HWGENERAL (MSM_USB_BASE + 0x0004) +#define USB_HWHOST (MSM_USB_BASE + 0x0008) +#define USB_HWDEVICE (MSM_USB_BASE + 0x000C) +#define USB_HWTXBUF (MSM_USB_BASE + 0x0010) +#define USB_HWRXBUF (MSM_USB_BASE + 0x0014) +#define USB_SBUSCFG (MSM_USB_BASE + 0x0090) + +#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ +#define USB_HCIVERSION (MSM_USB_BASE + 0x0102) /* 16 bit */ +#define USB_HCSPARAMS (MSM_USB_BASE + 0x0104) +#define USB_HCCPARAMS (MSM_USB_BASE + 0x0108) +#define USB_DCIVERSION (MSM_USB_BASE + 0x0120) /* 16 bit */ +#define USB_USBCMD (MSM_USB_BASE + 0x0140) +#define USB_USBSTS (MSM_USB_BASE + 0x0144) +#define USB_USBINTR (MSM_USB_BASE + 0x0148) +#define USB_FRINDEX (MSM_USB_BASE + 0x014C) +#define USB_DEVICEADDR (MSM_USB_BASE + 0x0154) +#define USB_ENDPOINTLISTADDR (MSM_USB_BASE + 0x0158) +#define USB_BURSTSIZE (MSM_USB_BASE + 0x0160) +#define USB_TXFILLTUNING (MSM_USB_BASE + 0x0164) +#define USB_ULPI_VIEWPORT (MSM_USB_BASE + 0x0170) +#define USB_ENDPTNAK (MSM_USB_BASE + 0x0178) +#define USB_ENDPTNAKEN (MSM_USB_BASE + 0x017C) +#define USB_PORTSC (MSM_USB_BASE + 0x0184) +#define USB_OTGSC (MSM_USB_BASE + 0x01A4) +#define USB_USBMODE (MSM_USB_BASE + 0x01A8) +#define USB_ENDPTSETUPSTAT (MSM_USB_BASE + 0x01AC) +#define USB_ENDPTPRIME (MSM_USB_BASE + 0x01B0) +#define USB_ENDPTFLUSH (MSM_USB_BASE + 0x01B4) +#define USB_ENDPTSTAT (MSM_USB_BASE + 0x01B8) +#define USB_ENDPTCOMPLETE (MSM_USB_BASE + 0x01BC) +#define USB_ENDPTCTRL(n) (MSM_USB_BASE + 0x01C0 + (4 * (n))) + + +#define USBCMD_RESET 2 +#define USBCMD_ATTACH 1 + +#define USBMODE_DEVICE 2 +#define USBMODE_HOST 3 + +struct ept_queue_head +{ + unsigned config; + unsigned current; /* read-only */ + + unsigned next; + unsigned info; + unsigned page0; + unsigned page1; + unsigned page2; + unsigned page3; + unsigned page4; + unsigned reserved_0; + + unsigned char setup_data[8]; + + unsigned reserved_1; + unsigned reserved_2; + unsigned reserved_3; + unsigned reserved_4; +}; + +#define CONFIG_MAX_PKT(n) ((n) << 16) +#define CONFIG_ZLT (1 << 29) /* stop on zero-len xfer */ +#define CONFIG_IOS (1 << 15) /* IRQ on setup */ + +struct ept_queue_item +{ + unsigned next; + unsigned info; + unsigned page0; + unsigned page1; + unsigned page2; + unsigned page3; + unsigned page4; + unsigned reserved; +}; + +#define TERMINATE 1 + +#define INFO_BYTES(n) ((n) << 16) +#define INFO_IOC (1 << 15) +#define INFO_ACTIVE (1 << 7) +#define INFO_HALTED (1 << 6) +#define INFO_BUFFER_ERROR (1 << 5) +#define INFO_TX_ERROR (1 << 3) + + +#define STS_NAKI (1 << 16) /* */ +#define STS_SLI (1 << 8) /* R/WC - suspend state entered */ +#define STS_SRI (1 << 7) /* R/WC - SOF recv'd */ +#define STS_URI (1 << 6) /* R/WC - RESET recv'd - write to clear */ +#define STS_FRI (1 << 3) /* R/WC - Frame List Rollover */ +#define STS_PCI (1 << 2) /* R/WC - Port Change Detect */ +#define STS_UEI (1 << 1) /* R/WC - USB Error */ +#define STS_UI (1 << 0) /* R/WC - USB Transaction Complete */ + + +/* bits used in all the endpoint status registers */ +#define EPT_TX(n) (1 << ((n) + 16)) +#define EPT_RX(n) (1 << (n)) + + +#define CTRL_TXE (1 << 23) +#define CTRL_TXR (1 << 22) +#define CTRL_TXI (1 << 21) +#define CTRL_TXD (1 << 17) +#define CTRL_TXS (1 << 16) +#define CTRL_RXE (1 << 7) +#define CTRL_RXR (1 << 6) +#define CTRL_RXI (1 << 5) +#define CTRL_RXD (1 << 1) +#define CTRL_RXS (1 << 0) + +#define CTRL_TXT_CTRL (0 << 18) +#define CTRL_TXT_ISOCH (1 << 18) +#define CTRL_TXT_BULK (2 << 18) +#define CTRL_TXT_INT (3 << 18) + +#define CTRL_RXT_CTRL (0 << 2) +#define CTRL_RXT_ISOCH (1 << 2) +#define CTRL_RXT_BULK (2 << 2) +#define CTRL_RXT_INT (3 << 2) + +#define ULPI_WAKEUP (1 << 31) +#define ULPI_RUN (1 << 30) +#define ULPI_WRITE (1 << 29) +#define ULPI_READ (0 << 29) +#define ULPI_STATE_NORMAL (1 << 27) +#define ULPI_ADDR(n) (((n) & 255) << 16) +#define ULPI_DATA(n) ((n) & 255) +#define ULPI_DATA_READ(n) (((n) >> 8) & 255) + +#endif diff --git a/include/msm7k/irqs.h b/include/msm7k/irqs.h new file mode 100644 index 0000000..d37d50d --- /dev/null +++ b/include/msm7k/irqs.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_IRQS_H + +/* MSM7200 ARM11 Interrupt Numbers */ +/* See 80-VE113-1 A, pp219-221 */ + +#define INT_A9_M2A_0 0 +#define INT_A9_M2A_1 1 +#define INT_A9_M2A_2 2 +#define INT_A9_M2A_3 3 +#define INT_A9_M2A_4 4 +#define INT_A9_M2A_5 5 +#define INT_A9_M2A_6 6 +#define INT_GP_TIMER_EXP 7 +#define INT_DEBUG_TIMER_EXP 8 +#define INT_UART1 9 +#define INT_UART2 10 +#define INT_UART3 11 +#define INT_UART1_RX 12 +#define INT_UART2_RX 13 +#define INT_UART3_RX 14 +#define INT_USB_OTG 15 +#define INT_MDDI_PRI 16 +#define INT_MDDI_EXT 17 +#define INT_MDDI_CLIENT 18 +#define INT_MDP 19 +#define INT_GRAPHICS 20 +#define INT_ADM_AARM 21 +#define INT_ADSP_A11 22 +#define INT_ADSP_A9_A11 23 +#define INT_SDC1_0 24 +#define INT_SDC1_1 25 +#define INT_SDC2_0 26 +#define INT_SDC2_1 27 +#define INT_KEYSENSE 28 +#define INT_TCHSCRN_SSBI 29 +#define INT_TCHSCRN1 30 +#define INT_TCHSCRN2 31 + +#define INT_GPIO_GROUP1 (32 + 0) +#define INT_GPIO_GROUP2 (32 + 1) +#define INT_PWB_I2C (32 + 2) +#define INT_NAND_WR_ER_DONE (32 + 3) +#define INT_NAND_OP_DONE (32 + 4) +#define INT_SOFTRESET (32 + 5) +#define INT_PBUS_ARM11 (32 + 6) +#define INT_AXI_MPU_SMI (32 + 7) +#define INT_AXI_MPU_EBI1 (32 + 8) +#define INT_AD_HSSD (32 + 9) +#define INT_ARM11_PM (32 + 10) +#define INT_ARM11_DMA (32 + 11) +#define INT_TSIF_IRQ (32 + 12) +#define INT_UART1DM_IRQ (32 + 13) +#define INT_UART1DM_RX (32 + 14) +#define INT_SPARE0 (32 + 15) + +#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) + +#define NR_IRQS 48 + +#endif diff --git a/include/msm7k/mddi.h b/include/msm7k/mddi.h new file mode 100644 index 0000000..619655e --- /dev/null +++ b/include/msm7k/mddi.h @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_MDDI_H +#define __ASM_ARCH_MSM7200_MDDI_H + +#define MSM_MDDI_BASE 0xAA600000 + +/* see 80-VA736-2 C pp 776-787 */ + +#define MDDI_REG(off) (MSM_MDDI_BASE + (off)) + +#define MDDI_CMD MDDI_REG(0x0000) +#define MDDI_VERSION MDDI_REG(0x0004) +#define MDDI_PRI_PTR MDDI_REG(0x0008) +#define MDDI_SEC_PTR MDDI_REG(0x000C) +#define MDDI_BPS MDDI_REG(0x0010) +#define MDDI_SPM MDDI_REG(0x0014) +#define MDDI_INT MDDI_REG(0x0018) + +#define MDDI_INT_PRI_PTR_READ (1 << 0) +#define MDDI_INT_SEC_PTR_READ (1 << 1) +#define MDDI_INT_REV_DATA_AVAIL (1 << 2) +#define MDDI_INT_DISP_REQ (1 << 3) +#define MDDI_INT_PRI_UNDERFLOW (1 << 4) +#define MDDI_INT_SEC_UNDERFLOW (1 << 5) +#define MDDI_INT_REV_OVERFLOW (1 << 6) +#define MDDI_INT_CRC_ERROR (1 << 7) +#define MDDI_INT_MDDI_IN (1 << 8) +#define MDDI_INT_PRI_OVERWRITE (1 << 9) +#define MDDI_INT_SEC_OVERWRITE (1 << 10) +#define MDDI_INT_REV_OVERWRITE (1 << 11) +#define MDDI_INT_DMA_FAILURE (1 << 12) +#define MDDI_INT_LINK_ACTIVE (1 << 13) +#define MDDI_INT_IN_HIBERNATION (1 << 14) +#define MDDI_INT_PRI_LINK_LIST_DONE (1 << 15) +#define MDDI_INT_SEC_LINK_LIST_DONE (1 << 16) +#define MDDI_INT_NO_REQ_PKTS_PENDING (1 << 17) +#define MDDI_INT_RTD_FAILURE (1 << 18) +#define MDDI_INT_REV_PKT_RECEIVED (1 << 19) +#define MDDI_INT_REV_PKTS_AVAIL (1 << 20) + +#define MDDI_INTEN MDDI_REG(0x001C) +#define MDDI_REV_PTR MDDI_REG(0x0020) +#define MDDI_REV_SIZE MDDI_REG(0x0024) +#define MDDI_STAT MDDI_REG(0x0028) + +#define MDDI_STAT_LINK_ACTIVE (1 << 0) +#define MDDI_STAT_NEW_REV_PTR (1 << 1) +#define MDDI_STAT_NEW_PRI_PTR (1 << 2) +#define MDDI_STAT_NEW_SEC_PTR (1 << 3) +#define MDDI_STAT_IN_HIBERNATION (1 << 4) +#define MDDI_STAT_PRI_LINK_LIST_DONE (1 << 5) +#define MDDI_STAT_SEC_LINK_LIST_DONE (1 << 6) +#define MDDI_STAT_SEND_TIMING_PKT (1 << 7) +#define MDDI_STAT_SEND_REV_ENCAP_WITH_FLAGS (1 << 8) +#define MDDI_STAT_SEND_POWER_DOWN (1 << 9) +#define MDDI_STAT_DO_HANDSHAKE (1 << 10) +#define MDDI_STAT_RTD_MEAS_FAIL (1 << 11) +#define MDDI_STAT_CLIENT_WAKEUP_REQ (1 << 12) +#define MDDI_STAT_DMA_ABORT (1 << 13) +#define MDDI_STAT_REV_OVERFLOW_RESET (1 << 14) +#define MDDI_STAT_FORCE_NEW_REV_PTR (1 << 15) +#define MDDI_STAT_CRC_ERRORS (1 << 16) + +#define MDDI_REV_RATE_DIV MDDI_REG(0x002C) +#define MDDI_REV_CRC_ERR MDDI_REG(0x0030) +#define MDDI_TA1_LEN MDDI_REG(0x0034) +#define MDDI_TA2_LEN MDDI_REG(0x0038) +#define MDDI_TEST_BUS MDDI_REG(0x003C) +#define MDDI_TEST MDDI_REG(0x0040) +#define MDDI_REV_PKT_CNT MDDI_REG(0x0044) +#define MDDI_DRIVE_HI MDDI_REG(0x0048) +#define MDDI_DRIVE_LO MDDI_REG(0x004C) +#define MDDI_DISP_WAKE MDDI_REG(0x0050) +#define MDDI_REV_ENCAP_SZ MDDI_REG(0x0054) +#define MDDI_RTD_VAL MDDI_REG(0x0058) +#define MDDI_MDP_VID_FMT_DES MDDI_REG(0x005C) +#define MDDI_MDP_VID_PIX_ATTR MDDI_REG(0x0060) +#define MDDI_MDP_VID_CLIENTID MDDI_REG(0x0064) +#define MDDI_PAD_CTL MDDI_REG(0x0068) +#define MDDI_DRIVER_START_CNT MDDI_REG(0x006C) +#define MDDI_NEXT_PRI_PTR MDDI_REG(0x0070) +#define MDDI_NEXT_SEC_PTR MDDI_REG(0x0074) +#define MDDI_MISR_CTL MDDI_REG(0x0078) +#define MDDI_MISR_DATA MDDI_REG(0x007C) +#define MDDI_SF_CNT MDDI_REG(0x0080) +#define MDDI_MF_CNT MDDI_REG(0x0084) +#define MDDI_CURR_REV_PTR MDDI_REG(0x0088) +#define MDDI_CORE_VER MDDI_REG(0x008C) + +#define CMD_POWER_DOWN 0x0100 +#define CMD_POWER_UP 0x0200 +#define CMD_HIBERNATE 0x0300 +#define CMD_RESET 0x0400 +#define CMD_IGNORE 0x0500 +#define CMD_REV_ENC_REQ 0x0600 +#define CMD_RTD_MEASURE 0x0700 +#define CMD_LINK_ACTIVE 0x0900 +#define CMD_PERIODIC_REV_ENC 0x0A00 +#define CMD_FORCE_NEW_REV_PTR 0x0C00 + +#define CMD_GET_CLIENT_CAP 0x0601 +#define CMD_GET_CLIENT_STATUS 0x0602 + +#if 1 +#define FORMAT_18BPP 0x5666 +#define FORMAT_24BPP 0x5888 +#define FORMAT_16BPP 0x5565 +#else +#define FORMAT_MONOCHROME (0 << 13) +#define FORMAT_PALETTE (1 << 13) +#define FORMAT_RGB (2 << 13) +#define FORMAT_YCBCR422 (3 << 13) +#define FORMAT_BAYER (4 << 13) +#endif + +#define PIXATTR_BOTH_EYES 3 +#define PIXATTR_LEFT_EYE 2 +#define PIXATTR_RIGHT_EYE 1 +#define PIXATTR_ALT_DISPLAY 0 + +#define PIXATTR_PROGRESSIVE 0 +#define PIXATTR_INTERLACED (1 << 2) +#define PIXATTR_ALTERNATE (1 << 3) + +#define PIXATTR_IGNORE_LRTB (1 << 5) + +#define PIXATTR_TO_REFRESH (0 << 6) +#define PIXATTR_TO_OFFLINE (1 << 6) +#define PIXATTR_TO_ALL (3 << 6) + +#define PIXATTR_LAST_ROW (1 << 15) + +#define TYPE_VIDEO_STREAM 16 +#define TYPE_CLIENT_CAPS 66 +#define TYPE_REGISTER_ACCESS 146 +#define TYPE_CLIENT_STATUS 70 + +typedef struct mddi_video_stream mddi_video_stream; +typedef struct mddi_register_access mddi_register_access; +typedef struct mddi_client_caps mddi_client_caps; + +typedef struct mddi_llentry mddi_llentry; + +struct __attribute__((packed)) mddi_video_stream +{ + unsigned short length; /* length in bytes excluding this field */ + unsigned short type; /* MDDI_TYPE_VIDEO_STREAM */ + unsigned short client_id; /* set to zero */ + + unsigned short format; + unsigned short pixattr; + + unsigned short left; + unsigned short top; + unsigned short right; + unsigned short bottom; + + unsigned short start_x; + unsigned short start_y; + + unsigned short pixels; + + unsigned short crc; + unsigned short reserved; +}; + +struct __attribute__((packed)) mddi_register_access +{ + unsigned short length; + unsigned short type; + unsigned short client_id; + + unsigned short rw_info; /* flag below | count of reg_data */ +#define MDDI_WRITE (0 << 14) +#define MDDI_READ (2 << 14) +#define MDDI_READ_RESP (3 << 14) + + unsigned reg_addr; + unsigned short crc; /* 16 bit crc of the above */ + + unsigned reg_data; /* "list" of 3byte data values */ +}; + +struct __attribute__((packed)) mddi_llentry { + unsigned short flags; + unsigned short header_count; + unsigned short data_count; + void *data; + mddi_llentry *next; + unsigned short reserved; + union { + mddi_video_stream v; + mddi_register_access r; + unsigned _[12]; + } u; +}; + +struct __attribute__((packed)) mddi_client_caps +{ + unsigned short length; + unsigned short type; + unsigned short client_id; + + unsigned short protocol_ver; + unsigned short min_protocol_ver; + unsigned short data_rate_cap; + unsigned char interface_type_cap; + unsigned char num_alt_displays; + unsigned short postcal_data_rate; + unsigned short bitmap_width; + unsigned short bitmap_height; + unsigned short display_window_width; + unsigned short display_window_height; + unsigned cmap_size; + unsigned short cmap_rgb_width; + unsigned short rgb_cap; + unsigned char mono_cap; + unsigned char reserved1; + unsigned short ycbcr_cap; + unsigned short bayer_cap; + unsigned short alpha_cursor_planes; + unsigned client_feature_cap; + unsigned char max_video_frame_rate_cap; + unsigned char min_video_frame_rate_cap; + unsigned short min_sub_frame_rate; + unsigned short audio_buf_depth; + unsigned short audio_channel_cap; + unsigned short audio_sampe_rate_rap; + unsigned char audio_sample_res; + unsigned char mic_audio_sample_res; + unsigned short mic_sample_rate_cap; + unsigned char keyboard_data_fmt; + unsigned char pointing_device_data_fmt; + unsigned short content_protection_type; + unsigned short manufacturer_name; + unsigned short product_code; + unsigned short reserved3; + unsigned serial_no; + unsigned char week_of_manufacture; + unsigned char year_of_manufacture; + + unsigned short crc; +}; + +#endif diff --git a/include/msm7k/mdp.h b/include/msm7k/mdp.h new file mode 100644 index 0000000..11f05e8 --- /dev/null +++ b/include/msm7k/mdp.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_MDP_H +#define __ASM_ARCH_MSM7200_MDP_H + +#define MSM_MDP_BASE1 0xAA200000 +#define MSM_MDP_BASE2 0xAA210100 + +/* see 80-VA736-2 C pp 587-627 */ + +#define MDP_REG1(off) (MSM_MDP_BASE1 + (off)) +#define MDP_REG(off) (MSM_MDP_BASE2 + (off)) + + +#define MDP_SYNC_CONFIG_0 MDP_REG1(0x0000) +#define MDP_SYNC_CONFIG_1 MDP_REG1(0x0004) +#define MDP_SYNC_CONFIG_2 MDP_REG1(0x0008) +#define MDP_SYNC_VSYNC_EN (1 << 17) +#define MDP_SYNC_SYNC_EN (1 << 16) +#define MDP_SYNC_DIV_CNT(n) ((n) & 0xffff) + +#define MDP_SYNC_STATUS_0 MDP_REG1(0x000C) +#define MDP_SYNC_STATUS_1 MDP_REG1(0x0010) +#define MDP_SYNC_STATUS_2 MDP_REG1(0x0014) +#define MDP_SYNC_FRAME_COUNT(n) (((n) >> 16) & 0xfff) +#define MDP_SYNC_LINE_COUNT(n) ((n) & 0x3ff) + +#define MDP_SYNC_THRESH_0 MDP_REG1(0x0018) +#define MDP_SYNC_SEC_ABOVE(n) (((n) & 0xFF) << 24) +#define MDP_SYNC_SEC_BELOW(n) (((n) & 0xFF) << 16) +#define MDP_SYNC_PRIM_ABOVE(n) (((n) & 0xFF) << 8) +#define MDP_SYNC_PRIM_BELOW(n) ((n) & 0xFF) + +#define MDP_SYNC_THRESH_1 MDP_REG1(0x001C) +#define MDP_SYNC_EXT_ABOVE(n) (((n) & 0xFF) << 8) +#define MDP_SYNC_EXT_BELOW(n) ((n) & 0xFF) + +#define MDP_INTR_ENABLE MDP_REG1(0x0020) +#define MDP_INTR_STATUS MDP_REG1(0x0024) +#define MDP_INTR_CLEAR MDP_REG1(0x0028) +#define MDP_INTR_LIST0_DONE (1 << 0) +#define MDP_INTR_LIST1_DONE (1 << 1) +#define MDP_INTR_DMA_DONE (1 << 2) +#define MDP_INTR_TV_DONE (1 << 3) +#define MDP_INTR_CONFIG_ERR (1 << 4) +#define MDP_INTR_ROI_ERR (1 << 5) +#define MDP_INTR_TV_UNDERRUN (1 << 6) + +#define MDP_HW_VERSION MDP_REG1(0x0070) + + +#define MDP_EDGE_CONFIG MDP_REG(0x0000) +#define MDP_TILE_CONFIG MDP_REG(0x0004) + +/* BLT controls */ +#define MDP_SRC_ROI MDP_REG(0x0008) +#define MDP_SRCP0_ADDR MDP_REG(0x000C) +#define MDP_SRCP1_ADDR MDP_REG(0x0010) +#define MDP_SRCP2_ADDR MDP_REG(0x0014) +#define MDP_SRCP3_ADDR MDP_REG(0x0018) +#define MDP_SRCP01_STRIDE MDP_REG(0x001C) +#define MDP_SRCP23_STRIDE MDP_REG(0x0020) +#define MDP_SRC_CONFIG MDP_REG(0x0024) +#define MDP_UNPACK_PATTERN0 MDP_REG(0x0028) +#define MDP_UNPACK_PATTERN1 MDP_REG(0x002C) +#define MDP_UNPACK_PATTERN2 MDP_REG(0x0030) +#define MDP_UNPACK_PATTERN3 MDP_REG(0x0034) +#define MDP_PPP_CONFIG MDP_REG(0x0038) +#define MDP_PHASEX_INIT MDP_REG(0x003C) +#define MDP_PHASEY_INIT MDP_REG(0x0040) +#define MDP_PHASEX_STEP MDP_REG(0x0044) +#define MDP_PHASEY_STEP MDP_REG(0x0048) +#define MDP_ALPHA_CONFIG MDP_REG(0x004C) +#define MDP_DST_CONFIG MDP_REG(0x0050) +#define MDP_PACK_PATTERN0 MDP_REG(0x0054) +#define MDP_PACK_PATTERN1 MDP_REG(0x0058) +#define MDP_PACK_PATTERN2 MDP_REG(0x005C) +#define MDP_PACK_PATTERN3 MDP_REG(0x0060) +#define MDP_DST_ROI MDP_REG(0x0064) +#define MDP_DSTP0_ADDR MDP_REG(0x0068) +#define MDP_DSTP1_ADDR MDP_REG(0x006C) +#define MDP_DSTP2_ADDR MDP_REG(0x0070) +#define MDP_DSTP3_ADDR MDP_REG(0x0074) +#define MDP_DSTP01_STRIDE MDP_REG(0x0078) +#define MDP_DSTP23_STRIDE MDP_REG(0x007C) + +#endif diff --git a/include/msm7k/nand.h b/include/msm7k/nand.h new file mode 100644 index 0000000..12f2f9a --- /dev/null +++ b/include/msm7k/nand.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_NAND_H +#define __ASM_ARCH_MSM7200_NAND_H + +#define MSM_NAND_BASE 0xA0A00000 + +/* see 80-VA736-2 C pp 354-414 */ + +#define NAND_REG(off) (MSM_NAND_BASE + (off)) + +#define NAND_FLASH_CMD NAND_REG(0x0000) +#define NAND_ADDR0 NAND_REG(0x0004) +#define NAND_ADDR1 NAND_REG(0x0008) +#define NAND_FLASH_CHIP_SELECT NAND_REG(0x000C) +#define NAND_EXEC_CMD NAND_REG(0x0010) +#define NAND_FLASH_STATUS NAND_REG(0x0014) +#define NAND_BUFFER_STATUS NAND_REG(0x0018) +#define NAND_DEV0_CFG0 NAND_REG(0x0020) +#define NAND_DEV0_CFG1 NAND_REG(0x0024) +#define NAND_DEV1_CFG0 NAND_REG(0x0030) +#define NAND_DEV1_CFG1 NAND_REG(0x0034) +#define NAND_READ_ID NAND_REG(0x0040) +#define NAND_READ_STATUS NAND_REG(0x0044) +#define NAND_CONFIG_DATA NAND_REG(0x0050) +#define NAND_CONFIG NAND_REG(0x0054) +#define NAND_CONFIG_MODE NAND_REG(0x0058) +#define NAND_CONFIG_STATUS NAND_REG(0x0060) +#define NAND_MACRO1_REG NAND_REG(0x0064) +#define NAND_XFR_STEP1 NAND_REG(0x0070) +#define NAND_XFR_STEP2 NAND_REG(0x0074) +#define NAND_XFR_STEP3 NAND_REG(0x0078) +#define NAND_XFR_STEP4 NAND_REG(0x007C) +#define NAND_XFR_STEP5 NAND_REG(0x0080) +#define NAND_XFR_STEP6 NAND_REG(0x0084) +#define NAND_XFR_STEP7 NAND_REG(0x0088) +#define NAND_DEV_CMD0 NAND_REG(0x00A0) +#define NAND_DEV_CMD1 NAND_REG(0x00A4) +#define NAND_DEV_CMD2 NAND_REG(0x00A8) +#define NAND_DEV_CMD_VLD NAND_REG(0x00AC) +#define NAND_EBI2_MISR_SIG_REG NAND_REG(0x00B0) +#define NAND_EBI2_ECC_BUF_CFG NAND_REG(0x00F0) +#define NAND_FLASH_BUFFER NAND_REG(0x0100) + +/* device commands */ + +#define NAND_CMD_SOFT_RESET 0x01 +#define NAND_CMD_PAGE_READ 0x32 +#define NAND_CMD_PAGE_READ_ECC 0x33 +#define NAND_CMD_PAGE_READ_ALL 0x34 +#define NAND_CMD_SEQ_PAGE_READ 0x15 +#define NAND_CMD_PRG_PAGE 0x36 +#define NAND_CMD_PRG_PAGE_ECC 0x37 +#define NAND_CMD_PRG_PAGE_ALL 0x39 +#define NAND_CMD_BLOCK_ERASE 0x3A +#define NAND_CMD_FETCH_ID 0x0B +#define NAND_CMD_STATUS 0x0C +#define NAND_CMD_RESET 0x0D + +#endif diff --git a/include/msm7k/shared.h b/include/msm7k/shared.h new file mode 100644 index 0000000..b81732b --- /dev/null +++ b/include/msm7k/shared.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef MSM7K_SHARED_H +#define MSM7K_SHARED_H + +#define MSM7K_SHARED_PHYS 0x01F00000 + +#define MSM7K_VERSION (MSM7K_SHARED_PHYS + 0x40) + +#define VERSION_QDSP6 4 +#define VERSION_APPS_SBL 6 +#define VERSION_MODEM_SBL 7 +#define VERSION_APPS 8 +#define VERSION_MODEM 9 + +void get_version_modem(char *s); +void get_version_modem_sbl(char *s); + + +#define ACPU_CLK 0 /* Applications processor clock */ +#define ADM_CLK 1 /* Applications data mover clock */ +#define ADSP_CLK 2 /* ADSP clock */ +#define EBI1_CLK 3 /* External bus interface 1 clock */ +#define EBI2_CLK 4 /* External bus interface 2 clock */ +#define ECODEC_CLK 5 /* External CODEC clock */ +#define EMDH_CLK 6 /* External MDDI host clock */ +#define GP_CLK 7 /* General purpose clock */ +#define GRP_CLK 8 /* Graphics clock */ +#define I2C_CLK 9 /* I2C clock */ +#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ +#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ +#define IMEM_CLK 12 /* Internal graphics memory clock */ +#define MDC_CLK 13 /* MDDI client clock */ +#define MDP_CLK 14 /* Mobile display processor clock */ +#define PBUS_CLK 15 /* Peripheral bus clock */ +#define PCM_CLK 16 /* PCM clock */ +#define PMDH_CLK 17 /* Primary MDDI host clock */ +#define SDAC_CLK 18 /* Stereo DAC clock */ +#define SDC1_CLK 19 /* Secure Digital Card clocks */ +#define SDC1_PCLK 20 +#define SDC2_CLK 21 +#define SDC2_PCLK 22 +#define SDC3_CLK 23 +#define SDC3_PCLK 24 +#define SDC4_CLK 25 +#define SDC4_PCLK 26 +#define TSIF_CLK 27 /* Transport Stream Interface clocks */ +#define TSIF_REF_CLK 28 +#define TV_DAC_CLK 29 /* TV clocks */ +#define TV_ENC_CLK 30 +#define UART1_CLK 31 /* UART clocks */ +#define UART2_CLK 32 +#define UART3_CLK 33 +#define UART1DM_CLK 34 +#define UART2DM_CLK 35 +#define USB_HS_CLK 36 /* High speed USB core clock */ +#define USB_HS_PCLK 37 /* High speed USB pbus clock */ +#define USB_OTG_CLK 38 /* Full speed USB clock */ +#define VDC_CLK 39 /* Video controller clock */ +#define VFE_CLK 40 /* Camera / Video Front End clock */ +#define VFE_MDC_CLK 41 /* VFE MDDI client clock */ + +enum +{ + VREG_MSMA_ID, + VREG_MSMP_ID, + VREG_MSME1_ID, /* Not supported in Panoramix */ + VREG_MSMC1_ID, /* Not supported in PM6620 */ + VREG_MSMC2_ID, /* Supported in PM7500 only */ + VREG_GP3_ID, /* Supported in PM7500 only */ + VREG_MSME2_ID, /* Supported in PM7500 and Panoramix only */ + VREG_GP4_ID, /* Supported in PM7500 only */ + VREG_GP1_ID, /* Supported in PM7500 only */ + VREG_TCXO_ID, + VREG_PA_ID, + VREG_RFTX_ID, + VREG_RFRX1_ID, + VREG_RFRX2_ID, + VREG_SYNT_ID, + VREG_WLAN_ID, + VREG_USB_ID, + VREG_BOOST_ID, + VREG_MMC_ID, + VREG_RUIM_ID, + VREG_MSMC0_ID, /* Supported in PM6610 only */ + VREG_GP2_ID, /* Supported in PM7500 only */ + VREG_GP5_ID, /* Supported in PM7500 only */ + VREG_GP6_ID, /* Supported in PM7500 only */ + VREG_RF_ID, + VREG_RF_VCO_ID, + VREG_MPLL_ID, + VREG_S2_ID, + VREG_S3_ID, + VREG_RFUBM_ID, + VREG_NCP_ID, +}; + +int clock_enable(unsigned id); +int clock_disable(unsigned id); +int clock_set_rate(unsigned id, unsigned hz); +int clock_get_rate(unsigned id); + +int vreg_enable(unsigned id); +int vreg_disable(unsigned id); +int vreg_set_level(unsigned id, unsigned mv); + +void reboot(void); + +#endif diff --git a/include/msm7k/uart.h b/include/msm7k/uart.h new file mode 100644 index 0000000..cbcd960 --- /dev/null +++ b/include/msm7k/uart.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_UART_H +#define __ASM_ARCH_MSM7200_UART_H + +#define MSM_UART1_BASE 0xA9A00000 +#define MSM_UART2_BASE 0xA9B00000 +#define MSM_UART3_BASE 0xA9C00000 + +#define UART_MR1 0x0000 + +#define UART_MR1_AUTO_RFR_LEVEL0(n) (((n) & 0x3f) << 8) +#define UART_MR1_RX_RDY_CTL (1 << 7) +#define UART_MR1_CTS_CTL (1 << 6) +#define UART_MR1_AUTO_RFR_LEVEL1(n) ((n) & 0x3f) + +#define UART_MR2 0x0004 +#define UART_MR2_ERROR_MODE (1 << 6) +#define UART_MR2_BITS_PER_CHAR_5 (0 << 4) +#define UART_MR2_BITS_PER_CHAR_6 (1 << 4) +#define UART_MR2_BITS_PER_CHAR_7 (2 << 4) +#define UART_MR2_BITS_PER_CHAR_8 (3 << 4) +#define UART_MR2_STOP_BIT_LEN_0563 (0 << 2) +#define UART_MR2_STOP_BIT_LEN_1000 (1 << 2) +#define UART_MR2_STOP_BIT_LEN_1563 (2 << 2) +#define UART_MR2_STOP_BIT_LEN_2000 (3 << 2) +#define UART_MR2_PARITY_MODE_NONE (0) +#define UART_MR2_PARITY_MODE_ODD (1) +#define UART_MR2_PARITY_MODE_EVEN (2) +#define UART_MR2_PARITY_MODE_SPACE (3) + +#define UART_CSR 0x0008 +#define UART_CSR_115200 0xFF +#define UART_CSR_57600 0xEE +#define UART_CSR_38400 0xDD +#define UART_CSR_19200 0xBB + +#define UART_TF 0x000C + +#define UART_CR 0x0010 +#define UART_CR_CMD_NULL (0 << 4) +#define UART_CR_CMD_RESET_RX (1 << 4) +#define UART_CR_CMD_RESET_TX (2 << 4) +#define UART_CR_CMD_RESET_ERR (3 << 4) +#define UART_CR_CMD_RESET_BCI (4 << 4) +#define UART_CR_CMD_START_BREAK (5 << 4) +#define UART_CR_CMD_STOP_BREAK (6 << 4) +#define UART_CR_CMD_RESET_CTS_N (7 << 4) +#define UART_CR_CMD_PACKET_MODE (9 << 4) +#define UART_CR_CMD_MODE_RESET (12<< 4) +#define UART_CR_CMD_SET_RFR_N (13<< 4) +#define UART_CR_CMD_RESET_RFR_ND (14<< 4) +#define UART_CR_TX_DISABLE (1 << 3) +#define UART_CR_TX_ENABLE (1 << 3) +#define UART_CR_RX_DISABLE (1 << 3) +#define UART_CR_RX_ENABLE (1 << 3) + +#define UART_IMR 0x0014 +#define UART_IMR_RXLEV (1 << 4) +#define UART_IMR_TXLEV (1 << 0) + +#define UART_IPR 0x0018 +#define UART_TFWR 0x001C +#define UART_RFWR 0x0020 +#define UART_HCR 0x0024 + +#define UART_MREG 0x0028 +#define UART_NREG 0x002C +#define UART_DREG 0x0030 +#define UART_MNDREG 0x0034 +#define UART_IRDA 0x0038 +#define UART_MISR_MODE 0x0040 +#define UART_MISR_RESET 0x0044 +#define UART_MISR_EXPORT 0x0048 +#define UART_MISR_VAL 0x004C +#define UART_TEST_CTRL 0x0050 + +#define UART_SR 0x0008 +#define UART_SR_HUNT_CHAR (1 << 7) +#define UART_SR_RX_BREAK (1 << 6) +#define UART_SR_PAR_FRAME_ERR (1 << 5) +#define UART_SR_OVERRUN (1 << 4) +#define UART_SR_TX_EMPTY (1 << 3) +#define UART_SR_TX_READY (1 << 2) +#define UART_SR_RX_FULL (1 << 1) +#define UART_SR_RX_READY (1 << 0) + +#define UART_RF 0x000C +#define UART_MISR 0x0010 +#define UART_ISR 0x0014 + + +#endif diff --git a/include/msm7k/vic.h b/include/msm7k/vic.h new file mode 100644 index 0000000..46f3adf --- /dev/null +++ b/include/msm7k/vic.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __ASM_ARCH_MSM7200_VIC_H +#define __ASM_ARCH_MSM7200_VIC_H + +#define MSM_VIC_BASE 0xC0000000 + +#define VIC_REG(off) (MSM_VIC_BASE + (off)) + +/* See 80-VE113-1 A, pp 218-228 */ + +#define VIC_IRQ_STATUS0 VIC_REG(0x0000) +#define VIC_IRQ_STATUS1 VIC_REG(0x0004) +#define VIC_FIQ_STATUS0 VIC_REG(0x0008) +#define VIC_FIQ_STATUS1 VIC_REG(0x000C) +#define VIC_RAW_STATUS0 VIC_REG(0x0010) +#define VIC_RAW_STATUS1 VIC_REG(0x0014) +#define VIC_INT_CLEAR0 VIC_REG(0x0018) +#define VIC_INT_CLEAR1 VIC_REG(0x001C) +#define VIC_INT_SELECT0 VIC_REG(0x0020) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT1 VIC_REG(0x0024) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_EN0 VIC_REG(0x0028) +#define VIC_INT_EN1 VIC_REG(0x002C) +#define VIC_INT_ENCLEAR0 VIC_REG(0x0040) +#define VIC_INT_ENCLEAR1 VIC_REG(0x0044) +#define VIC_SOFTINT0 VIC_REG(0x0050) +#define VIC_SOFTINT1 VIC_REG(0x0054) +#define VIC_INT_MASTEREN VIC_REG(0x0060) /* 1: IRQ, 2: FIQ */ +#define VIC_PROTECTION VIC_REG(0x0064) /* 1: ENABLE */ +#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */ +#define VIC_INT_TYPE0 VIC_REG(0x0070) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE1 VIC_REG(0x0074) /* 1: EDGE, 0: LEVEL */ +#define VIC_IRQ_VEC_RD VIC_REG(0x0F00) /* pending int # */ +#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x0F20) /* pending vector addr */ + +#define VIC_VECTADDR(n) VIC_REG(0x0100+((n) * 4)) +#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4)) + +#endif diff --git a/libboot/Android.mk b/libboot/Android.mk new file mode 100644 index 0000000..d2085f3 --- /dev/null +++ b/libboot/Android.mk @@ -0,0 +1,25 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_ARM_MODE := arm + +LOCAL_SRC_FILES := \ + flash.c \ + poll.c \ + tags_partition.c \ + tags_revision.c \ + tags_serialno.c \ + tags_cmdline.c \ + gpio_keypad.c \ + init.c \ + tags.c + +LOCAL_C_INCLUDES := $(call include-path-for, bootloader) + +LOCAL_CFLAGS := -O2 -g -W -Wall +LOCAL_CFLAGS += -march=armv6 + +LOCAL_MODULE := libboot + +include $(BUILD_RAW_STATIC_LIBRARY) diff --git a/libboot/flash.c b/libboot/flash.c new file mode 100644 index 0000000..f1503dc --- /dev/null +++ b/libboot/flash.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/flash.h> + +#define MAX_PTN 16 + +static ptentry ptable[MAX_PTN]; +static unsigned pcount = 0; + +void flash_add_ptn(ptentry *ptn) +{ + if(pcount < MAX_PTN){ + memcpy(ptable + pcount, ptn, sizeof(*ptn)); + pcount++; + } +} + +void flash_dump_ptn(void) +{ + unsigned n; + for(n = 0; n < pcount; n++) { + ptentry *ptn = ptable + n; + dprintf("ptn %d name='%s' start=%d len=%d\n", + n, ptn->name, ptn->start, ptn->length); + } +} + + +ptentry *flash_find_ptn(const char *name) +{ + unsigned n; + for(n = 0; n < pcount; n++) { + if(!strcmp(ptable[n].name, name)) { + return ptable + n; + } + } + return 0; +} + +ptentry *flash_get_ptn(unsigned n) +{ + if(n < pcount) { + return ptable + n; + } else { + return 0; + } +} + +unsigned flash_get_ptn_count(void) +{ + return pcount; +} diff --git a/libboot/gpio_keypad.c b/libboot/gpio_keypad.c new file mode 100644 index 0000000..b1ec7c2 --- /dev/null +++ b/libboot/gpio_keypad.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/gpio.h> +#include <boot/gpio_keypad.h> + +int gpio_keypad_init(gpio_keypad_info *keypad) +{ + unsigned i; + for(i = 0; i < keypad->noutputs; i++) { + gpio_set(keypad->output_gpios[i], keypad->polarity ^ keypad->drive_inactive_outputs); + gpio_dir(keypad->output_gpios[i], keypad->drive_inactive_outputs); + } + for(i = 0; i < keypad->ninputs; i++) { + gpio_dir(keypad->input_gpios[i], 0); + } + keypad->state = 0; + return 0; +} + +void gpio_keypad_scan_keys(gpio_keypad_info *keypad) +{ + unsigned out, in; + unsigned long long keys; + unsigned npolarity = !keypad->polarity; + unsigned int shift; + + keys = 0; + out = keypad->noutputs; + shift = keypad->noutputs * keypad->ninputs; + while(out > 0) { + out--; + if(keypad->drive_inactive_outputs) + gpio_set(keypad->output_gpios[out], !npolarity); + else + gpio_dir(keypad->output_gpios[out], 1); + udelay(keypad->settle_time); + in = keypad->ninputs; + while(in > 0) { + in--; + shift--; + keys = (keys << 1) | (gpio_get(keypad->input_gpios[in]) ^ npolarity); + if(((unsigned)(keypad->state >> shift) ^ (unsigned)keys) & 1) { + unsigned int mapped_key = 0; + if(keypad->key_map) + mapped_key = keypad->key_map[shift]; + //dprintf("gpio_keypad_scan_keys: %d-%d (%d-%d) %d (%d): %d\n", out, in, + // keypad->output_gpios[out], keypad->input_gpios[in], + // shift, mapped_key, keys & 1); + if(mapped_key && key_changed) + key_changed(mapped_key, keys & 1); + } + } + if(keypad->drive_inactive_outputs) + gpio_set(keypad->output_gpios[out], npolarity); + else + gpio_dir(keypad->output_gpios[out], 0); + } + if(keys != keypad->state) { + keypad->state = keys; + //dprintf("gpio_keypad_scan_keys: %x %x\n", (unsigned long)(keys >> 32), (unsigned long)keys); + } +} + diff --git a/libboot/init.c b/libboot/init.c new file mode 100644 index 0000000..3223dda --- /dev/null +++ b/libboot/init.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +char data[3]; + +extern unsigned BOOTLOADER_INIT_FIRST; +extern unsigned BOOTLOADER_INIT_LAST; + +void call_init_hooks() +{ + unsigned x; + for(x = BOOTLOADER_INIT_FIRST; x < BOOTLOADER_INIT_LAST; x += 4) { + int (*hook)(void) = (void*) x; + hook(); + } +} diff --git a/libboot/poll.c b/libboot/poll.c new file mode 100644 index 0000000..4b87140 --- /dev/null +++ b/libboot/poll.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> + +#define MAX_POLL_FUNCS 16 + +typedef void (*poll_func)(void); + +static poll_func poll_funcs[MAX_POLL_FUNCS]; +static unsigned poll_count = 0; + +void boot_register_poll_func(void (*func)(void)) +{ + if(poll_count < MAX_POLL_FUNCS) { + poll_funcs[poll_count++] = func; + } +} + +void boot_poll(void) +{ + unsigned n; + for(n = 0; n < poll_count; n++) { + poll_funcs[n](); + } +} diff --git a/libboot/tags.c b/libboot/tags.c new file mode 100644 index 0000000..3fbf23b --- /dev/null +++ b/libboot/tags.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/tags.h> + +#define DBG(x...) do{}while(0) +//#define DBG(x...) dprintf(x) + +void tags_parse(void *_tags, struct tag_handler *handlers, unsigned count) +{ + unsigned n; + unsigned *tags = _tags; + + DBG("tags_parse %p\n", tags); + + /* make sure there's a CORE marker first */ + if(tags[0] != 2) return; + if(tags[1] != 0x54410001) return; + + for(;;) { + unsigned size = tags[0]; + unsigned type = tags[1]; + + DBG("tags_parse %x %x\n", size, type); + + if(size < 2) break; + + for(n = 0; n < count; n++) { + struct tag_handler *h = handlers + n; + if((h->type == type) || (h->type == 0)) { + h->func(type, (void*) &tags[2], (size - 2) * 4, h->cookie); + break; + } + } + + tags += size; + } +} + diff --git a/libboot/tags_cmdline.c b/libboot/tags_cmdline.c new file mode 100644 index 0000000..4496e53 --- /dev/null +++ b/libboot/tags_cmdline.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/tags.h> +#include <boot/flash.h> + +static void tag_cmdline(unsigned tag, void *data, unsigned bytes, void *cookie) +{ + *((const char **) cookie) = data; +} + +const char *tags_get_cmdline(void *tags) +{ + const char *cmdline = ""; + struct tag_handler h; + + h.type = 0x54410009; + h.func = tag_cmdline; + h.cookie = &cmdline; + + tags_parse(tags, &h, 1); + + return cmdline; +} diff --git a/libboot/tags_partition.c b/libboot/tags_partition.c new file mode 100644 index 0000000..5881a48 --- /dev/null +++ b/libboot/tags_partition.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/tags.h> +#include <boot/flash.h> + +static void ptn_importer(unsigned tag, void *data, unsigned bytes, void *cookie) +{ + struct ptentry *ptn = data; + unsigned n = 0; + + while(bytes >= sizeof(*ptn)) { + flash_add_ptn(ptn); + ptn++; + n++; + bytes -= sizeof(*ptn); + } +} + +static struct tag_handler ptn_handler = { + .type = 0x4d534d70, + .func = ptn_importer, +}; + +void tags_import_partitions(void *tags) +{ + tags_parse(tags, &ptn_handler, 1); +} diff --git a/libboot/tags_revision.c b/libboot/tags_revision.c new file mode 100644 index 0000000..d4eeb40 --- /dev/null +++ b/libboot/tags_revision.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/tags.h> +#include <boot/flash.h> + +static void tag_revision(unsigned tag, void *data, unsigned bytes, void *cookie) +{ + if(bytes == 4) { + memcpy(cookie, data, 4); + } +} + +unsigned tags_get_revision(void *tags) +{ + unsigned n = 0; + struct tag_handler h; + + h.type = 0x54410007; + h.func = tag_revision; + h.cookie = &n; + + tags_parse(tags, &h, 1); + + return n; +} diff --git a/libboot/tags_serialno.c b/libboot/tags_serialno.c new file mode 100644 index 0000000..a647c21 --- /dev/null +++ b/libboot/tags_serialno.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/tags.h> +#include <boot/flash.h> + +static void tag_serialno(unsigned tag, void *data, unsigned bytes, void *cookie) +{ + if(bytes == 8) { + memcpy(cookie, data, 8); + } +} + +void tags_get_serialno(void *tags, void *sn) +{ + struct tag_handler h; + + h.type = 0x54410006; + h.func = tag_serialno; + h.cookie = sn; + + tags_parse(tags, &h, 1); +} diff --git a/libc/Android.mk b/libc/Android.mk new file mode 100644 index 0000000..570bd6e --- /dev/null +++ b/libc/Android.mk @@ -0,0 +1,32 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_ARM_MODE := arm + +LOCAL_SRC_FILES := \ + dprintf.c \ + xprintf.c \ + cprintf.c \ + sprintf.c \ + malloc.c \ + memcmp.c \ + memcpy.c \ + memset.c \ + strcpy.c \ + strlen.c \ + strcmp.c \ + strstr.c \ + crypto.c \ + rsa.c \ + sha.c + +LOCAL_C_INCLUDES := $(call include-path-for, bootloader) +LOCAL_C_INCLUDES += include/mincrypt + +LOCAL_CFLAGS := -O2 -g -W -Wall +LOCAL_CFLAGS += -march=armv6 + +LOCAL_MODULE := libboot_c + +include $(BUILD_RAW_STATIC_LIBRARY) diff --git a/libc/cprintf.c b/libc/cprintf.c new file mode 100644 index 0000000..3f3425b --- /dev/null +++ b/libc/cprintf.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdarg.h> + +#include <boot/boot.h> +#include "libc_private.h" + +void cprintf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + __xprintf(fmt, ap, (void*) console_putc, 0); + va_end(ap); + + console_flush(); +} diff --git a/libc/crypto.c b/libc/crypto.c new file mode 100644 index 0000000..7c3f96c --- /dev/null +++ b/libc/crypto.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include "sha.h" +#include "rsa.h" + +void compute_digest(void *data, unsigned dlen, void *digest_out) +{ + uint8_t *digest = digest_out; + SHA(data, dlen, digest); +} + +int is_signature_okay(void *digest, void *signature, void *pubkey) +{ + return RSA_verify(pubkey, signature, SIGNATURE_SIZE, digest); +} diff --git a/libc/dprintf.c b/libc/dprintf.c new file mode 100644 index 0000000..f54d24b --- /dev/null +++ b/libc/dprintf.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdarg.h> + +#include <boot/boot.h> +#include "libc_private.h" + +static void do_nothing(void) +{ +} + +static void (*dputc)(unsigned) = (void *) do_nothing; +static void (*dflush)(void) = (void *) do_nothing; + +void dprintf_set_putc(void (*func)(unsigned)) +{ + dputc = func; +} +void dprintf_set_flush(void (*func)(void)) +{ + dflush = func; +} + +void dprintf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + __xprintf(fmt, ap, (void*) dputc, 0); + va_end(ap); +} diff --git a/libc/inttypes.h b/libc/inttypes.h new file mode 100644 index 0000000..e6a22e3 --- /dev/null +++ b/libc/inttypes.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _INTTYPES_H_ +#define _INTTYPES_H_ + +typedef unsigned long long uint64_t; +typedef unsigned long uint32_t; +typedef unsigned char uint8_t; +typedef long long int64_t; + +#endif diff --git a/libc/libc_private.h b/libc/libc_private.h new file mode 100644 index 0000000..58fa4b9 --- /dev/null +++ b/libc/libc_private.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LIBC_PRIVATE_H_ +#define _LIBC_PRIVATE_H_ + +void __xprintf(const char *fmt, va_list ap, + void (*xputc)(unsigned n, void *cookie), + void *cookie); + +#endif diff --git a/libc/malloc.c b/libc/malloc.c new file mode 100644 index 0000000..0d2880a --- /dev/null +++ b/libc/malloc.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +extern unsigned BOOTLOADER_HEAP; + +static unsigned __alloc_next = (unsigned) &BOOTLOADER_HEAP; + +void *alloc(unsigned sz) +{ + void *ptr; + + ptr = (void*) __alloc_next; + __alloc_next = (__alloc_next + sz + 31) & (~31); + + return ptr; +} + +void *alloc_page_aligned(unsigned sz) +{ + __alloc_next = (__alloc_next + 4095) & (~4095); + + return alloc(sz); +} + +void func(unsigned n) +{ + __alloc_next *= n; + __alloc_next *= n; +} diff --git a/libc/memcmp.c b/libc/memcmp.c new file mode 100644 index 0000000..e1f83c3 --- /dev/null +++ b/libc/memcmp.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +int memcmp(void *_a, void *_b, unsigned len) +{ + char *a = _a; + char *b = _b; + + while(len-- > 0) { + if(*a++ != *b++) return 1; + } + return 0; +} diff --git a/libc/memcpy.c b/libc/memcpy.c new file mode 100644 index 0000000..9144dae --- /dev/null +++ b/libc/memcpy.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +void *memcpy(void *_dst, const void *_src, unsigned len) +{ + unsigned char *dst = _dst; + const unsigned char *src = _src; + while(len-- > 0) { + *dst++ = *src++; + } + return _dst; +} diff --git a/libc/memset.c b/libc/memset.c new file mode 100644 index 0000000..6886df9 --- /dev/null +++ b/libc/memset.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +void *memset(void *_p, unsigned v, unsigned count) +{ + unsigned char *p = _p; + while(count-- > 0) *p++ = 0; + return _p; +} diff --git a/libc/rsa.c b/libc/rsa.c new file mode 100644 index 0000000..2aea562 --- /dev/null +++ b/libc/rsa.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "rsa.h" +#include "sha.h" + +/* a[] -= mod */ +static void subM(RSAPublicKey *key, uint32_t *a) { + int64_t A = 0; + int i; + for (i = 0; i < key->len; ++i) { + A += (uint64_t)a[i] - key->n[i]; + a[i] = (uint32_t)A; + A >>= 32; + } +} + +/* return a[] >= mod */ +static int geM(RSAPublicKey *key, const uint32_t *a) { + int i; + for (i = key->len; i;) { + --i; + if (a[i] < key->n[i]) return 0; + if (a[i] > key->n[i]) return 1; + } + return 1; /* equal */ +} + +/* montgomery c[] += a * b[] / R % mod */ +static void montMulAdd(RSAPublicKey *key, + uint32_t* c, + const uint32_t a, + const uint32_t* b) { + uint64_t A = (uint64_t)a * b[0] + c[0]; + uint32_t d0 = (uint32_t)A * key->n0inv; + uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A; + int i; + + for (i = 1; i < key->len; ++i) { + A = (A >> 32) + (uint64_t)a * b[i] + c[i]; + B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A; + c[i - 1] = (uint32_t)B; + } + + A = (A >> 32) + (B >> 32); + + c[i - 1] = (uint32_t)A; + + if (A >> 32) { + subM(key, c); + } +} + +/* montgomery c[] = a[] * b[] / R % mod */ +static void montMul(RSAPublicKey *key, + uint32_t* c, + const uint32_t* a, + const uint32_t* b) { + int i; + for (i = 0; i < key->len; ++i) { + c[i] = 0; + } + for (i = 0; i < key->len; ++i) { + montMulAdd(key, c, a[i], b); + } +} + +/* In-place public exponentiation. +** Input and output big-endian byte array in inout. +*/ +static void modpow3(RSAPublicKey *key, + uint8_t* inout) { + uint32_t a[RSANUMWORDS]; + uint32_t aR[RSANUMWORDS]; + uint32_t aaR[RSANUMWORDS]; + uint32_t *aaa = aR; /* Re-use location. */ + int i; + + /* Convert from big endian byte array to little endian word array. */ + for (i = 0; i < key->len; ++i) { + uint32_t tmp = + (inout[((key->len - 1 - i) * 4) + 0] << 24) | + (inout[((key->len - 1 - i) * 4) + 1] << 16) | + (inout[((key->len - 1 - i) * 4) + 2] << 8) | + (inout[((key->len - 1 - i) * 4) + 3] << 0); + a[i] = tmp; + } + + montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */ + montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */ + montMul(key, aaa, aaR, a); /* aaa = aaR * a / R mod M */ + + /* Make sure aaa < mod; aaa is at most 1x mod too large. */ + if (geM(key, aaa)) { + subM(key, aaa); + } + + /* Convert to bigendian byte array */ + for (i = key->len - 1; i >= 0; --i) { + uint32_t tmp = aaa[i]; + *inout++ = tmp >> 24; + *inout++ = tmp >> 16; + *inout++ = tmp >> 8; + *inout++ = tmp >> 0; + } +} + +/* Expected PKCS1.5 signature padding bytes, for a keytool RSA signature. +** Has the 0-length optional parameter encoded in the ASN1 (as opposed to the +** other flavor which omits the optional parameter entirely). This code does not +** accept signatures without the optional parameter. +*/ +static const uint8_t padding[RSANUMBYTES - SHA_DIGEST_SIZE] = { + 0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, + 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00, + 0x04,0x14 +}; + +/* Verify a 2048 bit RSA PKCS1.5 signature against an expected SHA-1 hash. +** Returns 0 on failure, 1 on success. +*/ +int RSA_verify(RSAPublicKey *key, + const uint8_t *signature, + const int len, + const uint8_t *sha) { + uint8_t buf[RSANUMBYTES]; + int i; + + if (key->len != RSANUMWORDS) { + return 0; /* Wrong key passed in. */ + } + + if (len != sizeof(buf)) { + return 0; /* Wrong input length. */ + } + + for (i = 0; i < len; ++i) { + buf[i] = signature[i]; + } + + modpow3(key, buf); + + /* Check pkcs1.5 padding bytes. */ + for (i = 0; i < (int) sizeof(padding); ++i) { + if (buf[i] != padding[i]) { + return 0; + } + } + + /* Check sha digest matches. */ + for (; i < len; ++i) { + if (buf[i] != *sha++) { + return 0; + } + } + + return 1; +} diff --git a/libc/rsa.h b/libc/rsa.h new file mode 100644 index 0000000..ebe3881 --- /dev/null +++ b/libc/rsa.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _EMBEDDED_RSA_H_ +#define _EMBEDDED_RSA_H_ + +#include <inttypes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define RSANUMBYTES 256 /* 2048 bit key length */ +#define RSANUMWORDS (RSANUMBYTES / sizeof(uint32_t)) + +typedef struct RSAPublicKey { + int len; /* Length of n[] in number of uint32_t */ + uint32_t n0inv; /* -1 / n[0] mod 2^32 */ + uint32_t n[RSANUMWORDS]; /* modulus as little endian array */ + uint32_t rr[RSANUMWORDS]; /* R^2 as little endian array */ +} RSAPublicKey; + +int RSA_verify(RSAPublicKey *key, + const uint8_t* signature, + const int len, + const uint8_t* sha); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/sha.c b/libc/sha.c new file mode 100644 index 0000000..69e1f58 --- /dev/null +++ b/libc/sha.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sha.h" + +#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +static void SHA1_transform(SHA_CTX *ctx) { + uint32_t W[80]; + uint32_t A, B, C, D, E; + uint8_t *p = ctx->buf; + int t; + + for(t = 0; t < 16; ++t) { + uint32_t tmp = *p++ << 24; + tmp |= *p++ << 16; + tmp |= *p++ << 8; + tmp |= *p++; + W[t] = tmp; + } + + for(; t < 80; t++) { + W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + } + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + + for(t = 0; t < 80; t++) { + uint32_t tmp = rol(5,A) + E + W[t]; + + if (t < 20) + tmp += (D^(B&(C^D))) + 0x5A827999; + else if ( t < 40) + tmp += (B^C^D) + 0x6ED9EBA1; + else if ( t < 60) + tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC; + else + tmp += (B^C^D) + 0xCA62C1D6; + + E = D; + D = C; + C = rol(30,B); + B = A; + A = tmp; + } + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +void SHA_init(SHA_CTX *ctx) { + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + ctx->count = 0; +} + +void SHA_update(SHA_CTX *ctx, const void *data, int len) { + int i = ctx->count % sizeof(ctx->buf); + const uint8_t* p = (const uint8_t*)data; + + ctx->count += len; + + while (len--) { + ctx->buf[i++] = *p++; + if (i == sizeof(ctx->buf)) { + SHA1_transform(ctx); + i = 0; + } + } +} +const uint8_t *SHA_final(SHA_CTX *ctx) { + uint8_t *p = ctx->buf; + uint64_t cnt = ctx->count * 8; + int i; + + SHA_update(ctx, (uint8_t*)"\x80", 1); + while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) { + SHA_update(ctx, (uint8_t*)"\0", 1); + } + for (i = 0; i < 8; ++i) { + uint8_t tmp = cnt >> ((7 - i) * 8); + SHA_update(ctx, &tmp, 1); + } + + for (i = 0; i < 5; i++) { + uint32_t tmp = ctx->state[i]; + *p++ = tmp >> 24; + *p++ = tmp >> 16; + *p++ = tmp >> 8; + *p++ = tmp >> 0; + } + + return ctx->buf; +} + +/* Convenience function */ +const uint8_t* SHA(const void *data, int len, uint8_t *digest) { + const uint8_t *p; + int i; + SHA_CTX ctx; + SHA_init(&ctx); + SHA_update(&ctx, data, len); + p = SHA_final(&ctx); + for (i = 0; i < SHA_DIGEST_SIZE; ++i) { + digest[i] = *p++; + } + return digest; +} diff --git a/libc/sha.h b/libc/sha.h new file mode 100644 index 0000000..1761a7b --- /dev/null +++ b/libc/sha.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _EMBEDDED_SHA_H_ +#define _EMBEDDED_SHA_H_ + +#include <inttypes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SHA_CTX { + uint64_t count; + uint8_t buf[64]; + uint32_t state[5]; +} SHA_CTX; + +void SHA_init(SHA_CTX *ctx); +void SHA_update(SHA_CTX *ctx, const void* data, int len); +const uint8_t* SHA_final(SHA_CTX *ctx); + +/* Convenience method. Returns digest parameter value. */ +const uint8_t* SHA(const void *data, int len, uint8_t *digest); + +#define SHA_DIGEST_SIZE 20 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/sprintf.c b/libc/sprintf.c new file mode 100644 index 0000000..4075724 --- /dev/null +++ b/libc/sprintf.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdarg.h> + +#include <boot/boot.h> +#include "libc_private.h" + +struct snprintf_ctxt +{ + char *next; + int avail; +}; + +static void snprintf_putc(unsigned n, void *cookie) +{ + struct snprintf_ctxt *ctxt = cookie; + + if(ctxt->avail > 0) { + *ctxt->next++ = n; + ctxt->avail--; + } +} + +int snprintf(char *str, int sz, const char *fmt, ...) +{ + va_list ap; + struct snprintf_ctxt ctxt; + + if(sz < 1) return 0; + + ctxt.avail = sz - 1; + ctxt.next = str; + + va_start(ap, fmt); + __xprintf(fmt, ap, snprintf_putc, &ctxt); + va_end(ap); + + *ctxt.next = 0; + return ctxt.next - str; +} diff --git a/libc/strcmp.c b/libc/strcmp.c new file mode 100644 index 0000000..aa5284a --- /dev/null +++ b/libc/strcmp.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +int strcmp(const char *a, const char *b) +{ + while(*a && *b) { + if(*a++ != *b++) return 1; + } + if(*a || *b) return 1; + return 0; +} diff --git a/libc/strcpy.c b/libc/strcpy.c new file mode 100644 index 0000000..154b256 --- /dev/null +++ b/libc/strcpy.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +char *strcpy(char *dst, const char *src) +{ + char *ret = dst; + while (*dst++ = *src++) ; + return ret; +} diff --git a/libc/strlen.c b/libc/strlen.c new file mode 100644 index 0000000..9a73799 --- /dev/null +++ b/libc/strlen.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +int strlen(const char *s) +{ + int len = 0; + while(*s++) len++; + return len; +} diff --git a/libc/strstr.c b/libc/strstr.c new file mode 100644 index 0000000..2ca92a5 --- /dev/null +++ b/libc/strstr.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> + +char *strstr(const char *s1, const char *s2) +{ + int l1 = strlen(s1); + int l2 = strlen(s2); + + while (l1 >= l2) { + if (memcmp(s1, s2, l2) == 0) { + return s1; + } + s1++; + l1--; + } + return 0; +} diff --git a/libc/xprintf.c b/libc/xprintf.c new file mode 100644 index 0000000..8f0fe94 --- /dev/null +++ b/libc/xprintf.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdarg.h> +#include "libc_private.h" + +static int hex2asc(int n) +{ + n &= 15; + if(n > 9){ + return ('a' - 10) + n; + } else { + return '0' + n; + } +} + +static void xputs(const char *s, void (*xputc)(unsigned n, void *cookie), void *cookie) +{ + while (*s) { + xputc(*s++, cookie); + } +} + +void __xprintf(const char *fmt, va_list ap, + void (*xputc)(unsigned n, void *cookie), + void *cookie) +{ + char scratch[16]; + + for(;;){ + switch(*fmt){ + case 0: + va_end(ap); + return; + case '%': + switch(fmt[1]) { + case 'c': { + unsigned n = va_arg(ap, unsigned); + xputc(n, cookie); + fmt += 2; + continue; + } + case 'h': { + unsigned n = va_arg(ap, unsigned); + xputc(hex2asc(n >> 12), cookie); + xputc(hex2asc(n >> 8), cookie); + xputc(hex2asc(n >> 4), cookie); + xputc(hex2asc(n >> 0), cookie); + fmt += 2; + continue; + } + case 'b': { + unsigned n = va_arg(ap, unsigned); + xputc(hex2asc(n >> 4), cookie); + xputc(hex2asc(n >> 0), cookie); + fmt += 2; + continue; + } + case 'p': + case 'X': + case 'x': { + unsigned n = va_arg(ap, unsigned); + char *p = scratch + 15; + *p = 0; + do { + *--p = hex2asc(n); + n = n >> 4; + } while(n != 0); + while(p > (scratch + 7)) *--p = '0'; + xputs(p, xputc, cookie); + fmt += 2; + continue; + } + case 'd': { + int n = va_arg(ap, int); + char *p = scratch + 15; + *p = 0; + if(n < 0) { + xputc('-', cookie); + n = -n; + } + do { + *--p = (n % 10) + '0'; + n /= 10; + } while(n != 0); + xputs(p, xputc, cookie); + fmt += 2; + continue; + } + case 's': { + char *s = va_arg(ap, char*); + if(s == 0) s = "(null)"; + xputs(s, xputc, cookie); + fmt += 2; + continue; + } + } + xputc(*fmt++, cookie); + break; + case '\n': + xputc('\r', cookie); + default: + xputc(*fmt++, cookie); + } + } +} diff --git a/nandwrite/Android.mk b/nandwrite/Android.mk new file mode 100644 index 0000000..be97da9 --- /dev/null +++ b/nandwrite/Android.mk @@ -0,0 +1,20 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_ARM_MODE := arm + +LOCAL_C_INCLUDES := $(call include-path-for, bootloader mkbootimg) + +LOCAL_SRC_FILES := init.S jtag.c nandwrite.c + +LOCAL_CFLAGS := -O2 -g -W -Wall +LOCAL_CFLAGS += -march=armv6 + +LOCAL_MODULE := nandwrite + +LOCAL_MODULE_PATH := $(PRODUCT_OUT) +LOCAL_STATIC_LIBRARIES := $(TARGET_BOOTLOADER_LIBS) libboot libboot_c + +include $(BUILD_RAW_EXECUTABLE) + +$(LOCAL_BUILT_MODULE) : PRIVATE_LINK_SCRIPT := $(TARGET_BOOTLOADER_LINK_SCRIPT) diff --git a/nandwrite/init.S b/nandwrite/init.S new file mode 100644 index 0000000..c542503 --- /dev/null +++ b/nandwrite/init.S @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/arm.h> + +v_reset: + b start +v_undefined: + b . +v_swi: + b . +v_prefetch_abt: + b . +v_data_abt: + b . +v_reserved: + b . +v_irq: + b . +v_fiq: + b . + +start: + /* save registers for main() */ + mov r7, r0 + mov r8, r1 + mov r9, r2 + mov r10, r3 + + /* init stacks */ + ldr r0, =BOOTLOADER_STACK + msr cpsr_c, #(PSR_I | PSR_F | PSR_SVC) + mov sp, r0 + + /* zero the BSS */ + ldr r1, =BOOTLOADER_BSS + ldr r2, =BOOTLOADER_END + mov r0, #0 +1: str r0, [r1], #4 + cmp r1, r2 + ble 1b + + bl periph_2gb_open + + /* restore registers for main() */ + mov r0, r7 + mov r1, r8 + mov r2, r9 + mov r3, r10 + + ldr r4, =_main + blx r4 + b . diff --git a/nandwrite/jtag.c b/nandwrite/jtag.c new file mode 100644 index 0000000..e91d1e8 --- /dev/null +++ b/nandwrite/jtag.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> + +#define STATUS_NOMSG 0 +#define STATUS_OKAY 1 +#define STATUS_FAIL 2 +#define STATUS_PRINT 3 + +void jtag_hook(); + +volatile unsigned _jtag_cmd = 0; +volatile unsigned _jtag_msg = 0; +unsigned char _jtag_cmd_buffer[128]; +unsigned char _jtag_msg_buffer[128]; + +volatile unsigned _jtag_arg0 = 0; +volatile unsigned _jtag_arg1 = 0; +volatile unsigned _jtag_arg2 = 0; + +static void jtag_msg(unsigned status, const char *msg) +{ + unsigned char *out = _jtag_msg_buffer; + while((*out++ = *msg++) != 0) ; + _jtag_msg = status; + do { + jtag_hook(); + } while(_jtag_msg != 0); +} + +void jtag_okay(const char *msg) +{ + if(msg == 0) msg = "OKAY"; + jtag_msg(STATUS_OKAY, msg); +} + +void jtag_fail(const char *msg) +{ + if(msg == 0) msg = "FAIL"; + jtag_msg(STATUS_FAIL, msg); +} + +int jtag_cmd_pending() +{ + jtag_hook(); + return (int) _jtag_cmd; +} + +void jtag_cmd_loop(void (*do_cmd)(const char *, unsigned, unsigned, unsigned)) +{ + unsigned n; + for(;;) { + if(jtag_cmd_pending()){ + do_cmd((const char*) _jtag_cmd_buffer, _jtag_arg0, _jtag_arg1, _jtag_arg2); + for(n = 0; n < 256; n++) _jtag_cmd_buffer[n] = 0; + _jtag_arg0 = 0; + _jtag_arg1 = 0; + _jtag_arg2 = 0; + _jtag_cmd = 0; + } + } +} + +static char jtag_putc_buffer[128]; +static unsigned jtag_putc_count = 0; + +static void jtag_push_buffer(void) +{ + jtag_putc_buffer[jtag_putc_count] = 0; + jtag_putc_count = 0; + jtag_msg(STATUS_PRINT, jtag_putc_buffer); +} + +void jtag_dputc(unsigned c) +{ + if((c < 32) || (c > 127)) { + if(c == '\n') { + jtag_push_buffer(); + } + return; + } + + jtag_putc_buffer[jtag_putc_count++] = c; + if(jtag_putc_count == 127) { + jtag_push_buffer(); + } +} + diff --git a/nandwrite/nandwrite.c b/nandwrite/nandwrite.c new file mode 100644 index 0000000..c715095 --- /dev/null +++ b/nandwrite/nandwrite.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/board.h> +#include <boot/flash.h> + +#define FLASH_PAGE_SIZE 2048 +#define FLASH_PAGE_BITS 11 + +int startswith(const char *str, const char *prefix) +{ + while(*prefix){ + if(*prefix++ != *str++) return 0; + } + return 1; +} + +void verify_flash(ptentry *p, void *addr, unsigned len, int extra) +{ + int offset = 0; + void *buf = alloc(FLASH_PAGE_SIZE + extra); + int verify_extra = extra; + if(verify_extra > 4) + verify_extra = 16; + while(len > 0) { + flash_read_ext(p, extra, offset, buf, FLASH_PAGE_SIZE); + if(memcmp(addr, buf, FLASH_PAGE_SIZE + verify_extra)) { + dprintf("verify failed at %x\n", offset); + jtag_fail("verify failed"); + return; + } + offset += FLASH_PAGE_SIZE; + addr += FLASH_PAGE_SIZE; + len -= FLASH_PAGE_SIZE; + if(extra) { + addr += extra; + len -= extra; + } + } + dprintf("verify done %d extra bytes\n", verify_extra); + jtag_okay("verify done"); +} + +void handle_flash(const char *name, unsigned addr, unsigned len) +{ + int r; + ptentry *p; + + dprintf("image @ %x (%d bytes)\n", addr, len); + dprintf("write to '%s' partition\n", name); + + p = flash_find_ptn(name); + + if(p == 0) { + jtag_fail("partition not found"); + return; + } else { + if(flash_init()) { + jtag_fail("flash_init() failed"); + return; + } + + dprintf("erasing flash @ %d (len=%d)\n", p->start, p->length); + flash_erase(p); + + if(len) { + dprintf("writing flash at @ %d\n", p->start); + + if(!strcmp(name, "system") || !strcmp(name, "userdata")) { + r = flash_write(p, 64, (void*) addr, len); + } else { + len = (len + FLASH_PAGE_SIZE - 1) & (~(FLASH_PAGE_SIZE-1)); + r = flash_write(p, 0, (void*) addr, len); + } + //verify_flash(p, addr, len, (!strcmp(name, "system") || !strcmp(name, "userdata")) ? 64 : 0); + if(r) { + jtag_fail("partition write failed"); + } else { + jtag_okay("partition written"); + } + return; + } else { + jtag_okay("partition erased"); + return; + } + } +} + +void hexdump(void *ptr, unsigned len) +{ + unsigned char *b = ptr; + int count = 0; + + dprintf("%x: ", (unsigned) b); + while(len-- > 0) { + dprintf("%b ", *b++); + if(++count == 16) { + dprintf("\n%x: ", (unsigned) b); + count = 0; + } + } + if(count != 0) dprintf("\n"); +} + +static unsigned char *tmpbuf = 0; + +void handle_dump(const char *name, unsigned offset) +{ + ptentry *p; + + if(tmpbuf == 0) { + tmpbuf = alloc(4096); + } + + dprintf("dump '%s' partition\n", name); + p = flash_find_ptn(name); + + if(p == 0) { + jtag_fail("partition not found"); + return; + } + + if(flash_init()) { + jtag_fail("flash_init() failed"); + return; + } + +#if 0 + /* XXX reimpl */ + if(flash_read_page(p->start * 64, tmpbuf, tmpbuf + 2048)){ + jtag_fail("flash_read() failed"); + return; + } +#endif + + dprintf("page %d data:\n", p->start * 64); + hexdump(tmpbuf, 256); + dprintf("page %d extra:\n", p->start * 64); + hexdump(tmpbuf, 16); + jtag_okay("done"); +} + +void handle_command(const char *cmd, unsigned a0, unsigned a1, unsigned a2) +{ + if(startswith(cmd,"flash:")){ + handle_flash(cmd + 6, a0, a1); + return; + } + + if(startswith(cmd,"dump:")){ + handle_dump(cmd + 5, a0); + return; + } + + jtag_fail("unknown command"); +} + +int _main(void) +{ + arm11_clock_init(); + + dprintf_set_putc(jtag_dputc); + + board_init(); + + jtag_cmd_loop(handle_command); + + return 0; +} diff --git a/usbloader/Android.mk b/usbloader/Android.mk new file mode 100644 index 0000000..0d7dfef --- /dev/null +++ b/usbloader/Android.mk @@ -0,0 +1,22 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_ARM_MODE := arm + +LOCAL_C_INCLUDES := $(call include-path-for, bootloader) +LOCAL_C_INCLUDES += tools/mkbootimg + +LOCAL_SRC_FILES := init.S main.c usbloader.c + +LOCAL_CFLAGS := -O2 -g -W -Wall +LOCAL_CFLAGS += -march=armv6 +LOCAL_CFLAGS += -DPRODUCTNAME='"$(strip $(TARGET_BOOTLOADER_BOARD_NAME))"' + +LOCAL_MODULE := usbloader + +LOCAL_MODULE_PATH := $(PRODUCT_OUT) +LOCAL_STATIC_LIBRARIES := $(TARGET_BOOTLOADER_LIBS) libboot libboot_c + +include $(BUILD_RAW_EXECUTABLE) + +$(LOCAL_BUILT_MODULE) : PRIVATE_LINK_SCRIPT := $(TARGET_BOOTLOADER_LINK_SCRIPT) diff --git a/usbloader/init.S b/usbloader/init.S new file mode 100644 index 0000000..9d048ea --- /dev/null +++ b/usbloader/init.S @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +.global irq_glue +.global irq_vector_table + +#include <boot/arm.h> + +v_reset: + b start +v_undefined: + b . +v_swi: + b . +v_prefetch_abt: + b . +v_data_abt: + b . +v_reserved: + b . +v_irq: + b . +v_fiq: + b . + +start: + ldr r5, =0xfffff000 + ands r4, pc, r5 + beq already_at_zero + + /* we're not loaded at 0 -- relocate us back down to where we belong */ + mov r5, #0 + ldr r6, =BOOTLOADER_END +1: ldr r7, [r4], #4 + str r7, [r5], #4 + cmp r5, r6 + bne 1b + + mov pc, #0 + +already_at_zero: + /* save registers for main() */ + mov r7, r0 + mov r8, r1 + mov r9, r2 + mov r10, r3 + + /* init stack */ + ldr r0, =BOOTLOADER_STACK + msr cpsr_c, #(PSR_I | PSR_F | PSR_SVC) + mov sp, r0 + + /* zero the BSS */ + ldr r1, =BOOTLOADER_BSS + ldr r2, =BOOTLOADER_END + mov r0, #0 +1: str r0, [r1], #4 + cmp r1, r2 + ble 1b + + bl periph_2gb_open + + /* restore registers for main() */ + mov r0, r7 + mov r1, r8 + mov r2, r9 + mov r3, r10 + + ldr r4, =_main + blx r4 + b . diff --git a/usbloader/main.c b/usbloader/main.c new file mode 100644 index 0000000..490b138 --- /dev/null +++ b/usbloader/main.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/uart.h> +#include <boot/tags.h> +#include <boot/flash.h> +#include <boot/board.h> + +#include <bootimg.h> + +#define FLASH_PAGE_SIZE 2048 +#define FLASH_PAGE_BITS 11 + +#define ADDR_TAGS 0x10000100 + +static void create_atags(unsigned taddr, const char *cmdline, + unsigned raddr, unsigned rsize) +{ + unsigned n = 0; + unsigned pcount; + unsigned *tags = (unsigned *) taddr; + + // ATAG_CORE + tags[n++] = 2; + tags[n++] = 0x54410001; + + if(rsize) { + // ATAG_INITRD2 + tags[n++] = 4; + tags[n++] = 0x54420005; + tags[n++] = raddr; + tags[n++] = rsize; + } + + if((pcount = flash_get_ptn_count())){ + ptentry *ptn; + unsigned pn; + unsigned m = n + 2; + + for(pn = 0; pn < pcount; pn++) { + ptn = flash_get_ptn(pn); + memcpy(tags + m, ptn, sizeof(ptentry)); + m += (sizeof(ptentry) / sizeof(unsigned)); + } + + tags[n + 0] = m - n; + tags[n + 1] = 0x4d534d70; + n = m; + } + if(cmdline && cmdline[0]) { + const char *src; + char *dst; + unsigned len = 0; + + dst = (char*) (tags + n + 2); + src = cmdline; + while((*dst++ = *src++)) len++; + + len++; + len = (len + 3) & (~3); + + // ATAG_CMDLINE + tags[n++] = 2 + (len / 4); + tags[n++] = 0x54410009; + + n += (len / 4); + } + + // ATAG_NONE + tags[n++] = 0; + tags[n++] = 0; +} + +static void boot_linux(unsigned kaddr) +{ + void (*entry)(unsigned,unsigned,unsigned) = (void*) kaddr; + + entry(0, board_machtype(), ADDR_TAGS); +} + +unsigned char raw_header[2048]; + +int boot_linux_from_flash(void) +{ + boot_img_hdr *hdr = (void*) raw_header; + unsigned n; + ptentry *p; + unsigned offset = 0; + const char *cmdline; + + if((p = flash_find_ptn("boot")) == 0) { + cprintf("NO BOOT PARTITION\n"); + return -1; + } + + if(flash_read(p, offset, raw_header, 2048)) { + cprintf("CANNOT READ BOOT IMAGE HEADER\n"); + return -1; + } + offset += 2048; + + if(memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + cprintf("INVALID BOOT IMAGE HEADER\n"); + return -1; + } + + n = (hdr->kernel_size + (FLASH_PAGE_SIZE - 1)) & (~(FLASH_PAGE_SIZE - 1)); + if(flash_read(p, offset, (void*) hdr->kernel_addr, n)) { + cprintf("CANNOT READ KERNEL IMAGE\n"); + return -1; + } + offset += n; + + n = (hdr->ramdisk_size + (FLASH_PAGE_SIZE - 1)) & (~(FLASH_PAGE_SIZE - 1)); + if(flash_read(p, offset, (void*) hdr->ramdisk_addr, n)) { + cprintf("CANNOT READ RAMDISK IMAGE\n"); + return -1; + } + offset += n; + + dprintf("\nkernel @ %x (%d bytes)\n", hdr->kernel_addr, hdr->kernel_size); + dprintf("ramdisk @ %x (%d bytes)\n\n\n", hdr->ramdisk_addr, hdr->ramdisk_size); + + if(hdr->cmdline[0]) { + cmdline = (char*) hdr->cmdline; + } else { + cmdline = board_cmdline(); + if(cmdline == 0) { + cmdline = "mem=50M console=null"; + } + } + cprintf("cmdline = '%s'\n", cmdline); + + cprintf("\nBooting Linux\n"); + + create_atags(ADDR_TAGS, cmdline, + hdr->ramdisk_addr, hdr->ramdisk_size); + + boot_linux(hdr->kernel_addr); + return 0; +} + +void usbloader_init(void); +void uart_putc(unsigned); +const char *get_fastboot_version(void); + +extern unsigned linux_type; +extern unsigned linux_tags; + +static unsigned revision = 0; + +char serialno[32]; + +void dump_smem_info(void); + +static void tag_dump(unsigned tag, void *data, unsigned sz, void *cookie) +{ + dprintf("tag type=%x data=%x size=%x\n", tag, (unsigned) data, sz); +} + +static struct tag_handler tag_dump_handler = { + .func = tag_dump, + .type = 0, +}; + +void xdcc_putc(unsigned x) +{ + while (dcc_putc(x) < 0) ; +} + +#define SERIALNO_STR "androidboot.serialno=" +#define SERIALNO_LEN strlen(SERIALNO_STR) + +static int boot_from_flash = 1; + +void key_changed(unsigned int key, unsigned int down) +{ + if(!down) return; + if(key == BOOT_KEY_STOP_BOOT) boot_from_flash = 0; +} + +static int tags_okay(unsigned taddr) +{ + unsigned *tags = (unsigned*) taddr; + + if(taddr != ADDR_TAGS) return 0; + if(tags[0] != 2) return 0; + if(tags[1] != 0x54410001) return 0; + + return 1; +} + +int _main(unsigned zero, unsigned type, unsigned tags) +{ + const char *cmdline = 0; + int n; + + arm11_clock_init(); + + /* must do this before board_init() so that we + ** use the partition table in the tags if it + ** already exists + */ + if((zero == 0) && (type != 0) && tags_okay(tags)) { + linux_type = type; + linux_tags = tags; + + cmdline = tags_get_cmdline((void*) linux_tags); + + tags_import_partitions((void*) linux_tags); + revision = tags_get_revision((void*) linux_tags); + if(revision == 1) { + console_set_colors(0x03E0, 0xFFFF); + } + if(revision == 2) { + console_set_colors(0x49B2, 0xFFFF); + } + + /* we're running as a second-stage, so wait for interrupt */ + boot_from_flash = 0; + } else { + linux_type = board_machtype(); + linux_tags = 0; + } + + board_init(); + keypad_init(); + + console_init(); + dprintf_set_putc(uart_putc); + + if(linux_tags == 0) { + /* generate atags containing partitions + * from the bootloader, etc + */ + linux_tags = ADDR_TAGS; + create_atags(linux_tags, 0, 0, 0); + } + + if (cmdline) { + char *sn = strstr(cmdline, SERIALNO_STR); + if (sn) { + char *s = serialno; + sn += SERIALNO_LEN; + while (*sn && (*sn != ' ') && ((s - serialno) < 31)) { + *s++ = *sn++; + } + *s++ = 0; + } + } + + cprintf("\n\nUSB FastBoot: V%s\n", get_fastboot_version()); + cprintf("Machine ID: %d v%d\n", linux_type, revision); + cprintf("Build Date: "__DATE__", "__TIME__"\n\n"); + + cprintf("Serial Number: %s\n\n", serialno[0] ? serialno : "UNKNOWN"); + + flash_dump_ptn(); + + flash_init(); + + /* scan the keyboard a bit */ + for(n = 0; n < 50; n++) { + boot_poll(); + } + + if (boot_from_flash) { + cprintf("\n ** BOOTING LINUX FROM FLASH **\n"); + boot_linux_from_flash(); + } + + usbloader_init(); + + for(;;) { + usb_poll(); + } + return 0; +} diff --git a/usbloader/usbloader.c b/usbloader/usbloader.c new file mode 100644 index 0000000..ca7b4fa --- /dev/null +++ b/usbloader/usbloader.c @@ -0,0 +1,535 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <boot/boot.h> +#include <boot/flash.h> +#include <boot/board.h> +#include <boot/usb.h> + +#include <boot/bootimg.h> +#include <boot/tags.h> + +#include <boot/gpio.h> + +#define VERSION "0.5" + +#define REQUIRE_SIGNATURE 0 + +#if REQUIRE_SIGNATURE +unsigned key_engineering[2 + 64 + 64] = { + 64,0x5b022317,-60769447,648742897,-13657530,585562035,591851935, + 454860199,-1809625305,1868200692,-155297008,-1688439840,-1333607631, + -483027189,-2051438457,1030069735,819944365,2133377257,-1978924214, + 2109678622,1974978919,-1811463608,765849268,1984092281,921245328, + -1055062768,1487475997,1209618652,871985152,-611178965,-2057018571, + 335641539,-1196119550,1550548229,-356223887,1909799623,1281016007, + 957001635,1005656532,-1027634024,-1576447610,-1917246637,589192795, + -1137386186,-1958135372,1933245070,64958951,-1820428322,-1577697840, + 1824253519,555306239,-1588272058,-1925773018,1205934271,-836584444, + -1140961670,-185198349,1293769947,37045923,1516796974,-297288651, + 651582073,-1337054592,-543971216,-1706823885,-1040652818,-594113104, + 260093481,-1277656496,56493468,1577037283,773995876,244894933, + -2075797967,783894843,880611008,-1433369702,380946504,-2081431477, + 1377832804,2089455451,-410001201,1245307237,-1228170341,-2062569137, + -1327614308,-1671042654,1242248660,-418803721,40890010,-1806767460, + -1468529145,-1058158532,1243817302,-527795003,175453645,-210650325, + -827053868,-571422860,886300657,2129677324,846504590,-1413102805, + -1287448511,-1991140134,56194155,1375685594,-129884114,1393568535, + -1098719620,-935279550,1717137954,-1782544741,272581921,-669183778, + 584824755,1434974827,-1122387971,-810584927,-2147338547,-937541680, + -313561073,5506366,-1594059648,-1744451574,1896015834,1496367069, + 1742853908,508461291,1905056764 +}; +#endif + +const char *get_fastboot_version(void) +{ + return VERSION; +} + +unsigned linux_type = 0; +unsigned linux_tags = 0; + +unsigned ramdisk_addr = 0x10400000; +unsigned ramdisk_size = 0; +unsigned kernel_addr = 0x10008000; +unsigned kernel_size = 0; + +static void fixup_tags(unsigned *tags, unsigned *out, const char *cmdline) +{ + unsigned *newtags = (unsigned *) 0x10004000; + unsigned *np = newtags; + unsigned n; + char *oldcmdline = ""; + + if(cmdline == 0) cmdline = ""; + + /* CORE */ + *np++ = 2; + *np++ = 0x54410001; + + if(tags != 0) { + while(*tags) { + if(tags[1] == 0x54410001) { + /* skip core tag */ + tags += tags[0]; + } else if((tags[1] == 0x54420005) && (ramdisk_size != 0)) { + /* skip ramdisk if we have one of our own */ + tags += tags[0]; + } else if((tags[1] == 0x54410009) && (cmdline[0])) { + /* skip existing cmdline so we can replace it */ + oldcmdline = (char*) (tags + 2); + tags += tags[0]; + } else { + /* copy any unknown tags */ + n = tags[0]; + while(n-- > 0) { + *np++ = *tags++; + } + } + } + } + + /* create a ramdisk tag if we need to */ + if(ramdisk_size) { + *np++ = 4; + *np++ = 0x54420005; + *np++ = ramdisk_addr; + *np++ = ramdisk_size; + } + + dprintf("cmdline: '%s'\n", oldcmdline); + dprintf("cmdline: '%s'\n", cmdline); + + /* create a cmdline tag if we need to */ + if(cmdline[0]) { + int len; + char *str = (char*) (np + 2); + + len = strlen(oldcmdline); + if(len) { + memcpy(str, oldcmdline, len); + str += len; + *str++ = ' '; + } + + len = strlen(cmdline); + memcpy(str, cmdline, len); + str += len; + *str++ = 0; + + /* length in words */ + len = ((str - ((char*) (np + 2))) + 3) / 4; + + dprintf("CMDLINE: '%s'\n", ((char*) (np + 2))); + + *np++ = 2 + len; + *np++ = 0x54410009; + + np += len; + } + + /* add footer tag */ + *np++ = 0; + *np++ = 0; + + /* copy it all back to the original tags area */ + while(newtags < np) { + *out++ = *newtags++; + } +} + +static char cmdline[BOOT_ARGS_SIZE]; + +static void boot_linux(void) +{ + unsigned *tags = (unsigned*) 0x10000100; + void (*entry)(unsigned,unsigned,unsigned) = (void*) kernel_addr; + + if(linux_type == 0) { + linux_type = board_machtype(); + } + + fixup_tags((unsigned*) linux_tags, tags, cmdline); + + entry(0, linux_type, tags); + + for(;;); +} + +/* convert a boot_image at kernel_addr into a kernel + ramdisk + tags */ +static int init_boot_linux(void) +{ + boot_img_hdr *hdr = (void*) kernel_addr; + unsigned page_mask = 2047; + unsigned kernel_actual; + unsigned ramdisk_actual; + unsigned second_actual; + + if((kernel_size < 2048) || memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)){ + dprintf("bootimg: bad header\n"); + return -1; + } + + if(hdr->page_size != 2048) { + dprintf("bootimg: invalid page size\n"); + return -1; + } + + kernel_actual = (hdr->kernel_size + page_mask) & (~page_mask); + ramdisk_actual = (hdr->ramdisk_size + page_mask) & (~page_mask); + second_actual = (hdr->second_size + page_mask) & (~page_mask); + + if(kernel_size != (kernel_actual + ramdisk_actual + second_actual + 2048)) { + dprintf("bootimg: invalid image size"); + return -1; + } + + /* XXX process commandline here */ + if(hdr->cmdline[0]){ + hdr->cmdline[BOOT_ARGS_SIZE - 1] = 0; + memcpy(cmdline, hdr->cmdline, BOOT_ARGS_SIZE); + } + + /* XXX how to validate addresses? */ + ramdisk_addr = hdr->ramdisk_addr; + ramdisk_size = hdr->ramdisk_size; + + kernel_addr = hdr->kernel_addr; + kernel_size = hdr->kernel_size; + + dprintf("bootimg: kernel addr=%x size=%x\n", + kernel_addr, kernel_size); + dprintf("bootimg: ramdisk addr=%x size=%x\n", + ramdisk_addr, ramdisk_size); + + memcpy((void*) ramdisk_addr, + hdr->magic + 2048 + kernel_actual, + ramdisk_size); + + memcpy((void*) kernel_addr, + hdr->magic + 2048, + kernel_size); + + return 0; +} + +static struct usb_endpoint *ep1in, *ep1out; +static struct usb_request *rx_req, *tx_req; +static unsigned rx_addr; +static unsigned rx_length; + +static char *cmdbuf; + +static void usb_rx_cmd_complete(struct usb_request *req, unsigned actual, int status); +static void usb_rx_data_complete(struct usb_request *req, unsigned actual, int status); + +static void rx_cmd(void) +{ + struct usb_request *req = rx_req; + req->buf = cmdbuf; + req->length = 4096; + req->complete = usb_rx_cmd_complete; + usb_queue_req(ep1out, req); +} + +static void rx_data(void) +{ + struct usb_request *req = rx_req; + req->buf = (void*) rx_addr; + req->length = (rx_length > 4096) ? 4096 : rx_length; + req->complete = usb_rx_data_complete; + usb_queue_req(ep1out, req); +} + +static void tx_status(const char *status) +{ + struct usb_request *req = tx_req; + int len = strlen(status); +// dprintf("tx_status('%s')\n", status); + memcpy(req->buf, status, len); + req->length = len; + req->complete = 0; + usb_queue_req(ep1in, req); +} + +static void usb_rx_data_complete(struct usb_request *req, unsigned actual, int status) +{ + if(status != 0) return; + + if(actual > rx_length) { + actual = rx_length; + } + + rx_addr += actual; + rx_length -= actual; + + if(rx_length > 0) { + rx_data(); + } else { + tx_status("OKAY"); + rx_cmd(); + } +} + +static unsigned hex2unsigned(char *x) +{ + unsigned n = 0; + + while(*x) { + switch(*x) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = (n << 4) | (*x - '0'); + break; + case 'a': case 'b': case 'c': + case 'd': case 'e': case 'f': + n = (n << 4) | (*x - 'a' + 10); + break; + case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': + n = (n << 4) | (*x - 'A' + 10); + break; + default: + return n; + } + x++; + } + + return n; +} + +static void num_to_hex8(unsigned n, char *out) +{ + static char tohex[16] = "0123456789abcdef"; + int i; + for(i = 7; i >= 0; i--) { + out[i] = tohex[n & 15]; + n >>= 4; + } + out[8] = 0; +} + +extern char serialno[]; + +static char signature[SIGNATURE_SIZE]; + +static void usb_rx_cmd_complete(struct usb_request *req, unsigned actual, int status) +{ + if(status != 0) return; + + if(actual > 4095) actual = 4095; + cmdbuf[actual] = 0; + + dprintf("\n> %s\n",cmdbuf); + +// dprintf("usb_rx_cmd_complete() '%s'\n", cmdbuf); + + if(memcmp(cmdbuf, "reboot", 6) == 0) { + tx_status("OKAY"); + rx_cmd(); + mdelay(100); + board_reboot(); + } +#if 0 + if(memcmp(cmdbuf, "debug:", 6) == 0) { + void debug(char *cmd, char *resp); + memcpy(cmdbuf, "OKAY", 5); + tx_status(cmdbuf); + rx_cmd(); + mdelay(5000); + dprintf("NOW!\n"); + debug(cmdbuf + 6, cmdbuf + 4); + return; + } +#endif + if(memcmp(cmdbuf, "getvar:", 7) == 0) { + char response[64]; + strcpy(response,"OKAY"); + + if(!strcmp(cmdbuf + 7, "version")) { + strcpy(response + 4, VERSION); + } else if(!strcmp(cmdbuf + 7, "product")) { + strcpy(response + 4, PRODUCTNAME); + } else if(!strcmp(cmdbuf + 7, "serialno")) { + strcpy(response + 4, serialno); + } else { + board_getvar(cmdbuf + 7, response + 4); + } + tx_status(response); + rx_cmd(); + return; + } + + if(memcmp(cmdbuf, "download:", 9) == 0) { + char status[16]; + rx_addr = kernel_addr; + rx_length = hex2unsigned(cmdbuf + 9); + if (rx_length > (64*1024*1024)) { + tx_status("FAILdata too large"); + rx_cmd(); + return; + } + kernel_size = rx_length; + dprintf("recv data addr=%x size=%x\n", rx_addr, rx_length); + strcpy(status,"DATA"); + num_to_hex8(rx_length, status + 4); + tx_status(status); + rx_data(); + return; + } + + if(memcmp(cmdbuf, "erase:", 6) == 0){ + struct ptentry *ptn; + ptn = flash_find_ptn(cmdbuf + 6); + if(ptn == 0) { + tx_status("FAILpartition does not exist"); + rx_cmd(); + return; + } + dprintf("erasing '%s'\n", ptn->name); + cprintf("erasing '%s'", ptn->name); + if(flash_erase(ptn)) { + tx_status("FAILfailed to erase partition"); + rx_cmd(); + cprintf(" - FAIL\n"); + return; + } else { + dprintf("partition '%s' erased\n", ptn->name); + cprintf(" - OKAY\n"); + } + tx_status("OKAY"); + rx_cmd(); + return; + } + + if(memcmp(cmdbuf, "flash:", 6) == 0){ + struct ptentry *ptn; + int extra = 0; + ptn = flash_find_ptn(cmdbuf + 6); + if(kernel_size == 0) { + tx_status("FAILno image downloaded"); + rx_cmd(); + return; + } + if(ptn == 0) { + tx_status("FAILpartition does not exist"); + rx_cmd(); + return; + } + if(!strcmp(ptn->name,"boot") || !strcmp(ptn->name,"recovery")) { + if(memcmp((void*) kernel_addr, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { + tx_status("FAILimage is not a boot image"); + rx_cmd(); + return; + } + } +#if REQUIRE_SIGNATURE + { + unsigned char digest[DIGEST_SIZE]; + compute_digest((void*) kernel_addr, kernel_size, digest); + if (is_signature_okay(digest, signature, key_engineering)) { + dprintf("verified by engineering key\n"); + } else { + tx_status("FAILsignature did not verify"); + rx_cmd(); + return; + } + } +#endif + if(!strcmp(ptn->name,"system") || !strcmp(ptn->name,"userdata")) { + extra = 64; + } else { + kernel_size = (kernel_size + 2047) & (~2047); + } + dprintf("writing %d bytes to '%s'\n", + kernel_size, ptn->name); + cprintf("writing '%s' (%d bytes)", ptn->name, kernel_size); + if(flash_write(ptn, extra, (void*) kernel_addr, kernel_size)) { + tx_status("FAILflash write failure"); + rx_cmd(); + cprintf(" - FAIL\n"); + return; + } else { + dprintf("partition '%s' updated\n", ptn->name); + cprintf(" - OKAY\n"); + } + tx_status("OKAY"); + rx_cmd(); + return; + } + if(memcmp(cmdbuf, "boot", 4) == 0) { + if(init_boot_linux()) { + tx_status("FAILinvalid boot image"); + rx_cmd(); + return; + } + dprintf("booting linux...\n"); + cprintf("\nbooting linux...\n"); + tx_status("OKAY"); + mdelay(10); + usb_shutdown(); + boot_linux(); + return; + } + if(memcmp(cmdbuf, "signature", 9) == 0) { + if (kernel_size != SIGNATURE_SIZE) { + tx_status("FAILsignature not 256 bytes long"); + rx_cmd(); + return; + } + memcpy(signature, (void*)kernel_addr, SIGNATURE_SIZE); + tx_status("OKAY"); + rx_cmd(); + return; + } + + tx_status("FAILinvalid command"); + rx_cmd(); +} + +void usb_status(unsigned online, unsigned highspeed) +{ + if(online) { + dprintf("usb: online (%s)\n", highspeed ? "highspeed" : "fullspeed"); + rx_cmd(); + } +} + +void usbloader_init(void) +{ + usb_init(); + + ep1out = usb_endpoint_alloc(1, 0, 512); + ep1in = usb_endpoint_alloc(1, 1, 512); + rx_req = usb_request_alloc(4096); + tx_req = usb_request_alloc(4096); + cmdbuf = rx_req->buf; + + boot_register_poll_func(usb_poll); +} |