patch-2.3.30 linux/arch/alpha/kernel/setup.c
Next file: linux/arch/alpha/kernel/smp.c
Previous file: linux/arch/alpha/kernel/ptrace.c
Back to the patch index
Back to the overall index
- Lines: 326
- Date:
Thu Dec 2 15:20:56 1999
- Orig file:
v2.3.29/linux/arch/alpha/kernel/setup.c
- Orig date:
Tue Nov 23 22:42:20 1999
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
@@ -119,12 +119,14 @@
WEAK(eb64p_mv);
WEAK(eb66_mv);
WEAK(eb66p_mv);
+WEAK(eiger_mv);
WEAK(jensen_mv);
WEAK(lx164_mv);
WEAK(miata_mv);
WEAK(mikasa_mv);
WEAK(mikasa_primo_mv);
WEAK(monet_mv);
+WEAK(nautilus_mv);
WEAK(noname_mv);
WEAK(noritake_mv);
WEAK(noritake_primo_mv);
@@ -189,33 +191,32 @@
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
#define PFN_MAX PFN_DOWN(0x80000000)
-static void __init setup_memory(void)
+#define for_each_mem_cluster(memdesc, cluster, i) \
+ for ((cluster) = (memdesc)->cluster, (i) = 0; \
+ (i) < (memdesc)->numclusters; (i)++, (cluster)++)
+
+static void __init
+setup_memory(void)
{
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
- unsigned long start_pfn, bootmap_size;
+ unsigned long start_pfn, bootmap_size, bootmap_pages, bootmap_start;
+ unsigned long start, end;
extern char _end[];
int i;
- /* alloc the bootmem after the kernel */
- start_pfn = PFN_UP(virt_to_phys(_end));
- SRM_printf("_end %p\n", _end);
-
- /* find free clusters, and init and free the bootmem accordingly */
- memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb);
-
- for (cluster = memdesc->cluster, i = memdesc->numclusters;
- i > 0; i--, cluster++)
- {
- unsigned long end;
+ /* Find free clusters, and init and free the bootmem accordingly. */
+ memdesc = (struct memdesc_struct *)
+ (hwrpb->mddt_offset + (unsigned long) hwrpb);
- printk("memcluster %d, usage %02lx, start %8lu, end %8lu\n",
+ for_each_mem_cluster(memdesc, cluster, i) {
+ printk("memcluster %d, usage %01lx, start %8lu, end %8lu\n",
i, cluster->usage, cluster->start_pfn,
- cluster->numpages);
+ cluster->start_pfn + cluster->numpages);
/* Bit 0 is console/PALcode reserved. Bit 1 is
non-volatile memory -- we might want to mark
- this for later */
+ this for later. */
if (cluster->usage & 3)
continue;
@@ -223,41 +224,89 @@
if (end > max_low_pfn)
max_low_pfn = end;
}
+
/* Enforce maximum of 2GB even if there is more. Blah. */
if (max_low_pfn > PFN_MAX)
max_low_pfn = PFN_MAX;
- SRM_printf("max_low_pfn %d\n", max_low_pfn);
+ printk("max_low_pfn %ld\n", max_low_pfn);
- /* allocate the bootmem array after the kernel and mark
- the whole MM as reserved */
- bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+ /* Find the end of the kernel memory. */
+ start_pfn = PFN_UP(virt_to_phys(_end));
+ printk("_end %p, start_pfn %ld\n", _end, start_pfn);
- for (cluster = memdesc->cluster, i = memdesc->numclusters;
- i > 0; i--, cluster++)
- {
- unsigned long end, start;
+ bootmap_start = -1;
- /* Bit 0 is console/PALcode reserved. Bit 1 is
- non-volatile memory -- we might want to mark
- this for later */
+ try_again:
+ if (max_low_pfn <= start_pfn)
+ panic("not enough memory to boot");
+
+ /* We need to know how many physically contigous pages
+ we'll need for the bootmap. */
+ bootmap_pages = bootmem_bootmap_pages(max_low_pfn);
+ printk("bootmap size: %ld pages\n", bootmap_pages);
+
+ /* Now find a good region where to allocate the bootmap. */
+ for_each_mem_cluster(memdesc, cluster, i) {
if (cluster->usage & 3)
continue;
- start = PFN_PHYS(cluster->start_pfn);
- if (start < PFN_PHYS(start_pfn) + bootmap_size)
- start = PFN_PHYS(start_pfn) + bootmap_size;
- if (PFN_DOWN(start) >= PFN_MAX)
+ start = cluster->start_pfn;
+ end = start + cluster->numpages;
+ if (end <= start_pfn)
continue;
+ if (start >= max_low_pfn)
+ continue;
+ if (start < start_pfn)
+ start = start_pfn;
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+ if (end - start >= bootmap_pages) {
+ printk("allocating bootmap in area %ld:%ld\n",
+ start, start+bootmap_pages);
+ bootmap_start = start;
+ break;
+ }
+ }
+
+ if (bootmap_start == -1) {
+ max_low_pfn >>= 1;
+ printk("bootmap area not found now trying with %ld pages\n",
+ max_low_pfn);
+ goto try_again;
+ }
- end = PFN_PHYS(cluster->start_pfn + cluster->numpages);
- if (PFN_DOWN(end) > PFN_MAX)
- end = PFN_PHYS(PFN_MAX);
+ /* Allocate the bootmap and mark the whole MM as reserved. */
+ bootmap_size = init_bootmem(bootmap_start, max_low_pfn);
+
+ /* Mark the free regions. */
+ for_each_mem_cluster(memdesc, cluster, i) {
+ if (cluster->usage & 3)
+ continue;
+
+ start = cluster->start_pfn;
+ if (start < start_pfn)
+ start = start_pfn;
+
+ end = cluster->start_pfn + cluster->numpages;
+ if (end > max_low_pfn)
+ end = max_low_pfn;
if (start >= end)
continue;
- free_bootmem(start, end-start);
+
+ start = PFN_PHYS(start);
+ end = PFN_PHYS(end);
+
+ free_bootmem(start, end - start);
+ printk("freeing pages %ld:%ld\n",
+ PFN_UP(start), PFN_DOWN(end));
}
+ /* Reserve the bootmap memory. */
+ reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size);
+ printk("reserving bootmap %ld:%ld\n", bootmap_start,
+ bootmap_start + PFN_UP(bootmap_size));
+
#ifdef CONFIG_BLK_DEV_INITRD
initrd_start = INITRD_START;
if (initrd_start) {
@@ -268,14 +317,38 @@
if (initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
printk("initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- initrd_end, phys_to_virt(PFN_PHYS(max_low_pfn)));
+ initrd_end,
+ phys_to_virt(PFN_PHYS(max_low_pfn)));
initrd_start = initrd_end = 0;
+ } else {
+ reserve_bootmem(virt_to_phys(initrd_start),
+ INITRD_SIZE);
}
- else
- reserve_bootmem(virt_to_phys(initrd_start), INITRD_SIZE);
}
#endif /* CONFIG_BLK_DEV_INITRD */
}
+
+int __init page_is_ram(unsigned long pfn)
+{
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
+ int i;
+
+ memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb);
+ for_each_mem_cluster(memdesc, cluster, i)
+ {
+ if (pfn >= cluster->start_pfn &&
+ pfn < cluster->start_pfn + cluster->numpages)
+ {
+ if (cluster->usage & 3)
+ return 0;
+ else
+ return 1;
+ }
+ }
+
+ return 0;
+}
#undef PFN_UP
#undef PFN_DOWN
#undef PFN_PHYS
@@ -288,7 +361,7 @@
struct percpu_struct *cpu;
char *type_name, *var_name, *p;
- hwrpb = (struct hwrpb_struct*)(IDENT_ADDR + INIT_HWRPB->phys_addr);
+ hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
/*
* Locate the command line.
@@ -346,19 +419,16 @@
type_name, (*var_name ? " variation " : ""), var_name,
hwrpb->sys_type, hwrpb->sys_variation);
}
- if (vec != &alpha_mv)
+ if (vec != &alpha_mv) {
alpha_mv = *vec;
-
+ }
+
#ifdef CONFIG_ALPHA_GENERIC
/* Assume that we've booted from SRM if we havn't booted from MILO.
Detect the later by looking for "MILO" in the system serial nr. */
alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
#endif
- SRM_printf("Booting on %s%s%s using machine vector %s\n",
- type_name, (*var_name ? " variation " : ""),
- var_name, alpha_mv.vector_name);
-
printk("Booting "
#ifdef CONFIG_ALPHA_GENERIC
"GENERIC "
@@ -446,11 +516,13 @@
"Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
"Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
"Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
- "Tsunami", "Wildfire", "CUSCO"
+ "Tsunami", "Wildfire", "CUSCO", "Eiger"
};
static char unofficial_names[][8] = {"100", "Ruffian"};
+static char api_names[][16] = {"200", "Nautilus"};
+
static char eb164_names[][8] = {"EB164", "PC164", "LX164", "SX164", "RX164"};
static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,4};
@@ -474,7 +546,6 @@
};
static int tsunami_indices[] = {0,1,2,3,4,5,6,7,8};
-
static struct alpha_machine_vector * __init
get_sysvec(long type, long variation, long cpu)
{
@@ -517,6 +588,7 @@
NULL, /* Tsunami -- see variation. */
NULL, /* Wildfire */
NULL, /* CUSCO */
+ &eiger_mv, /* Eiger */
};
static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata =
@@ -525,6 +597,12 @@
&ruffian_mv,
};
+ static struct alpha_machine_vector *api_vecs[] __initlocaldata =
+ {
+ NULL, /* 200 */
+ &nautilus_mv,
+ };
+
static struct alpha_machine_vector *alcor_vecs[] __initlocaldata =
{
&alcor_mv, &xlt_mv, &xlt_mv
@@ -573,6 +651,9 @@
vec = NULL;
if (type < N(systype_vecs)) {
vec = systype_vecs[type];
+ } else if ((type > ST_API_BIAS) &&
+ (type - ST_API_BIAS) < N(api_vecs)) {
+ vec = api_vecs[type - ST_API_BIAS];
} else if ((type > ST_UNOFFICIAL_BIAS) &&
(type - ST_UNOFFICIAL_BIAS) < N(unofficial_vecs)) {
vec = unofficial_vecs[type - ST_UNOFFICIAL_BIAS];
@@ -646,12 +727,14 @@
&eb64p_mv,
&eb66_mv,
&eb66p_mv,
+ &eiger_mv,
&jensen_mv,
&lx164_mv,
&miata_mv,
&mikasa_mv,
&mikasa_primo_mv,
&monet_mv,
+ &nautilus_mv,
&noname_mv,
&noritake_mv,
&noritake_primo_mv,
@@ -692,6 +775,9 @@
else set type name to family */
if (type < N(systype_names)) {
*type_name = systype_names[type];
+ } else if ((type > ST_API_BIAS) &&
+ (type - ST_API_BIAS) < N(api_names)) {
+ *type_name = api_names[type - ST_API_BIAS];
} else if ((type > ST_UNOFFICIAL_BIAS) &&
(type - ST_UNOFFICIAL_BIAS) < N(unofficial_names)) {
*type_name = unofficial_names[type - ST_UNOFFICIAL_BIAS];
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)