[patch] alpha port 2.3.29pre3

Andrea Arcangeli (andrea@suse.de)
Tue, 23 Nov 1999 16:11:01 +0100 (CET)


The common code changes I did are these:

1) I need an hook (resource_fixup()) in the middle of
find_resource() because on Alpha some magic
alignment on the PCI base addresses must be enforced
(or there's no way to boot).

2) in the pci code the sysdata must be copied on
all PCI devices and bridges before playing with
the device. This also allowed me to simplify
the alpha code that was taking the sysdata stored in
an ugly static variable to handle the first pcibios opeartions
(probing_hose). (on i386 this make no difference
as the sysdata is NULL there)

3) pci_claim_resource() must be called with the resource
set just with the secondary pci offsets or
pci_find_parent_resource() will have no way to find
the right root in first place.

4) On 64 bit arch the top of the bus space must be set to ~0UL so
we'll have a chance to open the pci window correctly.

5) after we'll find the right pci window of the pci bus
in pbus_set_ranges() we must convert the
phsical address to the bus address and this is done
with a per arch hook called pcibios_fixup_ranges().

6) the releasing of the initrd memory is buggy in
2.3.29pre3 since the addition of the bootmem allocator.
I fixed this on both i386 and Alpha (never tried this
initrd stuff though but looks ok now ;)

Of course tell me if you don't agree on some of the above points.

Everything else is alpha related and basically does:

o PCI updates
o bootmem initialization
o highmem pte/VM stuff

This is the patch I did to make Alpha working fine (here ;) on 2.3.29pre3:

diff -urN 2.3.29pre3/arch/alpha/boot/bootp.c alpha/arch/alpha/boot/bootp.c
--- 2.3.29pre3/arch/alpha/boot/bootp.c Tue Jul 13 02:02:03 1999
+++ alpha/arch/alpha/boot/bootp.c Mon Nov 22 23:15:10 1999
@@ -200,11 +200,11 @@
load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);

- memset((char*)ZERO_PAGE(0), 0, PAGE_SIZE);
- strcpy((char*)ZERO_PAGE(0), envval);
+ memset((char*)ZERO_PGE, 0, PAGE_SIZE);
+ strcpy((char*)ZERO_PGE, envval);
#ifdef INITRD_SIZE
- ((long *)(ZERO_PAGE(0)+256))[0] = initrd_start;
- ((long *)(ZERO_PAGE(0)+256))[1] = INITRD_SIZE;
+ ((long *)(ZERO_PGE+256))[0] = initrd_start;
+ ((long *)(ZERO_PGE+256))[1] = INITRD_SIZE;
#endif

runkernel();
diff -urN 2.3.29pre3/arch/alpha/boot/main.c alpha/arch/alpha/boot/main.c
--- 2.3.29pre3/arch/alpha/boot/main.c Tue Jul 13 02:02:03 1999
+++ alpha/arch/alpha/boot/main.c Mon Nov 22 23:15:10 1999
@@ -182,7 +182,7 @@
nbytes = 0;
}
envval[nbytes] = '\0';
- strcpy((char*)ZERO_PAGE(0), envval);
+ strcpy((char*)ZERO_PGE, envval);

srm_printk(" Ok\nNow booting the kernel\n");
runkernel();
diff -urN 2.3.29pre3/arch/alpha/kernel/alpha_ksyms.c alpha/arch/alpha/kernel/alpha_ksyms.c
--- 2.3.29pre3/arch/alpha/kernel/alpha_ksyms.c Sun Nov 21 03:20:16 1999
+++ alpha/arch/alpha/kernel/alpha_ksyms.c Tue Nov 23 14:31:19 1999
@@ -27,7 +27,7 @@
#include <asm/fpu.h>
#include <asm/irq.h>
#include <asm/machvec.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/semaphore.h>

#define __KERNEL_SYSCALLS__
diff -urN 2.3.29pre3/arch/alpha/kernel/core_apecs.c alpha/arch/alpha/kernel/core_apecs.c
--- 2.3.29pre3/arch/alpha/kernel/core_apecs.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/core_apecs.c Mon Nov 22 23:15:10 1999
@@ -357,7 +357,7 @@
};

void __init
-apecs_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+apecs_init_arch(void)
{
struct pci_controler *hose;

@@ -386,7 +386,7 @@
* Create our single hose.
*/

- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = APECS_CONF;
diff -urN 2.3.29pre3/arch/alpha/kernel/core_cia.c alpha/arch/alpha/kernel/core_cia.c
--- 2.3.29pre3/arch/alpha/kernel/core_cia.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/core_cia.c Mon Nov 22 23:15:10 1999
@@ -315,7 +315,7 @@
};

void __init
-cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+cia_init_arch(void)
{
struct pci_controler *hose;
struct resource *hae_mem;
@@ -424,8 +424,8 @@
* Create our single hose.
*/

- hose = alloc_pci_controler(mem_start);
- hae_mem = alloc_resource(mem_start);
+ hose = alloc_pci_controler();
+ hae_mem = alloc_resource();

hose->io_space = &ioport_resource;
hose->mem_space = hae_mem;
diff -urN 2.3.29pre3/arch/alpha/kernel/core_lca.c alpha/arch/alpha/kernel/core_lca.c
--- 2.3.29pre3/arch/alpha/kernel/core_lca.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/core_lca.c Mon Nov 22 23:15:10 1999
@@ -279,7 +279,7 @@
};

void __init
-lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+lca_init_arch(void)
{
struct pci_controler *hose;

@@ -307,7 +307,7 @@
* Create our single hose.
*/

- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = LCA_CONF;
diff -urN 2.3.29pre3/arch/alpha/kernel/core_mcpcia.c alpha/arch/alpha/kernel/core_mcpcia.c
--- 2.3.29pre3/arch/alpha/kernel/core_mcpcia.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/core_mcpcia.c Mon Nov 22 23:15:10 1999
@@ -205,7 +205,7 @@
static int
mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr, w;
unsigned char type1;

@@ -221,7 +221,7 @@
static int
mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr, w;
unsigned char type1;

@@ -237,7 +237,7 @@
static int
mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
unsigned char type1;

@@ -252,7 +252,7 @@
static int
mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
unsigned char type1;

@@ -327,16 +327,16 @@
}

static void __init
-mcpcia_new_hose(unsigned long *mem_start, int h)
+mcpcia_new_hose(int h)
{
struct pci_controler *hose;
struct resource *io, *mem, *hae_mem;
int mid = hose2mid(h);

- hose = alloc_pci_controler(mem_start);
- io = alloc_resource(mem_start);
- mem = alloc_resource(mem_start);
- hae_mem = alloc_resource(mem_start);
+ hose = alloc_pci_controler();
+ io = alloc_resource();
+ mem = alloc_resource();
+ hae_mem = alloc_resource();

hose->io_space = io;
hose->mem_space = hae_mem;
@@ -420,7 +420,7 @@
}

void __init
-mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+mcpcia_init_arch(void)
{
extern asmlinkage void entInt(void);
struct pci_controler *hose;
@@ -437,7 +437,7 @@
/* First, find how many hoses we have. */
for (h = 0; h < MCPCIA_MAX_HOSES; ++h) {
if (mcpcia_probe_hose(h)) {
- mcpcia_new_hose(mem_start, h);
+ mcpcia_new_hose(h);
hose_count++;
}
}
diff -urN 2.3.29pre3/arch/alpha/kernel/core_polaris.c alpha/arch/alpha/kernel/core_polaris.c
--- 2.3.29pre3/arch/alpha/kernel/core_polaris.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/core_polaris.c Mon Nov 22 23:15:10 1999
@@ -176,7 +176,7 @@
};

void __init
-polaris_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+polaris_init_arch(void)
{
struct pci_controler *hose;

@@ -192,7 +192,7 @@
* Create our single hose.
*/

- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = POLARIS_DENSE_CONFIG_BASE;
diff -urN 2.3.29pre3/arch/alpha/kernel/core_pyxis.c alpha/arch/alpha/kernel/core_pyxis.c
--- 2.3.29pre3/arch/alpha/kernel/core_pyxis.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/core_pyxis.c Mon Nov 22 23:15:10 1999
@@ -285,7 +285,7 @@
};

void __init
-pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+pyxis_init_arch(void)
{
struct pci_controler *hose;
unsigned int temp;
@@ -379,7 +379,7 @@
* Create our single hose.
*/

- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = PYXIS_CONF;
diff -urN 2.3.29pre3/arch/alpha/kernel/core_t2.c alpha/arch/alpha/kernel/core_t2.c
--- 2.3.29pre3/arch/alpha/kernel/core_t2.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/core_t2.c Mon Nov 22 23:15:10 1999
@@ -322,7 +322,7 @@
};

void __init
-t2_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+t2_init_arch(void)
{
struct pci_controler *hose;
unsigned int i;
@@ -384,7 +384,7 @@
* Create our single hose.
*/

- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = T2_CONF;
diff -urN 2.3.29pre3/arch/alpha/kernel/core_tsunami.c alpha/arch/alpha/kernel/core_tsunami.c
--- 2.3.29pre3/arch/alpha/kernel/core_tsunami.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/core_tsunami.c Mon Nov 22 23:15:10 1999
@@ -84,7 +84,7 @@
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
@@ -154,6 +154,7 @@
return PCIBIOS_DEVICE_NOT_FOUND;

__kernel_stb(value, *(vucp)addr);
+ mb();
return PCIBIOS_SUCCESSFUL;
}

@@ -167,6 +168,7 @@
return PCIBIOS_DEVICE_NOT_FOUND;

__kernel_stw(value, *(vusp)addr);
+ mb();
return PCIBIOS_SUCCESSFUL;
}

@@ -180,6 +182,7 @@
return PCIBIOS_DEVICE_NOT_FOUND;

*(vuip)addr = value;
+ mb();
return PCIBIOS_SUCCESSFUL;
}

@@ -243,31 +246,37 @@
#define FN __FUNCTION__

static void __init
-tsunami_init_one_pchip(tsunami_pchip *pchip, int index,
- unsigned long *mem_start)
+tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
{
struct pci_controler *hose;

if (tsunami_probe_read(&pchip->pctl.csr) == 0)
return;

- hose = alloc_pci_controler(mem_start);
- hose->io_space = alloc_resource(mem_start);
- hose->mem_space = alloc_resource(mem_start);
+ hose = alloc_pci_controler();
+ hose->io_space = alloc_resource();
+ hose->mem_space = alloc_resource();

hose->config_space = TSUNAMI_CONF(index);
hose->index = index;

hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS;
- hose->io_space->end = hose->io_space->start + 0xffff;
+ hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE;
hose->io_space->name = pci_io_names[index];
+ hose->io_space->flags = IORESOURCE_IO;

hose->mem_space->start = TSUNAMI_MEM(index) - TSUNAMI_MEM_BIAS;
+ /* the IOMEM address space is larger than 32bit but most pci
+ cars doesn't support 64bit address space so we stick with
+ 32bit here (see the TSUNAMI_MEM_SPACE define). */
hose->mem_space->end = hose->mem_space->start + 0xffffffff;
hose->mem_space->name = pci_mem_names[index];
+ hose->mem_space->flags = IORESOURCE_MEM;

- request_resource(&ioport_resource, hose->io_space);
- request_resource(&iomem_resource, hose->mem_space);
+ if (request_resource(&ioport_resource, hose->io_space) < 0)
+ printk(KERN_ERR "failed to request IO on hose %d", index);
+ if (request_resource(&iomem_resource, hose->mem_space) < 0)
+ printk(KERN_ERR "failed to request IOMEM on hose %d", index);

/*
* Set up the PCI->physical memory translation windows.
@@ -294,7 +303,7 @@
}

void __init
-tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+tsunami_init_arch(void)
{
#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
extern asmlinkage void entInt(void);
@@ -338,9 +347,9 @@
/* Find how many hoses we have, and initialize them. TSUNAMI
and TYPHOON can have 2, but might only have 1 (DS10). */

- tsunami_init_one_pchip(TSUNAMI_pchip0, 0, mem_start);
+ tsunami_init_one_pchip(TSUNAMI_pchip0, 0);
if (TSUNAMI_cchip->csc.csr & 1L<<14)
- tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start);
+ tsunami_init_one_pchip(TSUNAMI_pchip1, 1);
}

static inline void
diff -urN 2.3.29pre3/arch/alpha/kernel/machvec_impl.h alpha/arch/alpha/kernel/machvec_impl.h
--- 2.3.29pre3/arch/alpha/kernel/machvec_impl.h Tue Nov 23 00:11:55 1999
+++ alpha/arch/alpha/kernel/machvec_impl.h Tue Nov 23 04:17:20 1999
@@ -7,6 +7,7 @@
*/

#include <linux/config.h>
+#include <asm/pgalloc.h>

/* Whee. Both TSUNAMI and POLARIS don't have an HAE. Fix things up for
the GENERIC kernel by defining the HAE address to be that of the cache.
diff -urN 2.3.29pre3/arch/alpha/kernel/pci.c alpha/arch/alpha/kernel/pci.c
--- 2.3.29pre3/arch/alpha/kernel/pci.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/pci.c Tue Nov 23 14:55:12 1999
@@ -6,10 +6,14 @@
* David Mosberger (davidm@cs.arizona.edu)
*/

+/* 2.3.x PCI/resources, 1999 Andrea Arcangeli <andrea@suse.de> */
+
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/bootmem.h>
#include <asm/machvec.h>

#include "proto.h"
@@ -36,7 +40,6 @@
*/

struct pci_controler *hose_head, **hose_tail = &hose_head;
-struct pci_controler *probing_hose;

/*
* Quirks.
@@ -62,24 +65,93 @@
{ 0 }
};

+#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
+#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
+#define KB 1024
+#define MB (1024*KB)
+#define GB (1024*MB)
+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
+ unsigned long start, unsigned long size)
+{
+ unsigned long alignto;
+
+ if (res->flags & IORESOURCE_IO)
+ {
+ /*
+ * Aligning to 0x800 rather than the minimum base of
+ * 0x400 is an attempt to avoid having devices in
+ * any 0x?C?? range, which is where the de4x5 driver
+ * probes for EISA cards.
+ *
+ * Adaptecs, especially, resent such intrusions.
+ */
+ alignto = MAX(0x800, size);
+ start = ALIGN(start, alignto);
+ }
+ else if (res->flags & IORESOURCE_MEM)
+ {
+ /*
+ * The following holds at least for the Low Cost
+ * Alpha implementation of the PCI interface:
+ *
+ * In sparse memory address space, the first
+ * octant (16MB) of every 128MB segment is
+ * aliased to the very first 16 MB of the
+ * address space (i.e., it aliases the ISA
+ * memory address space). Thus, we try to
+ * avoid allocating PCI devices in that range.
+ * Can be allocated in 2nd-7th octant only.
+ * Devices that need more than 112MB of
+ * address space must be accessed through
+ * dense memory space only!
+ */
+ /* align to multiple of size of minimum base */
+ alignto = MAX(0x1000, size);
+ start = ALIGN(start, alignto);
+ if (size > 7 * 16*MB)
+ printk(KERN_WARNING "PCI: dev %s "
+ "requests %ld bytes of contiguous "
+ "address space---don't use sparse "
+ "memory accesses on this device!\n",
+ dev->name, size);
+ else
+ {
+ if (((start / (16*MB)) & 0x7) == 0) {
+ start &= ~(128*MB - 1);
+ start += 16*MB;
+ start = ALIGN(start, alignto);
+ }
+ if (start/(128*MB) != (start + size)/(128*MB)) {
+ start &= ~(128*MB - 1);
+ start += (128 + 16)*MB;
+ start = ALIGN(start, alignto);
+ }
+ }
+ }
+
+ return start;
+}
+#undef MAX
+#undef ALIGN
+#undef KB
+#undef MB
+#undef GB

/*
* Pre-layout host-independant device initialization.
*/

static void __init
-pcibios_assign_special(void)
+pcibios_assign_special(struct pci_dev * dev)
{
- struct pci_dev *dev;
- int i;
-
/* The first three resources of an IDE controler are often magic,
so leave them unchanged. This is true, for instance, of the
Contaq 82C693 as seen on SX164 and DP264. */

- for (dev = pci_devices; dev; dev = dev->next) {
- if (dev->class >> 8 != PCI_CLASS_STORAGE_IDE)
- continue;
+ if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE)
+ {
+ int i;
+
/* Resource 1 of IDE controller is the address of HD_CMD
register which actually occupies a single byte (0x3f6
for ide0) in reported 0x3f4-3f7 range. We have to fix
@@ -87,10 +159,9 @@
controller. */
dev->resource[1].start += 2;
dev->resource[1].end = dev->resource[1].start;
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- if (dev->resource[i].flags)
+ for (i = 0; i < PCI_NUM_RESOURCES; i++)
+ if (dev->resource[i].flags && dev->resource[i].start)
pci_claim_resource(dev, i);
- }
}
}

@@ -110,31 +181,63 @@
}

void __init
+pcibios_fixup_resource(struct resource *res, struct resource *root)
+{
+ res->start += root->start;
+ res->end += root->start;
+}
+
+void __init
+pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
+{
+ /* Update device resources. */
+
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ if (!dev->resource[i].start)
+ continue;
+ if (dev->resource[i].flags & IORESOURCE_IO)
+ pcibios_fixup_resource(&dev->resource[i],
+ bus->resource[0]);
+ else if (dev->resource[i].flags & IORESOURCE_MEM)
+ pcibios_fixup_resource(&dev->resource[i],
+ bus->resource[1]);
+ }
+ pcibios_assign_special(dev);
+}
+
+void __init
pcibios_fixup_bus(struct pci_bus *bus)
{
/* Propogate hose info into the subordinate devices. */

- struct pci_controler *hose = probing_hose;
+ struct pci_controler *hose = (struct pci_controler *) bus->sysdata;
struct pci_dev *dev;

bus->resource[0] = hose->io_space;
bus->resource[1] = hose->mem_space;
for (dev = bus->devices; dev; dev = dev->sibling)
- dev->sysdata = hose;
+ if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ pcibios_fixup_device_resources(dev, bus);
}

void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
{
- unsigned long where, size;
- u32 reg;
+ int where;
+ u32 reg;

- where = PCI_BASE_ADDRESS_0 + (resource * 4);
- size = res->end - res->start;
- pci_read_config_dword(dev, where, &reg);
- reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
- pci_write_config_dword(dev, where, reg);
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ reg = (res->start - root->start) | (res->flags & 0xf);
+ pci_write_config_dword(dev, where, reg);
+ if ((res->flags & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
+ == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64))
+ {
+ pci_write_config_dword(dev, where+4, 0);
+ printk(KERN_WARNING "PCI: dev %s type 64-bit\n", dev->name);
+ }

/* ??? FIXME -- record old value for shutdown. */
}
@@ -170,6 +273,15 @@
}

void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
+{
+ ranges->io_start -= bus->resource[0]->start;
+ ranges->io_end -= bus->resource[0]->start;
+ ranges->mem_start -= bus->resource[1]->start;
+ ranges->mem_end -= bus->resource[1]->start;
+}
+
+void __init
common_init_pci(void)
{
struct pci_controler *hose;
@@ -180,15 +292,12 @@
for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
hose->first_busno = next_busno;
hose->last_busno = 0xff;
- probing_hose = hose;
bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose);
hose->bus = bus;
next_busno = hose->last_busno = bus->subordinate;
next_busno += 1;
}
- probing_hose = NULL;

- pcibios_assign_special();
pci_assign_unassigned_resources(alpha_mv.min_io_address,
alpha_mv.min_mem_address);
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
@@ -197,17 +306,11 @@


struct pci_controler * __init
-alloc_pci_controler(unsigned long *mem_start)
+alloc_pci_controler(void)
{
- unsigned long start = *mem_start;
struct pci_controler *hose;
- if (start & 31)
- start = (start | 31) + 1;
- hose = (void *) start;
- start = (unsigned long) (hose + 1);
- *mem_start = start;

- memset(hose, 0, sizeof(*hose));
+ hose = alloc_bootmem(sizeof(*hose));

*hose_tail = hose;
hose_tail = &hose->next;
@@ -216,17 +319,11 @@
}

struct resource * __init
-alloc_resource(unsigned long *mem_start)
+alloc_resource(void)
{
- unsigned long start = *mem_start;
struct resource *res;
- if (start & 31)
- start = (start | 31) + 1;
- res = (void *) start;
- start = (unsigned long) (res + 1);
- *mem_start = start;

- memset(res, 0, sizeof(*res));
+ res = alloc_bootmem(sizeof(*res));

return res;
}
diff -urN 2.3.29pre3/arch/alpha/kernel/pci_impl.h alpha/arch/alpha/kernel/pci_impl.h
--- 2.3.29pre3/arch/alpha/kernel/pci_impl.h Tue Sep 14 14:35:30 1999
+++ alpha/arch/alpha/kernel/pci_impl.h Mon Nov 22 23:15:10 1999
@@ -125,12 +125,11 @@

/* The hose list. */
extern struct pci_controler *hose_head, **hose_tail;
-extern struct pci_controler *probing_hose;

extern void common_init_pci(void);
extern u8 common_swizzle(struct pci_dev *, u8 *);
-extern struct pci_controler *alloc_pci_controler(unsigned long *);
-extern struct resource *alloc_resource(unsigned long *);
+extern struct pci_controler *alloc_pci_controler(void);
+extern struct resource *alloc_resource(void);

extern const char *const pci_io_names[];
extern const char *const pci_mem_names[];
diff -urN 2.3.29pre3/arch/alpha/kernel/proto.h alpha/arch/alpha/kernel/proto.h
--- 2.3.29pre3/arch/alpha/kernel/proto.h Sun Nov 21 17:47:42 1999
+++ alpha/arch/alpha/kernel/proto.h Tue Nov 23 00:11:42 1999
@@ -12,43 +12,43 @@

/* core_apecs.c */
extern struct pci_ops apecs_pci_ops;
-extern void apecs_init_arch(unsigned long *, unsigned long *);
+extern void apecs_init_arch(void);
extern void apecs_pci_clr_err(void);
extern void apecs_machine_check(u64, u64, struct pt_regs *);

/* core_cia.c */
extern struct pci_ops cia_pci_ops;
-extern void cia_init_arch(unsigned long *, unsigned long *);
+extern void cia_init_arch(void);
extern void cia_machine_check(u64, u64, struct pt_regs *);

/* core_lca.c */
extern struct pci_ops lca_pci_ops;
-extern void lca_init_arch(unsigned long *, unsigned long *);
+extern void lca_init_arch(void);
extern void lca_machine_check(u64, u64, struct pt_regs *);

/* core_mcpcia.c */
extern struct pci_ops mcpcia_pci_ops;
-extern void mcpcia_init_arch(unsigned long *, unsigned long *);
+extern void mcpcia_init_arch(void);
extern void mcpcia_machine_check(u64, u64, struct pt_regs *);

/* core_polaris.c */
extern struct pci_ops polaris_pci_ops;
-extern void polaris_init_arch(unsigned long *, unsigned long *);
+extern void polaris_init_arch(void);
extern void polaris_machine_check(u64, u64, struct pt_regs *);

/* core_pyxis.c */
extern struct pci_ops pyxis_pci_ops;
-extern void pyxis_init_arch(unsigned long *, unsigned long *);
+extern void pyxis_init_arch(void);
extern void pyxis_machine_check(u64, u64, struct pt_regs *);

/* core_t2.c */
extern struct pci_ops t2_pci_ops;
-extern void t2_init_arch(unsigned long *, unsigned long *);
+extern void t2_init_arch(void);
extern void t2_machine_check(u64, u64, struct pt_regs *);

/* core_tsunami.c */
extern struct pci_ops tsunami_pci_ops;
-extern void tsunami_init_arch(unsigned long *, unsigned long *);
+extern void tsunami_init_arch(void);
extern void tsunami_machine_check(u64, u64, struct pt_regs *);

/* setup.c */
diff -urN 2.3.29pre3/arch/alpha/kernel/setup.c alpha/arch/alpha/kernel/setup.c
--- 2.3.29pre3/arch/alpha/kernel/setup.c Tue Oct 12 02:40:34 1999
+++ alpha/arch/alpha/kernel/setup.c Tue Nov 23 15:15:26 1999
@@ -4,6 +4,8 @@
* Copyright (C) 1995 Linus Torvalds
*/

+/* 2.3.x bootmem, 1999 Andrea Arcangeli <andrea@suse.de> */
+
/*
* Bootup setup stuff.
*/
@@ -26,6 +28,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/ioport.h>
+#include <linux/bootmem.h>

#ifdef CONFIG_RTC
#include <linux/timex.h>
@@ -40,6 +43,8 @@
#include <asm/hwrpb.h>
#include <asm/dma.h>
#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/mmu_context.h>

#include "proto.h"
#include "pci_impl.h"
@@ -57,7 +62,6 @@

#define N(a) (sizeof(a)/sizeof(a[0]))

-static unsigned long find_end_memory(void);
static struct alpha_machine_vector *get_sysvec(long, long, long);
static struct alpha_machine_vector *get_sysvec_byname(const char *);
static void get_sysnames(long, long, char **, char **);
@@ -68,7 +72,7 @@
* initialized, we need to copy things out into a more permanent
* place.
*/
-#define PARAM ZERO_PAGE(0)
+#define PARAM ZERO_PGE
#define COMMAND_LINE ((char*)(PARAM + 0x0000))
#define COMMAND_LINE_SIZE 256
#define INITRD_START (*(unsigned long *) (PARAM+0x100))
@@ -181,12 +185,105 @@
request_resource(io, standard_io_resources+i);
}

-void __init
-setup_arch(char **cmdline_p, unsigned long * memory_start_p,
- unsigned long * memory_end_p)
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#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)
{
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
+ unsigned long start_pfn, bootmap_size;
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;
+
+ printk("memcluster %d, usage %02lx, start %8lu, end %8lu\n",
+ i, cluster->usage, 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 */
+ if (cluster->usage & 3)
+ continue;
+
+ end = cluster->start_pfn + cluster->numpages;
+ 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);
+
+ /* allocate the bootmem array after the kernel and mark
+ the whole MM as reserved */
+ bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+
+ for (cluster = memdesc->cluster, i = memdesc->numclusters;
+ i > 0; i--, cluster++)
+ {
+ unsigned long end, start;
+
+ /* Bit 0 is console/PALcode reserved. Bit 1 is
+ non-volatile memory -- we might want to mark
+ this for later */
+ 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)
+ continue;
+
+ end = PFN_PHYS(cluster->start_pfn + cluster->numpages);
+ if (PFN_DOWN(end) > PFN_MAX)
+ end = PFN_PHYS(PFN_MAX);
+
+ if (start >= end)
+ continue;
+ free_bootmem(start, end-start);
+ }
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ initrd_start = INITRD_START;
+ if (initrd_start) {
+ initrd_end = initrd_start+INITRD_SIZE;
+ printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
+ (void *) initrd_start, INITRD_SIZE);
+
+ 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_start = initrd_end = 0;
+ }
+ else
+ reserve_bootmem(virt_to_phys(initrd_start), INITRD_SIZE);
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
+#undef PFN_UP
+#undef PFN_DOWN
+#undef PFN_PHYS
+#undef PFN_MAX

+void __init
+setup_arch(char **cmdline_p)
+{
struct alpha_machine_vector *vec = NULL;
struct percpu_struct *cpu;
char *type_name, *var_name, *p;
@@ -258,6 +355,10 @@
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 "
@@ -281,29 +382,12 @@
wrmces(0x7);

/* Find our memory. */
- *memory_end_p = find_end_memory();
- *memory_start_p = (unsigned long) _end;
-
-#ifdef CONFIG_BLK_DEV_INITRD
- initrd_start = INITRD_START;
- if (initrd_start) {
- initrd_end = initrd_start+INITRD_SIZE;
- printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
- (void *) initrd_start, INITRD_SIZE);
-
- if (initrd_end > *memory_end_p) {
- printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- initrd_end, (unsigned long) memory_end_p);
- initrd_start = initrd_end = 0;
- }
- }
-#endif
+ setup_memory();

/* Initialize the machine. Usually has to do with setting up
DMA windows and the like. */
if (alpha_mv.init_arch)
- alpha_mv.init_arch(memory_start_p, memory_end_p);
+ alpha_mv.init_arch();

/* Reserve standard resources. */
reserve_std_resources();
@@ -352,35 +436,6 @@
setup_smp();
#endif
}
-
-static unsigned long __init
-find_end_memory(void)
-{
- int i;
- unsigned long high = 0;
- struct memclust_struct * cluster;
- struct memdesc_struct * memdesc;
-
- memdesc = (struct memdesc_struct *)
- (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
- cluster = memdesc->cluster;
-
- for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
- unsigned long tmp;
- tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
- if (tmp > high)
- high = tmp;
- }
-
- /* Round it up to an even number of pages. */
- high = (high + PAGE_SIZE) & (PAGE_MASK*2);
-
- /* Enforce maximum of 2GB even if there is more. Blah. */
- if (high > 0x80000000UL)
- high = 0x80000000UL;
- return PAGE_OFFSET + high;
-}
-

static char sys_unknown[] = "Unknown";
static char systype_names[][16] = {
diff -urN 2.3.29pre3/arch/alpha/kernel/smp.c alpha/arch/alpha/kernel/smp.c
--- 2.3.29pre3/arch/alpha/kernel/smp.c Tue Sep 14 14:35:33 1999
+++ alpha/arch/alpha/kernel/smp.c Tue Nov 23 14:33:22 1999
@@ -23,8 +23,10 @@
#include <asm/irq.h>
#include <asm/bitops.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/hardirq.h>
#include <asm/softirq.h>
+#include <asm/mmu_context.h>

#define __KERNEL_SYSCALLS__
#include <asm/unistd.h>
diff -urN 2.3.29pre3/arch/alpha/kernel/sys_sio.c alpha/arch/alpha/kernel/sys_sio.c
--- 2.3.29pre3/arch/alpha/kernel/sys_sio.c Mon Nov 22 23:08:56 1999
+++ alpha/arch/alpha/kernel/sys_sio.c Tue Nov 23 01:30:44 1999
@@ -55,7 +55,7 @@
}

static inline void __init
-xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+xl_init_arch(void)
{
struct pci_controler *hose;

@@ -93,7 +93,7 @@
* Create our single hose.
*/

- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = LCA_CONF;
@@ -101,7 +101,7 @@
}

static inline void __init
-alphabook1_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+alphabook1_init_arch(void)
{
/* The AlphaBook1 has LCD video fixed at 800x600,
37 rows and 100 cols. */
@@ -109,7 +109,7 @@
screen_info.orig_video_cols = 100;
screen_info.orig_video_lines = 37;

- lca_init_arch(mem_start, mem_end);
+ lca_init_arch();
}


diff -urN 2.3.29pre3/arch/alpha/mm/fault.c alpha/arch/alpha/mm/fault.c
--- 2.3.29pre3/arch/alpha/mm/fault.c Tue Sep 14 14:34:05 1999
+++ alpha/arch/alpha/mm/fault.c Tue Nov 23 04:18:03 1999
@@ -11,7 +11,7 @@

#define __EXTERN_INLINE inline
#include <asm/mmu_context.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#undef __EXTERN_INLINE

#include <linux/signal.h>
diff -urN 2.3.29pre3/arch/alpha/mm/init.c alpha/arch/alpha/mm/init.c
--- 2.3.29pre3/arch/alpha/mm/init.c Tue Oct 26 21:30:50 1999
+++ alpha/arch/alpha/mm/init.c Tue Nov 23 14:54:29 1999
@@ -4,6 +4,8 @@
* Copyright (C) 1995 Linus Torvalds
*/

+/* 2.3.x zone allocator, 1999 Andrea Arcangeli <andrea@suse.de> */
+
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -15,6 +17,7 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
+#include <linux/bootmem.h> /* max_low_pfn */
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
@@ -22,10 +25,12 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/hwrpb.h>
#include <asm/dma.h>
+#include <asm/mmu_context.h>

-#define DEBUG_POISON 0
+static unsigned long totalram_pages;

extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
@@ -58,7 +63,7 @@
pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
if (pgd_none(*pgd)) {
if (pmd) {
- clear_page((unsigned long)pmd);
+ clear_page((void *)pmd);
pgd_set(pgd, pmd);
return pmd + offset;
}
@@ -81,7 +86,7 @@
pte = (pte_t *) __get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- clear_page((unsigned long)pte);
+ clear_page((void *)pte);
pmd_set(pmd, pte);
return pte + offset;
}
@@ -136,7 +141,7 @@
__bad_page(void)
{
memset((void *) EMPTY_PGE, 0, PAGE_SIZE);
- return pte_mkdirty(mk_pte((unsigned long) EMPTY_PGE, PAGE_SHARED));
+ return pte_mkdirty(mk_pte(mem_map + MAP_NR(EMPTY_PGE), PAGE_SHARED));
}

void
@@ -172,8 +177,6 @@
#endif
}

-extern unsigned long free_area_init(unsigned long, unsigned long);
-
static inline unsigned long
load_PCB(struct thread_struct * pcb)
{
@@ -186,40 +189,39 @@
* paging_init() sets up the page tables: in the alpha version this actually
* unmaps the bootup page table (as we're now in KSEG, so we don't need it).
*/
-unsigned long
-paging_init(unsigned long start_mem, unsigned long end_mem)
+void paging_init(void)
{
- int i;
unsigned long newptbr;
- struct memclust_struct * cluster;
- struct memdesc_struct * memdesc;
unsigned long original_pcb_ptr;
+ unsigned int zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long dma_pfn, high_pfn;

- /* initialize mem_map[] */
- start_mem = free_area_init(start_mem, end_mem);
+ dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ high_pfn = max_low_pfn;

- /* find free clusters, update mem_map[] accordingly */
- memdesc = (struct memdesc_struct *)
- (hwrpb->mddt_offset + (unsigned long) hwrpb);
- cluster = memdesc->cluster;
- for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
- unsigned long pfn, nr;
-
- /* Bit 0 is console/PALcode reserved. Bit 1 is
- non-volatile memory -- we might want to mark
- this for later */
- if (cluster->usage & 3)
- continue;
- pfn = cluster->start_pfn;
- nr = cluster->numpages;
+#define ORDER_MASK (~((1 << (MAX_ORDER-1))-1))
+#define ORDER_ALIGN(n) (((n) + ~ORDER_MASK) & ORDER_MASK)

- while (nr--)
- clear_bit(PG_reserved, &mem_map[pfn++].flags);
+ dma_pfn = ORDER_ALIGN(dma_pfn);
+ high_pfn = ORDER_ALIGN(high_pfn);
+
+#undef ORDER_MASK
+#undef ORDER_ALIGN
+
+ if (dma_pfn > high_pfn)
+ zones_size[ZONE_DMA] = high_pfn;
+ else
+ {
+ zones_size[0] = dma_pfn;
+ zones_size[ZONE_NORMAL] = high_pfn - dma_pfn;
}

+ /* initialize mem_map[] */
+ free_area_init(zones_size);
+
/* Initialize the kernel's page tables. Linux puts the vptb in
the last slot of the L1 page table. */
- memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE);
+ memset((void *)ZERO_PGE, 0, PAGE_SIZE);
memset(swapper_pg_dir, 0, PAGE_SIZE);
newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
pgd_val(swapper_pg_dir[1023]) =
@@ -252,8 +254,6 @@
phys_to_virt(original_pcb_ptr);
}
original_pcb = *(struct thread_struct *) original_pcb_ptr;
-
- return start_mem;
}

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
@@ -273,64 +273,12 @@
}
#endif

-#if DEBUG_POISON
-static void
-kill_page(unsigned long pg)
-{
- unsigned long *p = (unsigned long *)pg;
- unsigned long i = PAGE_SIZE, v = 0xdeadbeefdeadbeef;
- do {
- p[0] = v;
- p[1] = v;
- p[2] = v;
- p[3] = v;
- p[4] = v;
- p[5] = v;
- p[6] = v;
- p[7] = v;
- i -= 64;
- p += 8;
- } while (i != 0);
-}
-#else
-#define kill_page(pg)
-#endif
-
void
-mem_init(unsigned long start_mem, unsigned long end_mem)
+mem_init(void)
{
- unsigned long tmp;
-
- end_mem &= PAGE_MASK;
- max_mapnr = num_physpages = MAP_NR(end_mem);
- high_memory = (void *) end_mem;
- start_mem = PAGE_ALIGN(start_mem);
-
- /*
- * Mark the pages used by the kernel as reserved.
- */
- tmp = KERNEL_START;
- while (tmp < start_mem) {
- set_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags);
- tmp += PAGE_SIZE;
- }
-
- for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
- if (tmp >= MAX_DMA_ADDRESS)
- clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
- if (PageReserved(mem_map+MAP_NR(tmp)))
- continue;
- atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start && tmp >= initrd_start && tmp < initrd_end)
- continue;
-#endif
- kill_page(tmp);
- free_page(tmp);
- }
- tmp = nr_free_pages << PAGE_SHIFT;
- printk("Memory: %luk available\n", tmp >> 10);
- return;
+ max_mapnr = num_physpages = max_low_pfn;
+ totalram_pages += free_all_bootmem();
+ printk("Memory: %luk available\n", totalram_pages >> 10);
}

void
@@ -341,34 +289,36 @@

addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
- mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
- atomic_set(&mem_map[MAP_NR(addr)].count, 1);
- kill_page(addr);
+ ClearPageReserved(mem_map + MAP_NR(addr));
+ set_page_count(mem_map+MAP_NR(addr), 1);
free_page(addr);
+ totalram_pages++;
}
printk ("Freeing unused kernel memory: %ldk freed\n",
(&__init_end - &__init_begin) >> 10);
}

+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
void
si_meminfo(struct sysinfo *val)
{
- int i;
-
- i = max_mapnr;
- val->totalram = 0;
+ val->totalram = totalram_pages;
val->sharedram = 0;
- val->freeram = nr_free_pages << PAGE_SHIFT;
- val->bufferram = atomic_read(&buffermem);
- while (i-- > 0) {
- if (PageReserved(mem_map+i))
- continue;
- val->totalram++;
- if (!atomic_read(&mem_map[i].count))
- continue;
- val->sharedram += atomic_read(&mem_map[i].count) - 1;
- }
- val->totalram <<= PAGE_SHIFT;
- val->sharedram <<= PAGE_SHIFT;
- return;
+ val->freeram = nr_free_pages();
+ val->bufferram = atomic_read(&buffermem_pages);
+ val->totalhigh = 0;
+ val->freehigh = 0;
+ val->mem_unit = PAGE_SIZE;
}
diff -urN 2.3.29pre3/arch/i386/kernel/pci-i386.c alpha/arch/i386/kernel/pci-i386.c
--- 2.3.29pre3/arch/i386/kernel/pci-i386.c Tue Oct 26 21:30:50 1999
+++ alpha/arch/i386/kernel/pci-i386.c Mon Nov 22 23:15:10 1999
@@ -122,12 +122,12 @@
printk(KERN_ERR "PCI: I/O Region %s/%d too large (%ld bytes)\n", dev->slot_name, i, size);
return -EFBIG;
}
- if (allocate_resource(pr, r, size, 0x1000, ~0, 1024)) {
+ if (allocate_resource(pr, r, size, 0x1000, ~0, 1024, dev)) {
printk(KERN_ERR "PCI: Allocation of I/O region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
return -EBUSY;
}
} else {
- if (allocate_resource(pr, r, size, 0x10000000, ~0, size)) {
+ if (allocate_resource(pr, r, size, 0x10000000, ~0, size, dev)) {
printk(KERN_ERR "PCI: Allocation of memory region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
return -EBUSY;
}
@@ -291,6 +291,12 @@
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
pcibios_assign_resources();
+}
+
+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
+ unsigned long start, unsigned long size)
+{
+ return start;
}

int pcibios_enable_resources(struct pci_dev *dev)
diff -urN 2.3.29pre3/arch/i386/mm/init.c alpha/arch/i386/mm/init.c
--- 2.3.29pre3/arch/i386/mm/init.c Mon Nov 22 23:08:56 1999
+++ alpha/arch/i386/mm/init.c Mon Nov 22 23:15:10 1999
@@ -636,6 +636,19 @@
printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}

+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
void si_meminfo(struct sysinfo *val)
{
val->totalram = totalram_pages;
diff -urN 2.3.29pre3/drivers/block/rd.c alpha/drivers/block/rd.c
--- 2.3.29pre3/drivers/block/rd.c Mon Nov 22 23:08:57 1999
+++ alpha/drivers/block/rd.c Mon Nov 22 23:15:10 1999
@@ -276,9 +276,11 @@

static int initrd_release(struct inode *inode,struct file *file)
{
+ extern void free_initrd_mem(unsigned long, unsigned long);
+
+ if (--initrd_users) return 0;
+ free_initrd_mem(initrd_start, initrd_end);
initrd_start = 0;
- /* No need to actually release the pages, because that is
- done later by free_all_bootmem. */
return 0;
}

diff -urN 2.3.29pre3/drivers/pci/pci.c alpha/drivers/pci/pci.c
--- 2.3.29pre3/drivers/pci/pci.c Tue Oct 26 21:30:50 1999
+++ alpha/drivers/pci/pci.c Mon Nov 22 23:15:10 1999
@@ -437,6 +437,7 @@
dev = dev_cache;
memset(dev, 0, sizeof(*dev));
dev->bus = bus;
+ dev->sysdata = bus->sysdata;
dev->devfn = devfn;

if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
@@ -556,6 +557,7 @@
child->self = dev;
child->parent = bus;
child->ops = bus->ops;
+ child->sysdata = bus->sysdata;

/*
* Set up the primary, secondary and subordinate
diff -urN 2.3.29pre3/drivers/pci/setup.c alpha/drivers/pci/setup.c
--- 2.3.29pre3/drivers/pci/setup.c Tue Oct 26 21:30:50 1999
+++ alpha/drivers/pci/setup.c Tue Nov 23 16:02:32 1999
@@ -9,6 +9,8 @@
* Support routines for initializing a PCI subsystem.
*/

+/* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */
+
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -33,15 +35,8 @@
int err;

err = -EINVAL;
- if (root != NULL) {
- /* If `dev' is on a secondary pci bus, `root' may not be
- at the origin. In that case, adjust the resource into
- range. */
- res->start += root->start;
- res->end += root->start;
-
+ if (root != NULL)
err = request_resource(root, res);
- }
if (err) {
printk(KERN_ERR "PCI: Address space collision on region %d "
"of device %s\n", resource, dev->name);
@@ -89,7 +84,7 @@
DBGC((" for root[%lx:%lx] min[%lx] size[%lx]\n",
root->start, root->end, min, size));

- if (allocate_resource(root, res, size, min, -1, size) < 0) {
+ if (allocate_resource(root, res, size, min, -1, size, dev) < 0) {
printk(KERN_ERR
"PCI: Failed to allocate resource %d for %s\n",
i, dev->name);
@@ -148,13 +143,6 @@
pdev_assign_unassigned_resources(dev, min_io, min_mem);
}

-struct pbus_set_ranges_data
-{
- int found_vga;
- unsigned int io_start, io_end;
- unsigned int mem_start, mem_end;
-};
-
#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define ROUND_DOWN(x, a) ((x) & ~((a) - 1))

@@ -166,7 +154,7 @@
struct pci_dev *dev;

inner.found_vga = 0;
- inner.mem_start = inner.io_start = ~0;
+ inner.mem_start = inner.io_start = ~0UL;
inner.mem_end = inner.io_end = 0;

/* Collect information about how our direct children are layed out. */
@@ -200,6 +188,8 @@

inner.mem_start = ROUND_DOWN(inner.mem_start, 1*1024*1024);
inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024);
+
+ pcibios_fixup_pbus_ranges(bus, &inner);

/* Configure the bridge, if possible. */
if (bus->self) {
diff -urN 2.3.29pre3/drivers/video/tgafb.c alpha/drivers/video/tgafb.c
--- 2.3.29pre3/drivers/video/tgafb.c Tue Sep 14 14:35:13 1999
+++ alpha/drivers/video/tgafb.c Mon Nov 22 23:15:10 1999
@@ -937,7 +937,7 @@
static void tgafb_set_disp(const void *fb_par, struct display *disp,
struct fb_info_gen *info)
{
- disp->screen_base = ioremap(fb_info.tga_fb_base);
+ disp->screen_base = ioremap(fb_info.tga_fb_base, 0);
switch (fb_info.tga_type) {
#ifdef FBCON_HAS_CFB8
case 0: /* 8-plane */
diff -urN 2.3.29pre3/include/asm-alpha/core_tsunami.h alpha/include/asm-alpha/core_tsunami.h
--- 2.3.29pre3/include/asm-alpha/core_tsunami.h Tue Oct 12 18:16:42 1999
+++ alpha/include/asm-alpha/core_tsunami.h Mon Nov 22 23:15:10 1999
@@ -291,6 +291,9 @@
#define TSUNAMI_IO_BIAS TSUNAMI_IO(0)
#define TSUNAMI_MEM_BIAS TSUNAMI_MEM(0)

+/* The IO address space is larger than 0xffff */
+#define TSUNAMI_IO_SPACE (TSUNAMI_CONF(0) - TSUNAMI_IO(0))
+#define TSUNAMI_MEM_SPACE (_TSUNAMI_IACK_SC(0) - TSUNAMI_MEM(0))

/*
* Data structure for handling TSUNAMI machine checks:
diff -urN 2.3.29pre3/include/asm-alpha/div64.h alpha/include/asm-alpha/div64.h
--- 2.3.29pre3/include/asm-alpha/div64.h Sun Nov 21 03:20:20 1999
+++ alpha/include/asm-alpha/div64.h Mon Nov 22 23:15:10 1999
@@ -7,8 +7,8 @@
*/
#define do_div(n,base) ({ \
int __res; \
- __res = ((unsigned long) n) % (unsigned) base; \
- n = ((unsigned long) n) / (unsigned) base; \
+ __res = ((unsigned long) (n)) % (unsigned) (base); \
+ (n) = ((unsigned long) (n)) / (unsigned) (base); \
__res; })

#endif
diff -urN 2.3.29pre3/include/asm-alpha/machvec.h alpha/include/asm-alpha/machvec.h
--- 2.3.29pre3/include/asm-alpha/machvec.h Sun Nov 21 17:46:05 1999
+++ alpha/include/asm-alpha/machvec.h Tue Nov 23 00:07:43 1999
@@ -78,7 +78,7 @@
void (*device_interrupt)(unsigned long vector, struct pt_regs *regs);
void (*machine_check)(u64 vector, u64 la, struct pt_regs *regs);

- void (*init_arch)(unsigned long *, unsigned long *);
+ void (*init_arch)(void);
void (*init_irq)(void);
void (*init_pit)(void);
void (*init_pci)(void);
diff -urN 2.3.29pre3/include/asm-alpha/page.h alpha/include/asm-alpha/page.h
--- 2.3.29pre3/include/asm-alpha/page.h Tue Sep 14 14:33:21 1999
+++ alpha/include/asm-alpha/page.h Mon Nov 22 23:15:10 1999
@@ -19,7 +19,7 @@
* results in clearer kernel profiles as we see _who_ is
* doing page clearing or copying.
*/
-static inline void clear_page(unsigned long page)
+static inline void clear_page(void * page)
{
unsigned long count = PAGE_SIZE/64;
unsigned long *ptr = (unsigned long *)page;
@@ -38,7 +38,7 @@
} while (count);
}

-static inline void copy_page(unsigned long _to, unsigned long _from)
+static inline void copy_page(void * _to, void * _from)
{
unsigned long count = PAGE_SIZE/64;
unsigned long *to = (unsigned long *)_to;
@@ -106,7 +106,16 @@

#endif /* STRICT_MM_TYPECHECKS */

+#if 0
#define BUG() __asm__ __volatile__("call_pal 129 # bugchk")
+#else
+/* hack to see the BUG() information in the early boot stage */
+#define BUG() \
+do { \
+ SRM_printf("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ halt(); \
+} while(0)
+#endif
#define PAGE_BUG(page) BUG()

#endif /* !ASSEMBLY */
diff -urN 2.3.29pre3/include/asm-alpha/pgalloc.h alpha/include/asm-alpha/pgalloc.h
--- 2.3.29pre3/include/asm-alpha/pgalloc.h Thu Jan 1 01:00:00 1970
+++ alpha/include/asm-alpha/pgalloc.h Tue Nov 23 03:57:46 1999
@@ -0,0 +1,337 @@
+#ifndef _ALPHA_PGALLOC_H
+#define _ALPHA_PGALLOC_H
+
+#include <linux/config.h>
+
+/* Caches aren't brain-dead on the Alpha. */
+#define flush_cache_all() do { } while (0)
+#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_range(mm, start, end) do { } while (0)
+#define flush_cache_page(vma, vmaddr) do { } while (0)
+#define flush_page_to_ram(page) do { } while (0)
+#define flush_icache_range(start, end) do { } while (0)
+
+/*
+ * Use a few helper functions to hide the ugly broken ASN
+ * numbers on early Alphas (ev4 and ev45)
+ */
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __MMU_EXTERN_INLINE
+#endif
+
+__EXTERN_INLINE void
+ev4_flush_tlb_current(struct mm_struct *mm)
+{
+ tbiap();
+}
+
+__EXTERN_INLINE void
+ev4_flush_tlb_other(struct mm_struct *mm)
+{
+}
+
+extern void ev5_flush_tlb_current(struct mm_struct *mm);
+
+__EXTERN_INLINE void
+ev5_flush_tlb_other(struct mm_struct *mm)
+{
+ mm->context = 0;
+}
+
+/*
+ * Flush just one page in the current TLB set.
+ * We need to be very careful about the icache here, there
+ * is no way to invalidate a specific icache page..
+ */
+
+__EXTERN_INLINE void
+ev4_flush_tlb_current_page(struct mm_struct * mm,
+ struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ tbi(2 + ((vma->vm_flags & VM_EXEC) != 0), addr);
+}
+
+__EXTERN_INLINE void
+ev5_flush_tlb_current_page(struct mm_struct * mm,
+ struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ if (vma->vm_flags & VM_EXEC)
+ ev5_flush_tlb_current(mm);
+ else
+ tbi(2, addr);
+}
+
+
+#ifdef CONFIG_ALPHA_GENERIC
+# define flush_tlb_current alpha_mv.mv_flush_tlb_current
+# define flush_tlb_other alpha_mv.mv_flush_tlb_other
+# define flush_tlb_current_page alpha_mv.mv_flush_tlb_current_page
+#else
+# ifdef CONFIG_ALPHA_EV4
+# define flush_tlb_current ev4_flush_tlb_current
+# define flush_tlb_other ev4_flush_tlb_other
+# define flush_tlb_current_page ev4_flush_tlb_current_page
+# else
+# define flush_tlb_current ev5_flush_tlb_current
+# define flush_tlb_other ev5_flush_tlb_other
+# define flush_tlb_current_page ev5_flush_tlb_current_page
+# endif
+#endif
+
+#ifdef __MMU_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __MMU_EXTERN_INLINE
+#endif
+
+/*
+ * Flush current user mapping.
+ */
+static inline void flush_tlb(void)
+{
+ flush_tlb_current(current->mm);
+}
+
+#ifndef __SMP__
+/*
+ * Flush everything (kernel mapping may also have
+ * changed due to vmalloc/vfree)
+ */
+static inline void flush_tlb_all(void)
+{
+ tbia();
+}
+
+/*
+ * Flush a specified user mapping
+ */
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ if (mm != current->mm)
+ flush_tlb_other(mm);
+ else
+ flush_tlb_current(mm);
+}
+
+/*
+ * Page-granular tlb flush.
+ *
+ * do a tbisd (type = 2) normally, and a tbis (type = 3)
+ * if it is an executable mapping. We want to avoid the
+ * itlb flush, because that potentially also does a
+ * icache flush.
+ */
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ struct mm_struct * mm = vma->vm_mm;
+
+ if (mm != current->mm)
+ flush_tlb_other(mm);
+ else
+ flush_tlb_current_page(mm, vma, addr);
+}
+
+/*
+ * Flush a specified range of user mapping: on the
+ * Alpha we flush the whole user tlb.
+ */
+static inline void flush_tlb_range(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ flush_tlb_mm(mm);
+}
+
+#else /* __SMP__ */
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *);
+extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+extern void flush_tlb_range(struct mm_struct *, unsigned long, unsigned long);
+
+#endif /* __SMP__ */
+
+/*
+ * Allocate and free page tables. The xxx_kernel() versions are
+ * used to allocate a kernel page table - this turns on ASN bits
+ * if any.
+ */
+#ifndef __SMP__
+extern struct pgtable_cache_struct {
+ unsigned long *pgd_cache;
+ unsigned long *pte_cache;
+ unsigned long pgtable_cache_sz;
+} quicklists;
+#else
+#include <asm/smp.h>
+#define quicklists cpu_data[smp_processor_id()]
+#endif
+#define pgd_quicklist (quicklists.pgd_cache)
+#define pmd_quicklist ((unsigned long *)0)
+#define pte_quicklist (quicklists.pte_cache)
+#define pgtable_cache_size (quicklists.pgtable_cache_sz)
+
+extern __inline__ pgd_t *get_pgd_slow(void)
+{
+ pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init;
+
+ if (ret) {
+ init = pgd_offset(&init_mm, 0UL);
+ memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+ memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+
+ pgd_val(ret[PTRS_PER_PGD])
+ = pte_val(mk_pte(mem_map + MAP_NR(ret), PAGE_KERNEL));
+ }
+ return ret;
+}
+
+extern __inline__ pgd_t *get_pgd_fast(void)
+{
+ unsigned long *ret;
+
+ if((ret = pgd_quicklist) != NULL) {
+ pgd_quicklist = (unsigned long *)(*ret);
+ ret[0] = ret[1];
+ pgtable_cache_size--;
+ } else
+ ret = (unsigned long *)get_pgd_slow();
+ return (pgd_t *)ret;
+}
+
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
+{
+ *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+ pgd_quicklist = (unsigned long *) pgd;
+ pgtable_cache_size++;
+}
+
+extern __inline__ void free_pgd_slow(pgd_t *pgd)
+{
+ free_page((unsigned long)pgd);
+}
+
+extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_premasked);
+
+extern __inline__ pmd_t *get_pmd_fast(void)
+{
+ unsigned long *ret;
+
+ if((ret = (unsigned long *)pte_quicklist) != NULL) {
+ pte_quicklist = (unsigned long *)(*ret);
+ ret[0] = ret[1];
+ pgtable_cache_size--;
+ }
+ return (pmd_t *)ret;
+}
+
+extern __inline__ void free_pmd_fast(pmd_t *pmd)
+{
+ *(unsigned long *)pmd = (unsigned long) pte_quicklist;
+ pte_quicklist = (unsigned long *) pmd;
+ pgtable_cache_size++;
+}
+
+extern __inline__ void free_pmd_slow(pmd_t *pmd)
+{
+ free_page((unsigned long)pmd);
+}
+
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
+
+extern __inline__ pte_t *get_pte_fast(void)
+{
+ unsigned long *ret;
+
+ if((ret = (unsigned long *)pte_quicklist) != NULL) {
+ pte_quicklist = (unsigned long *)(*ret);
+ ret[0] = ret[1];
+ pgtable_cache_size--;
+ }
+ return (pte_t *)ret;
+}
+
+extern __inline__ void free_pte_fast(pte_t *pte)
+{
+ *(unsigned long *)pte = (unsigned long) pte_quicklist;
+ pte_quicklist = (unsigned long *) pte;
+ pgtable_cache_size++;
+}
+
+extern __inline__ void free_pte_slow(pte_t *pte)
+{
+ free_page((unsigned long)pte);
+}
+
+extern void __bad_pte(pmd_t *pmd);
+extern void __bad_pmd(pgd_t *pgd);
+
+#define pte_free_kernel(pte) free_pte_fast(pte)
+#define pte_free(pte) free_pte_fast(pte)
+#define pmd_free_kernel(pmd) free_pmd_fast(pmd)
+#define pmd_free(pmd) free_pmd_fast(pmd)
+#define pgd_free(pgd) free_pgd_fast(pgd)
+#define pgd_alloc() get_pgd_fast()
+
+extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address)
+{
+ address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+ if (pmd_none(*pmd)) {
+ pte_t *page = get_pte_fast();
+
+ if (!page)
+ return get_pte_slow(pmd, address);
+ pmd_set(pmd, page);
+ return page + address;
+ }
+ if (pmd_bad(*pmd)) {
+ __bad_pte(pmd);
+ return NULL;
+ }
+ return (pte_t *) pmd_page(*pmd) + address;
+}
+
+extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address)
+{
+ address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+ if (pgd_none(*pgd)) {
+ pmd_t *page = get_pmd_fast();
+
+ if (!page)
+ return get_pmd_slow(pgd, address);
+ pgd_set(pgd, page);
+ return page + address;
+ }
+ if (pgd_bad(*pgd)) {
+ __bad_pmd(pgd);
+ return NULL;
+ }
+ return (pmd_t *) pgd_page(*pgd) + address;
+}
+
+#define pte_alloc_kernel pte_alloc
+#define pmd_alloc_kernel pmd_alloc
+
+extern int do_check_pgt_cache(int, int);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+ struct task_struct * p;
+ pgd_t *pgd;
+
+ read_lock(&tasklist_lock);
+ for_each_task(p) {
+ if (!p->mm)
+ continue;
+ *pgd_offset(p->mm,address) = entry;
+ }
+ read_unlock(&tasklist_lock);
+ for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+ pgd[(address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)] = entry;
+}
+
+#endif /* _ALPHA_PGALLOC_H */
diff -urN 2.3.29pre3/include/asm-alpha/pgtable.h alpha/include/asm-alpha/pgtable.h
--- 2.3.29pre3/include/asm-alpha/pgtable.h Sun Oct 31 02:46:42 1999
+++ alpha/include/asm-alpha/pgtable.h Tue Nov 23 14:36:18 1999
@@ -9,165 +9,11 @@
* in <asm/page.h> (currently 8192).
*/
#include <linux/config.h>
-#include <linux/spinlock.h> /* For the task lock */

-#include <asm/system.h>
+#include <asm/page.h>
#include <asm/processor.h> /* For TASK_SIZE */
-#include <asm/mmu_context.h>
#include <asm/machvec.h>

-
-/* Caches aren't brain-dead on the Alpha. */
-#define flush_cache_all() do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_range(mm, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr) do { } while (0)
-#define flush_page_to_ram(page) do { } while (0)
-#define flush_icache_range(start, end) do { } while (0)
-
-/*
- * Use a few helper functions to hide the ugly broken ASN
- * numbers on early Alphas (ev4 and ev45)
- */
-
-#ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
-#define __MMU_EXTERN_INLINE
-#endif
-
-__EXTERN_INLINE void
-ev4_flush_tlb_current(struct mm_struct *mm)
-{
- tbiap();
-}
-
-__EXTERN_INLINE void
-ev4_flush_tlb_other(struct mm_struct *mm)
-{
-}
-
-extern void ev5_flush_tlb_current(struct mm_struct *mm);
-
-__EXTERN_INLINE void
-ev5_flush_tlb_other(struct mm_struct *mm)
-{
- mm->context = 0;
-}
-
-/*
- * Flush just one page in the current TLB set.
- * We need to be very careful about the icache here, there
- * is no way to invalidate a specific icache page..
- */
-
-__EXTERN_INLINE void
-ev4_flush_tlb_current_page(struct mm_struct * mm,
- struct vm_area_struct *vma,
- unsigned long addr)
-{
- tbi(2 + ((vma->vm_flags & VM_EXEC) != 0), addr);
-}
-
-__EXTERN_INLINE void
-ev5_flush_tlb_current_page(struct mm_struct * mm,
- struct vm_area_struct *vma,
- unsigned long addr)
-{
- if (vma->vm_flags & VM_EXEC)
- ev5_flush_tlb_current(mm);
- else
- tbi(2, addr);
-}
-
-
-#ifdef CONFIG_ALPHA_GENERIC
-# define flush_tlb_current alpha_mv.mv_flush_tlb_current
-# define flush_tlb_other alpha_mv.mv_flush_tlb_other
-# define flush_tlb_current_page alpha_mv.mv_flush_tlb_current_page
-#else
-# ifdef CONFIG_ALPHA_EV4
-# define flush_tlb_current ev4_flush_tlb_current
-# define flush_tlb_other ev4_flush_tlb_other
-# define flush_tlb_current_page ev4_flush_tlb_current_page
-# else
-# define flush_tlb_current ev5_flush_tlb_current
-# define flush_tlb_other ev5_flush_tlb_other
-# define flush_tlb_current_page ev5_flush_tlb_current_page
-# endif
-#endif
-
-#ifdef __MMU_EXTERN_INLINE
-#undef __EXTERN_INLINE
-#undef __MMU_EXTERN_INLINE
-#endif
-
-/*
- * Flush current user mapping.
- */
-static inline void flush_tlb(void)
-{
- flush_tlb_current(current->mm);
-}
-
-#ifndef __SMP__
-/*
- * Flush everything (kernel mapping may also have
- * changed due to vmalloc/vfree)
- */
-static inline void flush_tlb_all(void)
-{
- tbia();
-}
-
-/*
- * Flush a specified user mapping
- */
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- if (mm != current->mm)
- flush_tlb_other(mm);
- else
- flush_tlb_current(mm);
-}
-
-/*
- * Page-granular tlb flush.
- *
- * do a tbisd (type = 2) normally, and a tbis (type = 3)
- * if it is an executable mapping. We want to avoid the
- * itlb flush, because that potentially also does a
- * icache flush.
- */
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long addr)
-{
- struct mm_struct * mm = vma->vm_mm;
-
- if (mm != current->mm)
- flush_tlb_other(mm);
- else
- flush_tlb_current_page(mm, vma, addr);
-}
-
-/*
- * Flush a specified range of user mapping: on the
- * Alpha we flush the whole user tlb.
- */
-static inline void flush_tlb_range(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- flush_tlb_mm(mm);
-}
-
-#else /* __SMP__ */
-
-extern void flush_tlb_all(void);
-extern void flush_tlb_mm(struct mm_struct *);
-extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
-extern void flush_tlb_range(struct mm_struct *, unsigned long, unsigned long);
-
-#endif /* __SMP__ */
-
/* Certain architectures need to do special things when PTEs
* within a page table are directly modified. Thus, the following
* hook is made available.
@@ -293,7 +139,7 @@

#define BAD_PAGETABLE __bad_pagetable()
#define BAD_PAGE __bad_page()
-#define ZERO_PAGE(vaddr) (PAGE_OFFSET+0x30A000)
+#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(ZERO_PGE))

/* number of bits that fit into a memory pointer */
#define BITS_PER_PTR (8*sizeof(unsigned long))
@@ -330,8 +176,14 @@
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = ((page-PAGE_OFFSET) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; }
+#define mk_pte(page, pgprot) \
+({ \
+ pte_t pte; \
+ \
+ pte_val(pte) = ((unsigned long)(page - mem_map) << 32) | \
+ pgprot_val(pgprot); \
+ pte; \
+})

extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
{ pte_t pte; pte_val(pte) = (PHYS_TWIDDLE(physpage) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; }
@@ -345,8 +197,8 @@
extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
{ pgd_val(*pgdp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }

-extern inline unsigned long pte_page(pte_t pte)
-{ return PAGE_OFFSET + ((pte_val(pte) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
+#define pte_pagenr(x) ((unsigned long)((pte_val(x) >> 32)))
+#define pte_page(x) (mem_map+pte_pagenr(x))

extern inline unsigned long pmd_page(pmd_t pmd)
{ return PAGE_OFFSET + ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
@@ -368,6 +220,9 @@
extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; }
extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }

+#define page_address(page) ((page)->virtual)
+#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
@@ -395,10 +250,8 @@
#define pgd_offset_k(address) pgd_offset(&init_mm, address)

/* to find an entry in a page-table-directory. */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
-{
- return mm->pgd + ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1));
-}
+#define __pgd_offset(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pgd_offset(mm, address) ((mm)->pgd+__pgd_offset(address))

/* Find an entry in the second-level page table.. */
extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
@@ -412,186 +265,6 @@
return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1));
}

-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
-#ifndef __SMP__
-extern struct pgtable_cache_struct {
- unsigned long *pgd_cache;
- unsigned long *pte_cache;
- unsigned long pgtable_cache_sz;
-} quicklists;
-#else
-#include <asm/smp.h>
-#define quicklists cpu_data[smp_processor_id()]
-#endif
-#define pgd_quicklist (quicklists.pgd_cache)
-#define pmd_quicklist ((unsigned long *)0)
-#define pte_quicklist (quicklists.pte_cache)
-#define pgtable_cache_size (quicklists.pgtable_cache_sz)
-
-extern __inline__ pgd_t *get_pgd_slow(void)
-{
- pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init;
-
- if (ret) {
- init = pgd_offset(&init_mm, 0);
- memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
- memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-
- pgd_val(ret[PTRS_PER_PGD])
- = pte_val(mk_pte((unsigned long)ret, PAGE_KERNEL));
- }
- return ret;
-}
-
-extern __inline__ pgd_t *get_pgd_fast(void)
-{
- unsigned long *ret;
-
- if((ret = pgd_quicklist) != NULL) {
- pgd_quicklist = (unsigned long *)(*ret);
- ret[0] = ret[1];
- pgtable_cache_size--;
- } else
- ret = (unsigned long *)get_pgd_slow();
- return (pgd_t *)ret;
-}
-
-extern __inline__ void free_pgd_fast(pgd_t *pgd)
-{
- *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
- pgd_quicklist = (unsigned long *) pgd;
- pgtable_cache_size++;
-}
-
-extern __inline__ void free_pgd_slow(pgd_t *pgd)
-{
- free_page((unsigned long)pgd);
-}
-
-extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_premasked);
-
-extern __inline__ pmd_t *get_pmd_fast(void)
-{
- unsigned long *ret;
-
- if((ret = (unsigned long *)pte_quicklist) != NULL) {
- pte_quicklist = (unsigned long *)(*ret);
- ret[0] = ret[1];
- pgtable_cache_size--;
- }
- return (pmd_t *)ret;
-}
-
-extern __inline__ void free_pmd_fast(pmd_t *pmd)
-{
- *(unsigned long *)pmd = (unsigned long) pte_quicklist;
- pte_quicklist = (unsigned long *) pmd;
- pgtable_cache_size++;
-}
-
-extern __inline__ void free_pmd_slow(pmd_t *pmd)
-{
- free_page((unsigned long)pmd);
-}
-
-extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
-
-extern __inline__ pte_t *get_pte_fast(void)
-{
- unsigned long *ret;
-
- if((ret = (unsigned long *)pte_quicklist) != NULL) {
- pte_quicklist = (unsigned long *)(*ret);
- ret[0] = ret[1];
- pgtable_cache_size--;
- }
- return (pte_t *)ret;
-}
-
-extern __inline__ void free_pte_fast(pte_t *pte)
-{
- *(unsigned long *)pte = (unsigned long) pte_quicklist;
- pte_quicklist = (unsigned long *) pte;
- pgtable_cache_size++;
-}
-
-extern __inline__ void free_pte_slow(pte_t *pte)
-{
- free_page((unsigned long)pte);
-}
-
-extern void __bad_pte(pmd_t *pmd);
-extern void __bad_pmd(pgd_t *pgd);
-
-#define pte_free_kernel(pte) free_pte_fast(pte)
-#define pte_free(pte) free_pte_fast(pte)
-#define pmd_free_kernel(pmd) free_pmd_fast(pmd)
-#define pmd_free(pmd) free_pmd_fast(pmd)
-#define pgd_free(pgd) free_pgd_fast(pgd)
-#define pgd_alloc() get_pgd_fast()
-
-extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address)
-{
- address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
- if (pmd_none(*pmd)) {
- pte_t *page = get_pte_fast();
-
- if (!page)
- return get_pte_slow(pmd, address);
- pmd_set(pmd, page);
- return page + address;
- }
- if (pmd_bad(*pmd)) {
- __bad_pte(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + address;
-}
-
-extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address)
-{
- address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
- if (pgd_none(*pgd)) {
- pmd_t *page = get_pmd_fast();
-
- if (!page)
- return get_pmd_slow(pgd, address);
- pgd_set(pgd, page);
- return page + address;
- }
- if (pgd_bad(*pgd)) {
- __bad_pmd(pgd);
- return NULL;
- }
- return (pmd_t *) pgd_page(*pgd) + address;
-}
-
-#define pte_alloc_kernel pte_alloc
-#define pmd_alloc_kernel pmd_alloc
-
-extern int do_check_pgt_cache(int, int);
-
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
-{
- struct task_struct * p;
- pgd_t *pgd;
-
- read_lock(&tasklist_lock);
- for_each_task(p) {
- if (!p->mm)
- continue;
- *pgd_offset(p->mm,address) = entry;
- }
- read_unlock(&tasklist_lock);
- for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
- pgd[(address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)] = entry;
-}
-
extern pgd_t swapper_pg_dir[1024];

/*
@@ -610,9 +283,11 @@
extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
{ pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; }

-#define SWP_TYPE(entry) (((entry) >> 32) & 0xff)
-#define SWP_OFFSET(entry) ((entry) >> 40)
-#define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset)))
+#define SWP_TYPE(x) (((x).val >> 32) & 0xff)
+#define SWP_OFFSET(x) ((x).val >> 40)
+#define SWP_ENTRY(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) })
+#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x) ((pte_t) { (x).val })

#define module_map vmalloc
#define module_unmap vfree
@@ -622,6 +297,13 @@
#define kern_addr_valid(addr) (1)

#define io_remap_page_range(start, busaddr, size, prot) \
- remap_page_range(start, virt_to_phys(__ioremap(busaddr)), size, prot)
+ remap_page_range(start, virt_to_phys(__ioremap(busaddr), 0), size, prot)
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))

#endif /* _ALPHA_PGTABLE_H */
diff -urN 2.3.29pre3/include/asm-alpha/system.h alpha/include/asm-alpha/system.h
--- 2.3.29pre3/include/asm-alpha/system.h Sun Nov 21 17:46:05 1999
+++ alpha/include/asm-alpha/system.h Tue Nov 23 14:18:13 1999
@@ -363,6 +363,17 @@
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))

+/* Very dirty but nevertheless very fun hack ;). I recall the aboot printf()
+ that will in turn use the SRM console to do the debugging of the boot
+ process. As there's no runtime symbol table, the address of printf()
+ is hardwired and is in function of the bootlx binary you have in /boot...
+ 1999 Andrea Arcangeli <andrea@suse.de> */
+#if 0
+#define SRM_printf(args...) ({ int (*__SRM_printf)(const char *fmt, ...) = (int (*)(const char *fmt, ...)) 0x20000aa0; __SRM_printf(args); })
+#else
+#define SRM_printf(args...)
+#endif
+
#endif /* __ASSEMBLY__ */

#endif
diff -urN 2.3.29pre3/include/linux/bootmem.h alpha/include/linux/bootmem.h
--- 2.3.29pre3/include/linux/bootmem.h Mon Nov 22 23:08:58 1999
+++ alpha/include/linux/bootmem.h Tue Nov 23 15:29:39 1999
@@ -3,6 +3,7 @@

#include <asm/pgtable.h>
#include <asm/dma.h>
+#include <asm/cache.h>
#include <linux/init.h>

/*
diff -urN 2.3.29pre3/include/linux/ioport.h alpha/include/linux/ioport.h
--- 2.3.29pre3/include/linux/ioport.h Tue Sep 14 14:35:32 1999
+++ alpha/include/linux/ioport.h Mon Nov 22 23:15:10 1999
@@ -80,10 +80,11 @@

extern int request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
+struct pci_dev;
extern int allocate_resource(struct resource *root, struct resource *new,
unsigned long size,
unsigned long min, unsigned long max,
- unsigned long align);
+ unsigned long align, struct pci_dev *);

/* Convenience shorthand with allocation */
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
@@ -106,5 +107,8 @@
#define HAVE_AUTOIRQ
extern void autoirq_setup(int waittime);
extern int autoirq_report(int waittime);
+
+extern unsigned long resource_fixup(struct pci_dev *, struct resource *,
+ unsigned long, unsigned long);

#endif /* _LINUX_IOPORT_H */
diff -urN 2.3.29pre3/include/linux/pci.h alpha/include/linux/pci.h
--- 2.3.29pre3/include/linux/pci.h Thu Nov 11 18:23:12 1999
+++ alpha/include/linux/pci.h Tue Nov 23 15:29:24 1999
@@ -404,8 +404,16 @@
int (*write_dword)(struct pci_dev *, int where, u32 val);
};

+struct pbus_set_ranges_data
+{
+ int found_vga;
+ unsigned long io_start, io_end;
+ unsigned long mem_start, mem_end;
+};
+
void pcibios_init(void);
void pcibios_fixup_bus(struct pci_bus *);
+void pcibios_fixup_pbus_ranges(struct pci_bus *, struct pbus_set_ranges_data *);
int pcibios_enable_device(struct pci_dev *);
char *pcibios_setup (char *str);

diff -urN 2.3.29pre3/kernel/resource.c alpha/kernel/resource.c
--- 2.3.29pre3/kernel/resource.c Sun Nov 21 03:20:20 1999
+++ alpha/kernel/resource.c Mon Nov 22 23:15:10 1999
@@ -126,7 +126,7 @@
static int find_resource(struct resource *root, struct resource *new,
unsigned long size,
unsigned long min, unsigned long max,
- unsigned long align)
+ unsigned long align, struct pci_dev * dev)
{
struct resource *this = root->child;
unsigned long start, end;
@@ -142,6 +142,7 @@
if (end > max)
end = max;
start = (start + align - 1) & ~(align - 1);
+ start = resource_fixup (dev, new, start, size);
if (start < end && end - start + 1 >= size) {
new->start = start;
new->end = start + size - 1;
@@ -161,12 +162,12 @@
int allocate_resource(struct resource *root, struct resource *new,
unsigned long size,
unsigned long min, unsigned long max,
- unsigned long align)
+ unsigned long align, struct pci_dev * dev)
{
int err;

write_lock(&resource_lock);
- err = find_resource(root, new, size, min, max, align);
+ err = find_resource(root, new, size, min, max, align, dev);
if (err >= 0 && __request_resource(root, new))
err = -EBUSY;
write_unlock(&resource_lock);

The patch can be downloaded also from here:

ftp://ftp.*.kernel.org/pub/linux/kernel/people/andrea/patches/v2.3/2.3.29pre3/alpha-1.bz2

andrea@alpha:~ > uname -a
Linux alpha 2.3.29 #77 SMP Tue Nov 23 15:16:07 CET 1999 alpha unknown

;)

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/