1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <aboot/aboot.h> 30#include <aboot/io.h> 31#include <omap4/mux.h> 32#include <omap4/hw.h> 33#include <omap4/omap4_rom.h> 34#include "protocol.h" 35 36#define min(a,b) ( ((a) < (b)) ? (a) : (b) ) 37 38struct usb usb; 39 40unsigned cfg_machine_type = 2791; 41 42int load_from_usb(u32 *_len, u32 *_addr, u32 *_entry) 43{ 44 u32 len, addr, entry, msg; 45 46 if (usb_open(&usb)) { 47 printf("failed to open usb\n"); 48 return -1; 49 } 50 51 msg = ABOOT_IS_READY; 52 usb_write(&usb, &msg, sizeof(msg)); 53 54 for (;;) { 55 len = addr = 0x0; 56 57 usb_read(&usb, &len, 4); 58 if (len == ABOOT_NO_MORE_DATA) { 59 printf("OK, no more data\n"); 60 break; 61 } 62 usb_read(&usb, &addr, 4); 63 usb_read(&usb, &entry, 4); 64 65 printf("Entry point is %08X\n", entry); 66 printf("Reading %d bytes to %08X\n", len, addr); 67 68 *_addr = addr; 69 *_len = len; 70 *_entry = entry; 71 72 u32 to_read= len; 73 void *read_ptr= (void *)addr; 74 size_t chunk= 0; 75 while(to_read > 0) { 76 /* Read a chunk. */ 77 u32 this_chunk= min(to_read, CHUNK_SIZE); 78 if(usb_read(&usb, read_ptr, this_chunk)) { 79 printf("usb_read failed\n"); 80 return -1; 81 } 82 to_read -= this_chunk; 83 read_ptr += this_chunk; 84 85 /* Acknowledge reception. */ 86 msg= chunk; 87 usb_write(&usb, &msg, sizeof(msg)); 88 chunk++; 89 } 90 } 91 92 usb_close(&usb); 93 return 0; 94} 95 96static void __attribute__((noreturn)) 97boot_image(u32 entry_point) { 98 void (*entry)(u32, u32, u32, u32)= (void *)entry_point; 99 100 printf("jumping to 0x%08X...\n", entry_point); 101 entry(0, 0, 0, 0); 102 for (;;); 103} 104 105void __attribute__((noreturn)) 106aboot(unsigned *info) { 107 unsigned n; 108 u32 len, addr = CONFIG_ADDR_DOWNLOAD, entry; 109 110 board_mux_init(); 111 sdelay(100); 112 113 scale_vcores(); 114 prcm_init(); 115 board_ddr_init(); 116 gpmc_init(); 117 board_late_init(); 118 119 serial_init(); 120 121 serial_puts("\n[ aboot second-stage loader ]\n\n"); 122 123 n = load_from_usb(&len, &addr, &entry); 124 printf("load complete\n"); 125 if (n) { 126 serial_puts("*** IO ERROR ***\n"); 127 } else { 128 printf("starting!\n"); 129 boot_image(entry); 130 } 131 132 for (;;) ; 133} 134 135