1 /* $NetBSD: raw.c,v 1.1 2011/01/26 01:18:54 pooka Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code was written by Alessandro Forin and Neil Pittman 8 * at Microsoft Research and contributed to The NetBSD Foundation 9 * by Microsoft Corporation. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <lib/libsa/stand.h> 34 #include <lib/libkern/libkern.h> 35 #include <machine/stdarg.h> 36 #include <machine/emipsreg.h> 37 38 #include <sys/param.h> 39 #include <sys/disklabel.h> 40 #include <sys/endian.h> 41 42 #include "common.h" 43 #include "raw.h" 44 #include "ace.h" 45 46 /* Used to parse strings of the form "a0/99/badface" all hex 47 */ 48 49 static inline int hexnum(char c) 50 { 51 if (c >= '0' && c <= '9') 52 return c - '0'; 53 if (c >= 'a' && c <= 'f') 54 return c - 'a'; 55 if (c >= 'A' && c <= 'F') 56 return c - 'A'; 57 return -1; 58 } 59 60 static char *getxnum(char *s, uint32_t *dest) 61 { 62 uint32_t u = 0; 63 char c; 64 int v = -1; 65 66 if ((c = *s++) == '/') 67 c = *s++; 68 while (c && c != '/') { 69 v = hexnum(c); 70 if (v < 0) 71 break; 72 u = (u << 4) + v; 73 c = *s++; 74 } 75 /* did we get any */ 76 if (v < 0) 77 return NULL; 78 *dest = u; 79 return s-1; 80 } 81 82 /* rawopen("", ctlr, unit, part); 83 */ 84 int 85 rawopen(struct open_file *f, ...) 86 { 87 int ctlr, unit, part; 88 char *file, *cp; 89 uint32_t start_sector, sector_count, load_address; 90 int er; 91 size_t cnt; 92 va_list ap; 93 94 va_start(ap, f); 95 96 ctlr = va_arg(ap, int); 97 unit = va_arg(ap, int); 98 part = va_arg(ap, int); 99 file = va_arg(ap, char *); 100 va_end(ap); 101 102 /* See if we have that controller */ 103 er = aceopen(f,ctlr,unit,part); 104 if (er != 0) 105 return er; 106 107 /* The string in FILE must tell us three things.. */ 108 cp = file; 109 cp = getxnum(cp,&start_sector); 110 if (cp == NULL) goto Bad; 111 cp = getxnum(cp,§or_count); 112 if (cp == NULL) goto Bad; 113 cp = getxnum(cp,&load_address); 114 if (cp == NULL) goto Bad; 115 116 //printf("%s -> %u %u %p\n", file, start_sector, sector_count, load_address); 117 118 /* Read them sectors */ 119 er = acestrategy(f->f_devdata, F_READ, start_sector, DEV_BSIZE * sector_count, 120 (void *) load_address, &cnt); 121 #ifndef LIBSA_NO_DEV_CLOSE 122 /* regardless, close the disk */ 123 aceclose(f); 124 #endif 125 /* How did it go, are we still alive */ 126 if (er != 0) 127 return er; 128 129 /* Ok, say it and do it then. */ 130 printf("Read %u sectors from sector %u at %x, jumping to it..\n", 131 sector_count, start_sector, load_address); 132 133 call_kernel(load_address,"raw","",0,NULL); 134 135 Bad: 136 #ifndef LIBSA_NO_DEV_CLOSE 137 /* regardless, close it */ 138 aceclose(f); 139 #endif 140 return (ENXIO); 141 } 142 143 #ifndef LIBSA_NO_DEV_CLOSE 144 int 145 rawclose(struct open_file *f) 146 { 147 /* Never gets here */ 148 return (0); 149 } 150 #endif 151 152 int 153 rawstrategy( 154 void *devdata, 155 int rw, 156 daddr_t bn, 157 size_t reqcnt, 158 void *addr, 159 size_t *cnt) /* out: number of bytes transfered */ 160 { 161 /* Never gets here */ 162 return (EIO); 163 } 164 165