diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-10 10:29:28 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-10 12:55:32 -0400 |
commit | 22d5c67c5b0476e463ce4b632ba9ec3953d33a5f (patch) | |
tree | 2a0e19587aa081c48f3cbb60585d47ebc9c52294 /arch/x86 | |
parent | 3b33553badcde952adcf3b3ba5faae38d7d85071 (diff) |
x86, VisWS: turn into generic arch, make VisWS boot on a regular PC
first step: make the VISWS subarch boot on a regular PC.
We take various shortcuts for that. We copy the generic arch setup file over
into the VISWS setup file.
This is the only step that is not expected to boot on a real VISWS.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/apic_32.c | 2 | ||||
-rw-r--r-- | arch/x86/mach-visws/reboot.c | 4 | ||||
-rw-r--r-- | arch/x86/mach-visws/setup.c | 249 | ||||
-rw-r--r-- | arch/x86/mach-visws/traps.c | 6 | ||||
-rw-r--r-- | arch/x86/mach-visws/visws_apic.c | 3 | ||||
-rw-r--r-- | arch/x86/pci/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/pci/visws.c | 6 |
7 files changed, 118 insertions, 154 deletions
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index 3e947208b9d9..3e58b676d23b 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c | |||
@@ -974,7 +974,7 @@ void __cpuinit setup_local_APIC(void) | |||
974 | * Double-check whether this APIC is really registered. | 974 | * Double-check whether this APIC is really registered. |
975 | */ | 975 | */ |
976 | if (!apic_id_registered()) | 976 | if (!apic_id_registered()) |
977 | BUG(); | 977 | WARN_ON_ONCE(1); |
978 | 978 | ||
979 | /* | 979 | /* |
980 | * Intel recommends to set DFR, LDR and TPR before enabling | 980 | * Intel recommends to set DFR, LDR and TPR before enabling |
diff --git a/arch/x86/mach-visws/reboot.c b/arch/x86/mach-visws/reboot.c index 99332abfad42..79c26eab8824 100644 --- a/arch/x86/mach-visws/reboot.c +++ b/arch/x86/mach-visws/reboot.c | |||
@@ -33,7 +33,7 @@ void machine_restart(char * __unused) | |||
33 | void machine_power_off(void) | 33 | void machine_power_off(void) |
34 | { | 34 | { |
35 | unsigned short pm_status; | 35 | unsigned short pm_status; |
36 | extern unsigned int pci_bus0; | 36 | /* extern unsigned int pci_bus0; */ |
37 | 37 | ||
38 | while ((pm_status = inw(PMSTS_PORT)) & 0x100) | 38 | while ((pm_status = inw(PMSTS_PORT)) & 0x100) |
39 | outw(pm_status, PMSTS_PORT); | 39 | outw(pm_status, PMSTS_PORT); |
@@ -45,7 +45,7 @@ void machine_power_off(void) | |||
45 | #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ | 45 | #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ |
46 | (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) | 46 | (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) |
47 | 47 | ||
48 | outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); | 48 | /* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ |
49 | outl(PIIX_SPECIAL_STOP, 0xCFC); | 49 | outl(PIIX_SPECIAL_STOP, 0xCFC); |
50 | } | 50 | } |
51 | 51 | ||
diff --git a/arch/x86/mach-visws/setup.c b/arch/x86/mach-visws/setup.c index d67868ec9b7f..2f5e277686b8 100644 --- a/arch/x86/mach-visws/setup.c +++ b/arch/x86/mach-visws/setup.c | |||
@@ -1,183 +1,144 @@ | |||
1 | /* | 1 | /* |
2 | * Unmaintained SGI Visual Workstation support. | 2 | * Machine specific setup for generic |
3 | * Split out from setup.c by davej@suse.de | ||
4 | */ | 3 | */ |
5 | 4 | ||
6 | #include <linux/smp.h> | 5 | #include <linux/smp.h> |
7 | #include <linux/init.h> | 6 | #include <linux/init.h> |
8 | #include <linux/interrupt.h> | 7 | #include <linux/interrupt.h> |
9 | #include <linux/module.h> | 8 | #include <asm/acpi.h> |
10 | |||
11 | #include <asm/fixmap.h> | ||
12 | #include <asm/arch_hooks.h> | 9 | #include <asm/arch_hooks.h> |
13 | #include <asm/io.h> | ||
14 | #include <asm/e820.h> | 10 | #include <asm/e820.h> |
15 | #include <asm/setup.h> | 11 | #include <asm/setup.h> |
16 | #include "cobalt.h" | ||
17 | #include "piix4.h" | ||
18 | |||
19 | int no_broadcast; | ||
20 | |||
21 | char visws_board_type = -1; | ||
22 | char visws_board_rev = -1; | ||
23 | |||
24 | void __init visws_get_board_type_and_rev(void) | ||
25 | { | ||
26 | int raw; | ||
27 | |||
28 | visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) | ||
29 | >> PIIX_GPI_BD_SHIFT; | ||
30 | /* | ||
31 | * Get Board rev. | ||
32 | * First, we have to initialize the 307 part to allow us access | ||
33 | * to the GPIO registers. Let's map them at 0x0fc0 which is right | ||
34 | * after the PIIX4 PM section. | ||
35 | */ | ||
36 | outb_p(SIO_DEV_SEL, SIO_INDEX); | ||
37 | outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ | ||
38 | |||
39 | outb_p(SIO_DEV_MSB, SIO_INDEX); | ||
40 | outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ | ||
41 | |||
42 | outb_p(SIO_DEV_LSB, SIO_INDEX); | ||
43 | outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ | ||
44 | |||
45 | outb_p(SIO_DEV_ENB, SIO_INDEX); | ||
46 | outb_p(1, SIO_DATA); /* Enable GPIO registers. */ | ||
47 | |||
48 | /* | ||
49 | * Now, we have to map the power management section to write | ||
50 | * a bit which enables access to the GPIO registers. | ||
51 | * What lunatic came up with this shit? | ||
52 | */ | ||
53 | outb_p(SIO_DEV_SEL, SIO_INDEX); | ||
54 | outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ | ||
55 | 12 | ||
56 | outb_p(SIO_DEV_MSB, SIO_INDEX); | 13 | #ifdef CONFIG_HOTPLUG_CPU |
57 | outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ | 14 | #define DEFAULT_SEND_IPI (1) |
58 | 15 | #else | |
59 | outb_p(SIO_DEV_LSB, SIO_INDEX); | 16 | #define DEFAULT_SEND_IPI (0) |
60 | outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ | 17 | #endif |
61 | |||
62 | outb_p(SIO_DEV_ENB, SIO_INDEX); | ||
63 | outb_p(1, SIO_DATA); /* Enable PM registers. */ | ||
64 | |||
65 | /* | ||
66 | * Now, write the PM register which enables the GPIO registers. | ||
67 | */ | ||
68 | outb_p(SIO_PM_FER2, SIO_PM_INDEX); | ||
69 | outb_p(SIO_PM_GP_EN, SIO_PM_DATA); | ||
70 | |||
71 | /* | ||
72 | * Now, initialize the GPIO registers. | ||
73 | * We want them all to be inputs which is the | ||
74 | * power on default, so let's leave them alone. | ||
75 | * So, let's just read the board rev! | ||
76 | */ | ||
77 | raw = inb_p(SIO_GP_DATA1); | ||
78 | raw &= 0x7f; /* 7 bits of valid board revision ID. */ | ||
79 | |||
80 | if (visws_board_type == VISWS_320) { | ||
81 | if (raw < 0x6) { | ||
82 | visws_board_rev = 4; | ||
83 | } else if (raw < 0xc) { | ||
84 | visws_board_rev = 5; | ||
85 | } else { | ||
86 | visws_board_rev = 6; | ||
87 | } | ||
88 | } else if (visws_board_type == VISWS_540) { | ||
89 | visws_board_rev = 2; | ||
90 | } else { | ||
91 | visws_board_rev = raw; | ||
92 | } | ||
93 | |||
94 | printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n", | ||
95 | (visws_board_type == VISWS_320 ? "320" : | ||
96 | (visws_board_type == VISWS_540 ? "540" : | ||
97 | "unknown")), visws_board_rev); | ||
98 | } | ||
99 | 18 | ||
19 | int no_broadcast=DEFAULT_SEND_IPI; | ||
20 | |||
21 | /** | ||
22 | * pre_intr_init_hook - initialisation prior to setting up interrupt vectors | ||
23 | * | ||
24 | * Description: | ||
25 | * Perform any necessary interrupt initialisation prior to setting up | ||
26 | * the "ordinary" interrupt call gates. For legacy reasons, the ISA | ||
27 | * interrupts should be initialised here if the machine emulates a PC | ||
28 | * in any way. | ||
29 | **/ | ||
100 | void __init pre_intr_init_hook(void) | 30 | void __init pre_intr_init_hook(void) |
101 | { | 31 | { |
102 | init_VISWS_APIC_irqs(); | 32 | init_ISA_irqs(); |
103 | } | 33 | } |
104 | 34 | ||
35 | /* | ||
36 | * IRQ2 is cascade interrupt to second interrupt controller | ||
37 | */ | ||
38 | static struct irqaction irq2 = { | ||
39 | .handler = no_action, | ||
40 | .mask = CPU_MASK_NONE, | ||
41 | .name = "cascade", | ||
42 | }; | ||
43 | |||
44 | /** | ||
45 | * intr_init_hook - post gate setup interrupt initialisation | ||
46 | * | ||
47 | * Description: | ||
48 | * Fill in any interrupts that may have been left out by the general | ||
49 | * init_IRQ() routine. interrupts having to do with the machine rather | ||
50 | * than the devices on the I/O bus (like APIC interrupts in intel MP | ||
51 | * systems) are started here. | ||
52 | **/ | ||
105 | void __init intr_init_hook(void) | 53 | void __init intr_init_hook(void) |
106 | { | 54 | { |
107 | #ifdef CONFIG_X86_LOCAL_APIC | 55 | #ifdef CONFIG_X86_LOCAL_APIC |
108 | apic_intr_init(); | 56 | apic_intr_init(); |
109 | #endif | 57 | #endif |
58 | |||
59 | if (!acpi_ioapic) | ||
60 | setup_irq(2, &irq2); | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * pre_setup_arch_hook - hook called prior to any setup_arch() execution | ||
65 | * | ||
66 | * Description: | ||
67 | * generally used to activate any machine specific identification | ||
68 | * routines that may be needed before setup_arch() runs. On VISWS | ||
69 | * this is used to get the board revision and type. | ||
70 | **/ | ||
71 | void __init pre_setup_arch_hook(void) | ||
72 | { | ||
110 | } | 73 | } |
111 | 74 | ||
112 | void __init pre_setup_arch_hook() | 75 | /** |
76 | * trap_init_hook - initialise system specific traps | ||
77 | * | ||
78 | * Description: | ||
79 | * Called as the final act of trap_init(). Used in VISWS to initialise | ||
80 | * the various board specific APIC traps. | ||
81 | **/ | ||
82 | void __init trap_init_hook(void) | ||
113 | { | 83 | { |
114 | visws_get_board_type_and_rev(); | ||
115 | } | 84 | } |
116 | 85 | ||
117 | static struct irqaction irq0 = { | 86 | static struct irqaction irq0 = { |
118 | .handler = timer_interrupt, | 87 | .handler = timer_interrupt, |
119 | .flags = IRQF_DISABLED | IRQF_IRQPOLL, | 88 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, |
120 | .name = "timer", | 89 | .mask = CPU_MASK_NONE, |
90 | .name = "timer" | ||
121 | }; | 91 | }; |
122 | 92 | ||
93 | /** | ||
94 | * time_init_hook - do any specific initialisations for the system timer. | ||
95 | * | ||
96 | * Description: | ||
97 | * Must plug the system timer interrupt source at HZ into the IRQ listed | ||
98 | * in irq_vectors.h:TIMER_IRQ | ||
99 | **/ | ||
123 | void __init time_init_hook(void) | 100 | void __init time_init_hook(void) |
124 | { | 101 | { |
125 | printk(KERN_INFO "Starting Cobalt Timer system clock\n"); | 102 | irq0.mask = cpumask_of_cpu(0); |
126 | |||
127 | /* Set the countdown value */ | ||
128 | co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ); | ||
129 | |||
130 | /* Start the timer */ | ||
131 | co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN); | ||
132 | |||
133 | /* Enable (unmask) the timer interrupt */ | ||
134 | co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); | ||
135 | |||
136 | /* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */ | ||
137 | setup_irq(0, &irq0); | 103 | setup_irq(0, &irq0); |
138 | } | 104 | } |
139 | 105 | ||
140 | /* Hook for machine specific memory setup. */ | 106 | #ifdef CONFIG_MCA |
141 | 107 | /** | |
142 | #define MB (1024 * 1024) | 108 | * mca_nmi_hook - hook into MCA specific NMI chain |
143 | 109 | * | |
144 | unsigned long sgivwfb_mem_phys; | 110 | * Description: |
145 | unsigned long sgivwfb_mem_size; | 111 | * The MCA (Microchannel Architecture) has an NMI chain for NMI sources |
146 | EXPORT_SYMBOL(sgivwfb_mem_phys); | 112 | * along the MCA bus. Use this to hook into that chain if you will need |
147 | EXPORT_SYMBOL(sgivwfb_mem_size); | 113 | * it. |
148 | 114 | **/ | |
149 | long long mem_size __initdata = 0; | 115 | void mca_nmi_hook(void) |
150 | |||
151 | char * __init machine_specific_memory_setup(void) | ||
152 | { | 116 | { |
153 | long long gfx_mem_size = 8 * MB; | 117 | /* If I recall correctly, there's a whole bunch of other things that |
118 | * we can do to check for NMI problems, but that's all I know about | ||
119 | * at the moment. | ||
120 | */ | ||
154 | 121 | ||
155 | mem_size = boot_params.alt_mem_k; | 122 | printk("NMI generated from unknown source!\n"); |
123 | } | ||
124 | #endif | ||
156 | 125 | ||
157 | if (!mem_size) { | 126 | static __init int no_ipi_broadcast(char *str) |
158 | printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); | 127 | { |
159 | mem_size = 128 * MB; | 128 | get_option(&str, &no_broadcast); |
160 | } | 129 | printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : |
130 | "IPI Broadcast"); | ||
131 | return 1; | ||
132 | } | ||
161 | 133 | ||
162 | /* | 134 | __setup("no_ipi_broadcast=", no_ipi_broadcast); |
163 | * this hardcodes the graphics memory to 8 MB | ||
164 | * it really should be sized dynamically (or at least | ||
165 | * set as a boot param) | ||
166 | */ | ||
167 | if (!sgivwfb_mem_size) { | ||
168 | printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); | ||
169 | sgivwfb_mem_size = 8 * MB; | ||
170 | } | ||
171 | 135 | ||
172 | /* | 136 | static int __init print_ipi_mode(void) |
173 | * Trim to nearest MB | 137 | { |
174 | */ | 138 | printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : |
175 | sgivwfb_mem_size &= ~((1 << 20) - 1); | 139 | "Shortcut"); |
176 | sgivwfb_mem_phys = mem_size - gfx_mem_size; | 140 | return 0; |
141 | } | ||
177 | 142 | ||
178 | e820_add_region(0, LOWMEMSIZE(), E820_RAM); | 143 | late_initcall(print_ipi_mode); |
179 | e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); | ||
180 | e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); | ||
181 | 144 | ||
182 | return "PROM"; | ||
183 | } | ||
diff --git a/arch/x86/mach-visws/traps.c b/arch/x86/mach-visws/traps.c index bfac6ba10f8a..dd1f5fa94210 100644 --- a/arch/x86/mach-visws/traps.c +++ b/arch/x86/mach-visws/traps.c | |||
@@ -25,13 +25,13 @@ static __init void lithium_init(void) | |||
25 | if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || | 25 | if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || |
26 | (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { | 26 | (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { |
27 | printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A'); | 27 | printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A'); |
28 | panic("This machine is not SGI Visual Workstation 320/540"); | 28 | /* panic("This machine is not SGI Visual Workstation 320/540"); */ |
29 | } | 29 | } |
30 | 30 | ||
31 | if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || | 31 | if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || |
32 | (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { | 32 | (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { |
33 | printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B'); | 33 | printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B'); |
34 | panic("This machine is not SGI Visual Workstation 320/540"); | 34 | /* panic("This machine is not SGI Visual Workstation 320/540"); */ |
35 | } | 35 | } |
36 | 36 | ||
37 | li_pcia_write16(LI_PCI_INTEN, ALLDEVS); | 37 | li_pcia_write16(LI_PCI_INTEN, ALLDEVS); |
@@ -62,7 +62,7 @@ static __init void cobalt_init(void) | |||
62 | co_apic_read(CO_APIC_ID)); | 62 | co_apic_read(CO_APIC_ID)); |
63 | } | 63 | } |
64 | 64 | ||
65 | void __init trap_init_hook(void) | 65 | void __init trap_init_hook_dontuse(void) |
66 | { | 66 | { |
67 | lithium_init(); | 67 | lithium_init(); |
68 | cobalt_init(); | 68 | cobalt_init(); |
diff --git a/arch/x86/mach-visws/visws_apic.c b/arch/x86/mach-visws/visws_apic.c index d8b2cfd85d92..8b1cd8e01cb4 100644 --- a/arch/x86/mach-visws/visws_apic.c +++ b/arch/x86/mach-visws/visws_apic.c | |||
@@ -25,6 +25,9 @@ | |||
25 | 25 | ||
26 | #include "cobalt.h" | 26 | #include "cobalt.h" |
27 | 27 | ||
28 | char visws_board_type = -1; | ||
29 | char visws_board_rev = -1; | ||
30 | |||
28 | static DEFINE_SPINLOCK(cobalt_lock); | 31 | static DEFINE_SPINLOCK(cobalt_lock); |
29 | 32 | ||
30 | /* | 33 | /* |
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 99d9f095e4d4..fa0164d80bbd 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile | |||
@@ -11,7 +11,7 @@ pci-y += legacy.o irq.o | |||
11 | 11 | ||
12 | # Careful: VISWS overrule the pci-y above. The colons are | 12 | # Careful: VISWS overrule the pci-y above. The colons are |
13 | # therefor correct. This needs a proper fix by distangling the code. | 13 | # therefor correct. This needs a proper fix by distangling the code. |
14 | pci-$(CONFIG_X86_VISWS) := visws.o fixup.o | 14 | #pci-$(CONFIG_X86_VISWS) := visws.o irq.o fixup.o |
15 | 15 | ||
16 | pci-$(CONFIG_X86_NUMAQ) += numa.o | 16 | pci-$(CONFIG_X86_NUMAQ) += numa.o |
17 | 17 | ||
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 16e52063ecb3..343ccf668d14 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c | |||
@@ -16,10 +16,10 @@ | |||
16 | static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } | 16 | static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } |
17 | static void pci_visws_disable_irq(struct pci_dev *dev) { } | 17 | static void pci_visws_disable_irq(struct pci_dev *dev) { } |
18 | 18 | ||
19 | int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; | 19 | /* int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; */ |
20 | void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; | 20 | /* void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; */ |
21 | 21 | ||
22 | void __init pcibios_penalize_isa_irq(int irq, int active) {} | 22 | /* void __init pcibios_penalize_isa_irq(int irq, int active) {} */ |
23 | 23 | ||
24 | 24 | ||
25 | unsigned int pci_bus0, pci_bus1; | 25 | unsigned int pci_bus0, pci_bus1; |