1/* $NetBSD: raw.c,v 1.3 2021/07/24 21:31:32 andvar 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/emipsreg.h> 36 37#include <sys/param.h> 38#include <sys/disklabel.h> 39#include <sys/endian.h> 40 41#include "common.h" 42#include "raw.h" 43#include "ace.h" 44 45/* Used to parse strings of the form "a0/99/badface" all hex 46 */ 47 48static inline int hexnum(char c) 49{ 50 if (c >= '0' && c <= '9') 51 return c - '0'; 52 if (c >= 'a' && c <= 'f') 53 return c - 'a'; 54 if (c >= 'A' && c <= 'F') 55 return c - 'A'; 56 return -1; 57} 58 59static char *getxnum(char *s, uint32_t *dest) 60{ 61 uint32_t u = 0; 62 char c; 63 int v = -1; 64 65 if ((c = *s++) == '/') 66 c = *s++; 67 while (c && c != '/') { 68 v = hexnum(c); 69 if (v < 0) 70 break; 71 u = (u << 4) + v; 72 c = *s++; 73 } 74 /* did we get any */ 75 if (v < 0) 76 return NULL; 77 *dest = u; 78 return s-1; 79} 80 81/* rawopen("", ctlr, unit, part); 82 */ 83int 84rawopen(struct open_file *f, ...) 85{ 86 int ctlr, unit, part; 87 char *file, *cp; 88 uint32_t start_sector, sector_count, load_address; 89 int er; 90 size_t cnt; 91 va_list ap; 92 93 va_start(ap, f); 94 95 ctlr = va_arg(ap, int); 96 unit = va_arg(ap, int); 97 part = va_arg(ap, int); 98 file = va_arg(ap, char *); 99 va_end(ap); 100 101 /* See if we have that controller */ 102 er = aceopen(f,ctlr,unit,part); 103 if (er != 0) 104 return er; 105 106 /* The string in FILE must tell us three things.. */ 107 cp = file; 108 cp = getxnum(cp,&start_sector); 109 if (cp == NULL) goto Bad; 110 cp = getxnum(cp,§or_count); 111 if (cp == NULL) goto Bad; 112 cp = getxnum(cp,&load_address); 113 if (cp == NULL) goto Bad; 114 115 //printf("%s -> %u %u %p\n", file, start_sector, sector_count, load_address); 116 117 /* Read them sectors */ 118 er = acestrategy(f->f_devdata, F_READ, start_sector, DEV_BSIZE * sector_count, 119 (void *) load_address, &cnt); 120#ifndef LIBSA_NO_DEV_CLOSE 121 /* regardless, close the disk */ 122 aceclose(f); 123#endif 124 /* How did it go, are we still alive */ 125 if (er != 0) 126 return er; 127 128 /* Ok, say it and do it then. */ 129 printf("Read %u sectors from sector %u at %x, jumping to it..\n", 130 sector_count, start_sector, load_address); 131 132 call_kernel(load_address,"raw","",0,NULL); 133 134 Bad: 135#ifndef LIBSA_NO_DEV_CLOSE 136 /* regardless, close it */ 137 aceclose(f); 138#endif 139 return (ENXIO); 140} 141 142#ifndef LIBSA_NO_DEV_CLOSE 143int 144rawclose(struct open_file *f) 145{ 146 /* Never gets here */ 147 return (0); 148} 149#endif 150 151int 152rawstrategy( 153 void *devdata, 154 int rw, 155 daddr_t bn, 156 size_t reqcnt, 157 void *addr, 158 size_t *cnt) /* out: number of bytes transferred */ 159{ 160 /* Never gets here */ 161 return (EIO); 162} 163 164