From: Ladislav Michl <ladis@linux-mips.org>
To: linux-mips@linux-mips.org
Cc: Ralf Baechle <ralf@linux-mips.org>
Subject: [PATCH] High memory detection for Indigo2
Date: Wed, 14 May 2003 09:53:40 +0200 [thread overview]
Message-ID: <20030514075340.GA4710@simek> (raw)
Hi,
this is second version of high memory detection for Indigo2.
It will allow to use more that 256M RAM. I was told by Ralf that
CONFIG_HIGHMEM is broken for I2, so you'll need to build 64bit
kernel to use it (I was also told there is more bugs related to
high memory support and I think that once high memory is detected
properly more people will be interested in hunting those bugs :))
Patch also completely replaces ARCS based memory detection by
memory controller based one. We need to read memory configuration
from MC anyway, so this will make kernel a bit smaller.
Index: arch/mips/sgi-ip22/ip22-mc.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/sgi-ip22/ip22-mc.c,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 ip22-mc.c
--- arch/mips/sgi-ip22/ip22-mc.c 6 Apr 2003 01:47:27 -0000 1.1.2.7
+++ arch/mips/sgi-ip22/ip22-mc.c 14 May 2003 07:37:53 -0000
@@ -1,51 +1,111 @@
/*
- * ip22-mc.c: Routines for manipulating the INDY memory controller.
+ * ip22-mc.c: Routines for manipulating SGI Memory Controller.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
+ * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org)
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
#include <asm/ptrace.h>
#include <asm/sgialib.h>
#include <asm/sgi/mc.h>
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>
-/* #define DEBUG_SGIMC */
-
struct sgimc_regs *sgimc;
-#ifdef DEBUG_SGIMC
-static inline char *mconfig_string(unsigned long val)
+static inline unsigned int get_bank_size(unsigned int val)
{
switch(val & SGIMC_MCONFIG_RMASK) {
- case SGIMC_MCONFIG_FOURMB:
- return "4MB";
-
- case SGIMC_MCONFIG_EIGHTMB:
- return "8MB";
+ case SGIMC_MCONFIG_256K: return 4*4*256 * 1024;
+ case SGIMC_MCONFIG_512K: return 4*4*512 * 1024;
+ case SGIMC_MCONFIG_1M: return 4*4*1024 * 1024;
+ case SGIMC_MCONFIG_2M: return 4*4*2048 * 1024;
+ case SGIMC_MCONFIG_4M: return 4*4*4096 * 1024;
+ case SGIMC_MCONFIG_8M: return 4*4*8192 * 1024;
+ default: return 0;
+ }
+}
- case SGIMC_MCONFIG_SXTEENMB:
- return "16MB";
+static inline unsigned int get_bank_config(int bank)
+{
+ unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0;
+ return bank % 2 ? res & 0xffff : res >> 16;
+}
- case SGIMC_MCONFIG_TTWOMB:
- return "32MB";
+struct mem {
+ unsigned long addr;
+ unsigned long size;
+};
- case SGIMC_MCONFIG_SFOURMB:
- return "64MB";
+/*
+ * Detect installed memory, do some sanity checks and notify kernel about it
+ */
+static void probe_memory(void)
+{
+ int i, j, found, cnt = 0;
+ struct mem bank[4];
+ struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}};
+
+ printk(KERN_INFO "MC: Probing memory configuration:\n");
+ for (i = 0; i < ARRAY_SIZE(bank); i++) {
+ int tmp = get_bank_config(i);
+ if (!(tmp & SGIMC_MCONFIG_BVALID))
+ continue;
+
+ if (!(bank[cnt].size = get_bank_size(tmp))) {
+ printk(KERN_WARNING " bank%d: unknown, ignored\n", i);
+ continue;
+ }
- case SGIMC_MCONFIG_OTEIGHTMB:
- return "128MB";
+ bank[cnt].addr = (tmp & SGIMC_MCONFIG_BASEADDR) << 22;
+ printk(KERN_INFO " bank%d: %3ldM @ %08lx\n",
+ i, bank[cnt].size / 1024 / 1024, bank[cnt].addr);
+ cnt++;
+ }
- default:
- return "wheee, unknown";
+ /* And you thought bubble sort is dead algorithm... */
+ do {
+ unsigned long addr, size;
+
+ found = 0;
+ for (i = 1; i < cnt; i++)
+ if (bank[i-1].addr > bank[i].addr) {
+ addr = bank[i].addr;
+ size = bank[i].size;
+ bank[i].addr = bank[i-1].addr;
+ bank[i].size = bank[i-1].size;
+ bank[i-1].addr = addr;
+ bank[i-1].size = size;
+ found = 1;
+ }
+ } while (found);
+
+ /* Figure out how are memory banks mapped into spaces */
+ for (i = 0; i < cnt; i++) {
+ found = 0;
+ for (j = 0; j < ARRAY_SIZE(space) && !found; j++)
+ if (space[j].addr + space[j].size == bank[i].addr) {
+ space[j].size += bank[i].size;
+ found = 1;
+ }
+ /* There is either hole or overlapping memory */
+ if (!found)
+ printk(KERN_CRIT "MC: Memory configuration mismatch "
+ "(%08lx), expect Bus Error soon\n",
+ bank[i].addr);
}
+
+ for (i = 0; i < ARRAY_SIZE(space); i++)
+ if (space[i].size)
+ add_memory_region(space[i].addr, space[i].size,
+ BOOT_MEM_RAM);
}
-#endif
void __init sgimc_init(void)
{
@@ -56,17 +116,6 @@
printk(KERN_INFO "MC: SGI memory controller Revision %d\n",
(int) sgimc->systemid & SGIMC_SYSID_MASKREV);
-#ifdef DEBUG_SGIMC
- prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n",
- mconfig_string(sgimc->mconfig0),
- mconfig_string(sgimc->mconfig1));
-
- prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n",
- sgimc->cpuctrl0, sgimc->cpuctrl1);
- prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n",
- sgimc->divider, sgimc->gioparm);
-#endif
-
/* Place the MC into a known state. This must be done before
* interrupts are first enabled etc.
*/
@@ -126,27 +175,32 @@
*/
/* First the basic invariants across all GIO64 implementations. */
- tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits. */
- tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists. */
+ tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */
+ tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */
if (ip22_is_fullhouse()) {
/* Fullhouse specific settings. */
if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) {
- tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */
- tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */
- tmp |= SGIMC_GIOPAR_MASTEREXP1;/* exp1 masters */
- tmp |= SGIMC_GIOPAR_RTIMEEXP0; /* exp0 is realtime */
+ tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */
+ tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */
+ tmp |= SGIMC_GIOPAR_MASTEREXP1; /* exp1 masters */
+ tmp |= SGIMC_GIOPAR_RTIMEEXP0; /* exp0 is realtime */
} else {
- tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC 64bits */
- tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */
+ tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC 64bits */
+ tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */
tmp |= SGIMC_GIOPAR_PLINEEXP1;
- tmp |= SGIMC_GIOPAR_MASTEREISA;/* EISA masters */
- tmp |= SGIMC_GIOPAR_GFX64; /* GFX at 64 bits */
+ tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */
+ tmp |= SGIMC_GIOPAR_GFX64; /* GFX at 64 bits */
}
} else {
/* Guiness specific settings. */
- tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */
- tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */
+ tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */
+ tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */
}
- sgimc->giopar = tmp; /* poof */
+ sgimc->giopar = tmp; /* poof */
+
+ probe_memory();
}
+
+void __init prom_meminit(void) {}
+void __init prom_free_prom_memory (void) {}
Index: arch/mips/config-shared.in
===================================================================
RCS file: /home/cvs/linux/arch/mips/Attic/config-shared.in,v
retrieving revision 1.1.2.59
diff -u -r1.1.2.59 config-shared.in
--- arch/mips/config-shared.in 5 May 2003 07:50:48 -0000 1.1.2.59
+++ arch/mips/config-shared.in 14 May 2003 07:37:53 -0000
@@ -481,7 +481,6 @@
fi
if [ "$CONFIG_SGI_IP22" = "y" ]; then
define_bool CONFIG_ARC32 y
- define_bool CONFIG_ARC_MEMORY y
define_bool CONFIG_ARC_PROMLIB y
define_bool CONFIG_BOARD_SCACHE y
define_bool CONFIG_BOOT_ELF32 y
Index: include/asm-mips/sgi/mc.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/sgi/mc.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 mc.h
--- include/asm-mips/sgi/mc.h 27 Apr 2003 22:25:28 -0000 1.1.2.2
+++ include/asm-mips/sgi/mc.h 14 May 2003 07:37:53 -0000
@@ -95,19 +95,22 @@
u32 _unused10[3];
volatile u32 lbursttp; /* Time period for long bursts */
+ /* MC chip can drive up to 4 bank 4 SIMMs each. All SIMMs in bank must
+ * be the same size. The size encoding for supported SIMMs is bellow */
u32 _unused11[9];
volatile u32 mconfig0; /* Memory config register zero */
u32 _unused12;
volatile u32 mconfig1; /* Memory config register one */
-
- /* These defines apply to both mconfig registers above. */
-#define SGIMC_MCONFIG_FOURMB 0x00000000 /* Physical ram = 4megs */
-#define SGIMC_MCONFIG_EIGHTMB 0x00000100 /* Physical ram = 8megs */
-#define SGIMC_MCONFIG_SXTEENMB 0x00000300 /* Physical ram = 16megs */
-#define SGIMC_MCONFIG_TTWOMB 0x00000700 /* Physical ram = 32megs */
-#define SGIMC_MCONFIG_SFOURMB 0x00000f00 /* Physical ram = 64megs */
-#define SGIMC_MCONFIG_OTEIGHTMB 0x00001f00 /* Physical ram = 128megs */
+#define SGIMC_MCONFIG_BASEADDR 0x000000ff /* Base address of bank*/
+#define SGIMC_MCONFIG_256K 0x00000000 /* 256k x 36 bits */
+#define SGIMC_MCONFIG_512K 0x00000100 /* 512k x 36 bits, 2 subbanks */
+#define SGIMC_MCONFIG_1M 0x00000300 /* 1M x 36 bits */
+#define SGIMC_MCONFIG_2M 0x00000700 /* 2M x 36 bits, 2 subbanks */
+#define SGIMC_MCONFIG_4M 0x00000f00 /* 4M x 36 bits */
+#define SGIMC_MCONFIG_8M 0x00001f00 /* 8M x 36 bits, 2 subbanks */
#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */
+#define SGIMC_MCONFIG_BVALID 0x00002000 /* Bank is valid */
+#define SGIMC_MCONFIG_SBANKS 0x00004000 /* Number of subbanks */
u32 _unused13;
volatile u32 cmacc; /* Mem access config for CPU */
Index: include/asm-mips64/sgi/mc.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips64/sgi/mc.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 mc.h
--- include/asm-mips64/sgi/mc.h 27 Apr 2003 22:25:28 -0000 1.1.2.2
+++ include/asm-mips64/sgi/mc.h 14 May 2003 07:37:53 -0000
@@ -95,19 +95,22 @@
u32 _unused10[3];
volatile u32 lbursttp; /* Time period for long bursts */
+ /* MC chip can drive up to 4 bank 4 SIMMs each. All SIMMs in bank must
+ * be the same size. The size encoding for supported SIMMs is bellow */
u32 _unused11[9];
volatile u32 mconfig0; /* Memory config register zero */
u32 _unused12;
volatile u32 mconfig1; /* Memory config register one */
-
- /* These defines apply to both mconfig registers above. */
-#define SGIMC_MCONFIG_FOURMB 0x00000000 /* Physical ram = 4megs */
-#define SGIMC_MCONFIG_EIGHTMB 0x00000100 /* Physical ram = 8megs */
-#define SGIMC_MCONFIG_SXTEENMB 0x00000300 /* Physical ram = 16megs */
-#define SGIMC_MCONFIG_TTWOMB 0x00000700 /* Physical ram = 32megs */
-#define SGIMC_MCONFIG_SFOURMB 0x00000f00 /* Physical ram = 64megs */
-#define SGIMC_MCONFIG_OTEIGHTMB 0x00001f00 /* Physical ram = 128megs */
+#define SGIMC_MCONFIG_BASEADDR 0x000000ff /* Base address of bank*/
+#define SGIMC_MCONFIG_256K 0x00000000 /* 256k x 36 bits */
+#define SGIMC_MCONFIG_512K 0x00000100 /* 512k x 36 bits, 2 subbanks */
+#define SGIMC_MCONFIG_1M 0x00000300 /* 1M x 36 bits */
+#define SGIMC_MCONFIG_2M 0x00000700 /* 2M x 36 bits, 2 subbanks */
+#define SGIMC_MCONFIG_4M 0x00000f00 /* 4M x 36 bits */
+#define SGIMC_MCONFIG_8M 0x00001f00 /* 8M x 36 bits, 2 subbanks */
#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */
+#define SGIMC_MCONFIG_BVALID 0x00002000 /* Bank is valid */
+#define SGIMC_MCONFIG_SBANKS 0x00004000 /* Number of subbanks */
u32 _unused13;
volatile u32 cmacc; /* Mem access config for CPU */
reply other threads:[~2003-05-14 7:54 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030514075340.GA4710@simek \
--to=ladis@linux-mips.org \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.