| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: autoconf.c,v 1.22 2009/03/18 10:22:26 cegger Exp $ */ | | 1 | /* $NetBSD: autoconf.c,v 1.23 2010/10/27 10:42:12 kiyohara Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1990 The Regents of the University of California. | | 4 | * Copyright (c) 1990 The Regents of the University of California. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * William Jolitz. | | 8 | * William Jolitz. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -27,135 +27,223 @@ | | | @@ -27,135 +27,223 @@ |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 | * SUCH DAMAGE. | | 32 | * SUCH DAMAGE. |
33 | * | | 33 | * |
34 | * @(#)autoconf.c 7.1 (Berkeley) 5/9/91 | | 34 | * @(#)autoconf.c 7.1 (Berkeley) 5/9/91 |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | /* | | 37 | /* |
38 | * Setup the system to run on the current machine. | | 38 | * Setup the system to run on the current machine. |
39 | * | | 39 | * |
40 | * Configure() is called at boot time and initializes the vba | | 40 | * Configure() is called at boot time and initializes the vba |
41 | * device tables and the memory controller monitoring. Available | | 41 | * device tables and the memory controller monitoring. Available |
42 | * devices are determined (from possibilities mentioned in ioconf.c), | | 42 | * devices are determined (from possibilities mentioned in ioconf.c), |
43 | * and the drivers are initialized. | | 43 | * and the drivers are initialized. |
44 | */ | | 44 | */ |
45 | | | 45 | |
46 | #include <sys/cdefs.h> | | 46 | #include <sys/cdefs.h> |
47 | __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.22 2009/03/18 10:22:26 cegger Exp $"); | | 47 | __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.23 2010/10/27 10:42:12 kiyohara Exp $"); |
48 | | | 48 | |
49 | #include <sys/param.h> | | 49 | #include <sys/param.h> |
50 | #include <sys/systm.h> | | 50 | #include <sys/systm.h> |
51 | #include <sys/buf.h> | | 51 | #include <sys/buf.h> |
| | | 52 | #include <sys/disk.h> |
52 | #include <sys/disklabel.h> | | 53 | #include <sys/disklabel.h> |
53 | #include <sys/conf.h> | | 54 | #include <sys/conf.h> |
54 | #include <sys/reboot.h> | | 55 | #include <sys/reboot.h> |
55 | #include <sys/device.h> | | 56 | #include <sys/device.h> |
56 | #include <sys/malloc.h> | | 57 | #include <sys/malloc.h> |
57 | #include <sys/queue.h> | | 58 | #include <sys/queue.h> |
58 | | | 59 | |
59 | #include "pci.h" | | 60 | #include "pci.h" |
60 | #if NPCI > 0 | | 61 | #if NPCI > 0 |
61 | #include <dev/pci/pcireg.h> | | 62 | #include <dev/pci/pcireg.h> |
62 | #include <dev/pci/pcivar.h> | | 63 | #include <dev/pci/pcivar.h> |
63 | #endif | | 64 | #endif |
| | | 65 | #include <dev/ata/atareg.h> |
| | | 66 | #include <dev/ata/atavar.h> |
| | | 67 | #include <dev/ata/wdvar.h> |
| | | 68 | #include <dev/scsipi/sdvar.h> |
64 | | | 69 | |
| | | 70 | #include <machine/bootinfo.h> |
65 | #include <machine/pte.h> | | 71 | #include <machine/pte.h> |
66 | #include <machine/intr.h> | | 72 | #include <machine/intr.h> |
67 | | | 73 | |
68 | void genppc_cpu_configure(void); | | 74 | void genppc_cpu_configure(void); |
69 | static void findroot(void); | | 75 | static void findroot(void); |
70 | | | 76 | |
| | | 77 | static int bus, target, lun, drive; |
| | | 78 | static const char *name = NULL; |
| | | 79 | |
71 | /* | | 80 | /* |
72 | * Determine i/o configuration for a machine. | | 81 | * Determine i/o configuration for a machine. |
73 | */ | | 82 | */ |
74 | | | 83 | |
75 | void | | 84 | void |
76 | cpu_configure(void) | | 85 | cpu_configure(void) |
77 | { | | 86 | { |
78 | | | 87 | |
| | | 88 | findroot(); |
| | | 89 | |
79 | if (config_rootfound("mainbus", NULL) == NULL) | | 90 | if (config_rootfound("mainbus", NULL) == NULL) |
80 | panic("configure: mainbus not configured"); | | 91 | panic("configure: mainbus not configured"); |
81 | | | 92 | |
82 | genppc_cpu_configure(); | | 93 | genppc_cpu_configure(); |
83 | } | | 94 | } |
84 | | | 95 | |
85 | void | | 96 | void |
86 | cpu_rootconf(void) | | 97 | cpu_rootconf(void) |
87 | { | | 98 | { |
88 | findroot(); | | | |
89 | | | 99 | |
90 | aprint_normal("boot device: %s\n", | | 100 | aprint_normal("boot device: %s\n", |
91 | booted_device ? booted_device->dv_xname : "<unknown>"); | | 101 | booted_device ? booted_device->dv_xname : "<unknown>"); |
92 | | | 102 | |
93 | setroot(booted_device, booted_partition); | | 103 | setroot(booted_device, booted_partition); |
94 | } | | 104 | } |
95 | | | 105 | |
96 | u_long bootdev = 0; /* should be dev_t, but not until 32 bits */ | | | |
97 | | | | |
98 | /* | | 106 | /* |
99 | * Attempt to find the device from which we were booted. | | 107 | * Attempt to find the device from which we were booted. |
100 | * If we can do so, and not instructed not to do so, | | 108 | * If we can do so, and not instructed not to do so, |
101 | * change rootdev to correspond to the load device. | | 109 | * change rootdev to correspond to the load device. |
102 | */ | | 110 | */ |
103 | void | | 111 | static void |
104 | findroot(void) | | 112 | findroot(void) |
105 | { | | 113 | { |
106 | int unit, part; | | 114 | struct btinfo_rootdevice *rdev; |
107 | device_t dv; | | 115 | int part; |
108 | const char *name; | | 116 | char *p; |
109 | | | 117 | |
110 | if ((bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) | | 118 | rdev = (struct btinfo_rootdevice *)lookup_bootinfo(BTINFO_ROOTDEVICE); |
111 | return; | | 119 | if (rdev == NULL) |
112 | | | 120 | return; |
113 | name = devsw_blk2name((bootdev >> B_TYPESHIFT) & B_TYPEMASK); | | 121 | p = rdev->rootdevice; |
114 | if (name == NULL) | | 122 | if (strncmp(p, "/dev/disk/", 10) != 0) |
115 | return; | | 123 | /* unknwon device... */ |
116 | | | 124 | return; |
117 | part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; | | 125 | p += 10; |
118 | unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; | | 126 | if (strncmp(p, "scsi/", 5) == 0) { |
119 | | | 127 | name = "sd"; |
120 | if ((dv = device_find_by_driver_unit(name, unit)) != NULL) { | | 128 | p += 5; |
121 | booted_device = dv; | | 129 | |
122 | booted_partition = part; | | 130 | bus = 0; |
123 | } | | 131 | while (isdigit(*p)) |
| | | 132 | bus = bus * 10 + (*p++) - '0'; |
| | | 133 | if (*p++ != '/') |
| | | 134 | return; |
| | | 135 | target = 0; |
| | | 136 | while (isdigit(*p)) |
| | | 137 | target = target * 10 + (*p++) - '0'; |
| | | 138 | if (*p++ != '/') |
| | | 139 | return; |
| | | 140 | lun = 0; |
| | | 141 | while (isdigit(*p)) |
| | | 142 | lun = lun * 10 + (*p++) - '0'; |
| | | 143 | } else if (strncmp(p, "ide/", 4) == 0) { |
| | | 144 | name = "wd"; |
| | | 145 | p += 4; |
| | | 146 | |
| | | 147 | bus = 0; |
| | | 148 | while (isdigit(*p)) |
| | | 149 | bus = bus * 10 + (*p++) - '0'; |
| | | 150 | if (*p++ != '/') |
| | | 151 | return; |
| | | 152 | if (strncmp(p, "master/0", 8) == 0) { |
| | | 153 | drive = 0; |
| | | 154 | p += 8; |
| | | 155 | } else if (strncmp(p, "slave/0", 7) == 0) { |
| | | 156 | drive = 1; |
| | | 157 | p += 7; |
| | | 158 | } else |
| | | 159 | return; |
| | | 160 | } else if (strcmp(p, "floppy") == 0) |
| | | 161 | return; |
| | | 162 | else |
| | | 163 | /* unknwon disk... */ |
| | | 164 | return; |
| | | 165 | |
| | | 166 | if (*p != '_' || !isdigit(*(p + 1))) |
| | | 167 | return; |
| | | 168 | p++; |
| | | 169 | part = 0; |
| | | 170 | while (isdigit(*p)) |
| | | 171 | part = part * 10 + (*p++) - '0'; |
| | | 172 | if (p != '\0') |
| | | 173 | return; |
| | | 174 | |
| | | 175 | booted_partition = part; |
124 | } | | 176 | } |
125 | | | 177 | |
126 | void | | 178 | void |
127 | device_register(struct device *dev, void *aux) | | 179 | device_register(device_t dev, void *aux) |
128 | { | | 180 | { |
| | | 181 | device_t bdev, cdev; |
129 | | | 182 | |
130 | #if NPCI > 0 | | 183 | #if NPCI > 0 |
131 | if (device_is_a(dev, "genfb") && | | 184 | if (device_is_a(dev, "genfb") && |
132 | device_is_a(device_parent(dev), "pci")) { | | 185 | device_is_a(device_parent(dev), "pci")) { |
133 | prop_dictionary_t dict = device_properties(dev); | | 186 | prop_dictionary_t dict = device_properties(dev); |
134 | struct pci_attach_args *pa = aux; | | 187 | struct pci_attach_args *pa = aux; |
135 | pcireg_t bar0; | | 188 | pcireg_t bar0; |
136 | uint32_t fbaddr; | | 189 | uint32_t fbaddr; |
137 | | | 190 | |
138 | bar0 = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START); | | 191 | bar0 = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START); |
139 | fbaddr = PCI_MAPREG_MEM_ADDR(bar0); | | 192 | fbaddr = PCI_MAPREG_MEM_ADDR(bar0); |
140 | | | 193 | |
141 | prop_dictionary_set_bool(dict, "is_console", 1); | | 194 | prop_dictionary_set_bool(dict, "is_console", 1); |
142 | prop_dictionary_set_uint32(dict, "width", 640); | | 195 | prop_dictionary_set_uint32(dict, "width", 640); |
143 | prop_dictionary_set_uint32(dict, "height", 480); | | 196 | prop_dictionary_set_uint32(dict, "height", 480); |
144 | prop_dictionary_set_uint32(dict, "depth", 8); | | 197 | prop_dictionary_set_uint32(dict, "depth", 8); |
145 | prop_dictionary_set_uint32(dict, "address", fbaddr); | | 198 | prop_dictionary_set_uint32(dict, "address", fbaddr); |
146 | } | | 199 | } |
147 | | | 200 | |
148 | if (device_is_a(dev, "siop") && | | 201 | if (device_is_a(dev, "siop") && |
149 | device_is_a(device_parent(dev), "pci")) { | | 202 | device_is_a(device_parent(dev), "pci")) { |
150 | prop_dictionary_t dict = device_properties(dev); | | 203 | prop_dictionary_t dict = device_properties(dev); |
151 | struct pci_attach_args *pa = aux; | | 204 | struct pci_attach_args *pa = aux; |
152 | int bus, device; | | 205 | int pbus, device; |
153 | | | 206 | |
154 | pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &device, NULL); | | 207 | pci_decompose_tag(pa->pa_pc, pa->pa_tag, &pbus, &device, NULL); |
155 | if (bus == 0 && device == 12) | | 208 | if (pbus == 0 && device == 12) |
156 | /* Internal SCSI uses PCI clock as SCSI clock */ | | 209 | /* Internal SCSI uses PCI clock as SCSI clock */ |
157 | prop_dictionary_set_bool(dict, "use_pciclock", 1); | | 210 | prop_dictionary_set_bool(dict, "use_pciclock", 1); |
158 | } | | 211 | } |
159 | #endif | | 212 | #endif |
| | | 213 | |
| | | 214 | if (booted_device != NULL) |
| | | 215 | return; |
| | | 216 | /* |
| | | 217 | * Check boot device. |
| | | 218 | * It is sd/wd connected by the onboard controller to be supported. |
| | | 219 | */ |
| | | 220 | if (device_is_a(dev, "sd") && strcmp(name, "sd") == 0) { |
| | | 221 | struct scsipibus_attach_args *sa = aux; |
| | | 222 | |
| | | 223 | bdev = device_parent(dev); |
| | | 224 | if (!device_is_a(bdev, "scsibus")) |
| | | 225 | return; |
| | | 226 | cdev = device_parent(bdev); |
| | | 227 | if (!device_is_a(cdev, "siop")) |
| | | 228 | return; |
| | | 229 | |
| | | 230 | if (sa->sa_periph->periph_target == target && |
| | | 231 | sa->sa_periph->periph_lun == lun) |
| | | 232 | booted_device = dev; |
| | | 233 | } else if (device_is_a(dev, "wd") && strcmp(name, "wd") == 0) { |
| | | 234 | struct ata_device *adev = aux; |
| | | 235 | |
| | | 236 | bdev = device_parent(dev); |
| | | 237 | if (!device_is_a(bdev, "atabus")) |
| | | 238 | return; |
| | | 239 | cdev = device_parent(bdev); |
| | | 240 | if (!device_is_a(cdev, "wdc")) |
| | | 241 | return; |
| | | 242 | if (!device_is_a(device_parent(cdev), "isa")) |
| | | 243 | return; |
| | | 244 | |
| | | 245 | if (adev->adev_drv_data->drive == drive) |
| | | 246 | booted_device = dev; |
| | | 247 | } |
160 | } | | 248 | } |
161 | | | 249 | |