1 /* $OpenBSD: rd.c,v 1.5 2020/12/09 18:10:19 krw Exp $ */
2
3 /*
4 * Copyright (c) 2010 Miodrag Vallat.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/param.h>
20 #include "libsa.h"
21 #include <machine/cpu.h>
22 #include <sys/exec_elf.h>
23
24 static off_t rdoffs;
25
26 /*
27 * INITRD I/O
28 */
29
30 int
rd_iostrategy(void * f,int rw,daddr_t dblk,size_t size,void * buf,size_t * rsize)31 rd_iostrategy(void *f, int rw, daddr_t dblk, size_t size, void *buf,
32 size_t *rsize)
33 {
34 /* never invoked directly */
35 return ENXIO;
36 }
37
38 int
rd_ioopen(struct open_file * f,...)39 rd_ioopen(struct open_file *f, ...)
40 {
41 return 0;
42 }
43
44 int
rd_ioclose(struct open_file * f)45 rd_ioclose(struct open_file *f)
46 {
47 return 0;
48 }
49
50 int
rd_isvalid()51 rd_isvalid()
52 {
53 Elf64_Ehdr *elf64 = (Elf64_Ehdr *)INITRD_BASE;
54
55 if (memcmp(elf64->e_ident, ELFMAG, SELFMAG) != 0 ||
56 elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
57 elf64->e_ident[EI_DATA] != ELFDATA2LSB ||
58 elf64->e_type != ET_EXEC || elf64->e_machine != EM_MIPS)
59 return 0;
60
61 return 1;
62 }
63
64 void
rd_invalidate()65 rd_invalidate()
66 {
67 bzero((void *)INITRD_BASE, sizeof(Elf64_Ehdr));
68 }
69
70 /*
71 * INITRD filesystem
72 */
73 int
rdfs_open(char * path,struct open_file * f)74 rdfs_open(char *path, struct open_file *f)
75 {
76 if (f->f_dev->dv_open == rd_ioopen) {
77 if (strcmp(path, kernelfile) == 0) {
78 rdoffs = 0;
79 return 0;
80 } else
81 return ENOENT;
82 }
83
84 return EINVAL;
85 }
86
87 int
rdfs_close(struct open_file * f)88 rdfs_close(struct open_file *f)
89 {
90 return 0;
91 }
92
93 int
rdfs_read(struct open_file * f,void * buf,size_t size,size_t * resid)94 rdfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
95 {
96 if (size != 0) {
97 bcopy((void *)(INITRD_BASE + rdoffs), buf, size);
98 rdoffs += size;
99 }
100 *resid = 0;
101
102 return 0;
103 }
104
105 int
rdfs_write(struct open_file * f,void * buf,size_t size,size_t * resid)106 rdfs_write(struct open_file *f, void *buf, size_t size, size_t *resid)
107 {
108 return EROFS;
109 }
110
111 off_t
rdfs_seek(struct open_file * f,off_t offset,int whence)112 rdfs_seek(struct open_file *f, off_t offset, int whence)
113 {
114 switch (whence) {
115 case 0: /* SEEK_SET */
116 rdoffs = offset;
117 break;
118 case 1: /* SEEK_CUR */
119 rdoffs += offset;
120 break;
121 default:
122 errno = EIO;
123 return -1;
124 }
125
126 return rdoffs;
127 }
128
129 int
rdfs_stat(struct open_file * f,struct stat * sb)130 rdfs_stat(struct open_file *f, struct stat *sb)
131 {
132 return EIO;
133 }
134
135 #ifndef NO_READDIR
136 int
rdfs_readdir(struct open_file * f,char * path)137 rdfs_readdir(struct open_file *f, char *path)
138 {
139 return EIO;
140 }
141 #endif
142