xref: /openbsd-src/sys/arch/loongson/loongson/hibernate_machdep.c (revision 2df12b22ee779d3f10995325e7cbd0d4be5705a0)
1 /*	$OpenBSD: hibernate_machdep.c,v 1.8 2015/05/05 02:13:46 guenther Exp $	*/
2 
3 /*
4  * Copyright (c) 2013 Paul Irofti.
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 
20 #include <sys/param.h>
21 #include <sys/buf.h>
22 #include <sys/conf.h>
23 #include <sys/device.h>
24 #include <sys/disk.h>
25 #include <sys/disklabel.h>
26 #include <sys/hibernate.h>
27 #include <sys/timeout.h>
28 #include <sys/malloc.h>
29 
30 #include <uvm/uvm_extern.h>
31 #include <uvm/uvm_pmemrange.h>
32 
33 #include <mips64/cache.h>
34 
35 #include <machine/hibernate.h>
36 #include <machine/hibernate_var.h>
37 #include <machine/kcore.h>
38 #include <machine/pmap.h>
39 #include <machine/memconf.h>
40 
41 #include "wd.h"
42 #include "ahci.h"
43 #include "softraid.h"
44 #include "sd.h"
45 
46 #if NWD > 0
47 #include <dev/ata/atavar.h>
48 #include <dev/ata/wdvar.h>
49 #endif
50 
51 /*
52  * Loongson MD Hibernate functions
53  *
54  * see Loongson hibernate.h for lowmem layout used during hibernate
55  */
56 
57 /*
58  * Returns the hibernate write I/O function to use on this machine
59  */
60 hibio_fn
get_hibernate_io_function(dev_t dev)61 get_hibernate_io_function(dev_t dev)
62 {
63 	char *blkname = findblkname(major(dev));
64 
65 	if (blkname == NULL)
66 		return NULL;
67 
68 #if NWD > 0
69 	if (strcmp(blkname, "wd") == 0)
70 		return wd_hibernate_io;
71 #endif
72 #if NSD > 0
73 	if (strcmp(blkname, "sd") == 0) {
74 		extern struct cfdriver sd_cd;
75 		extern int ahci_hibernate_io(dev_t dev, daddr_t blkno,
76 		    vaddr_t addr, size_t size, int op, void *page);
77 		extern int sr_hibernate_io(dev_t dev, daddr_t blkno,
78 		    vaddr_t addr, size_t size, int op, void *page);
79 		struct device *dv = disk_lookup(&sd_cd, DISKUNIT(dev));
80 
81 #if NAHCI > 0
82 		if (dv && dv->dv_parent && dv->dv_parent->dv_parent &&
83 		    strcmp(dv->dv_parent->dv_parent->dv_cfdata->cf_driver->cd_name,
84 		    "ahci") == 0)
85 			return ahci_hibernate_io;
86 #endif
87 #if NSOFTRAID > 0
88 		if (dv && dv->dv_parent && dv->dv_parent->dv_parent &&
89 		    strcmp(dv->dv_parent->dv_parent->dv_cfdata->cf_driver->cd_name,
90 		    "softraid") == 0)
91 			return sr_hibernate_io;
92 	}
93 #endif
94 #endif /* NSD > 0 */
95 	return NULL;
96 }
97 
98 /*
99  * Gather MD-specific data and store into hiber_info
100  */
101 int
get_hibernate_info_md(union hibernate_info * hiber_info)102 get_hibernate_info_md(union hibernate_info *hiber_info)
103 {
104 	int i;
105 
106 	/* Calculate memory ranges */
107 	hiber_info->nranges = 0;
108 	hiber_info->image_size = 0;
109 
110 	for (i = 0; i < MAXMEMSEGS && mem_layout[i].mem_last_page != 0; i++) {
111 		/* XXX: Adjust for stolen pages later */
112 		hiber_info->ranges[i].base =
113 		    mem_layout[i].mem_first_page >> PAGE_SHIFT;
114 		hiber_info->ranges[i].end =
115 		    mem_layout[i].mem_last_page >> PAGE_SHIFT;
116 		hiber_info->image_size +=
117 		    hiber_info->ranges[i].end - hiber_info->ranges[i].base;
118 		hiber_info->nranges++;
119 	}
120 
121 	return (0);
122 }
123 
124 /*
125  * Enter a mapping for va->pa in the resume pagetable
126  */
127 void
hibernate_enter_resume_mapping(vaddr_t va,paddr_t pa,int size)128 hibernate_enter_resume_mapping(vaddr_t va, paddr_t pa, int size)
129 {
130 	/* XXX TBD */
131 }
132 
133 /*
134  * Create the resume-time page table. This table maps the image(pig) area,
135  * the kernel text area, and various utility pages for use during resume,
136  * since we cannot overwrite the resuming kernel's page table during inflate
137  * and expect things to work properly.
138  */
139 void
hibernate_populate_resume_pt(union hibernate_info * hib_info,paddr_t image_start,paddr_t image_end)140 hibernate_populate_resume_pt(union hibernate_info *hib_info,
141     paddr_t image_start, paddr_t image_end)
142 {
143 	/* XXX TBD */
144 }
145 
146 /*
147  * During inflate, certain pages that contain our bookkeeping information
148  * (eg, the chunk table, scratch pages, etc) need to be skipped over and
149  * not inflated into.
150  *
151  * Returns 1 if the physical page at dest should be skipped, 0 otherwise
152  */
153 int
hibernate_inflate_skip(union hibernate_info * hib_info,paddr_t dest)154 hibernate_inflate_skip(union hibernate_info *hib_info, paddr_t dest)
155 {
156 	if (dest >= hib_info->piglet_pa &&
157 	    dest <= (hib_info->piglet_pa + 4 * HIBERNATE_CHUNK_SIZE))
158 		return (1);
159 
160 	return (0);
161 }
162 
163 void
hibernate_enable_intr_machdep(void)164 hibernate_enable_intr_machdep(void)
165 {
166 	enableintr();
167 }
168 
169 void
hibernate_disable_intr_machdep(void)170 hibernate_disable_intr_machdep(void)
171 {
172 	disableintr();
173 }
174 
175 void
hibernate_flush(void)176 hibernate_flush(void)
177 {
178 	Mips_SyncCache(curcpu());
179 }
180