diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sparc64/kernel/starfire.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/sparc64/kernel/starfire.c')
-rw-r--r-- | arch/sparc64/kernel/starfire.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/starfire.c b/arch/sparc64/kernel/starfire.c new file mode 100644 index 000000000000..ae859d40771e --- /dev/null +++ b/arch/sparc64/kernel/starfire.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* $Id: starfire.c,v 1.10 2001/04/14 21:13:45 davem Exp $ | ||
2 | * starfire.c: Starfire/E10000 support. | ||
3 | * | ||
4 | * Copyright (C) 1998 David S. Miller (davem@redhat.com) | ||
5 | * Copyright (C) 2000 Anton Blanchard (anton@samba.org) | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/slab.h> | ||
10 | |||
11 | #include <asm/page.h> | ||
12 | #include <asm/oplib.h> | ||
13 | #include <asm/smp.h> | ||
14 | #include <asm/upa.h> | ||
15 | #include <asm/starfire.h> | ||
16 | |||
17 | /* | ||
18 | * A few places around the kernel check this to see if | ||
19 | * they need to call us to do things in a Starfire specific | ||
20 | * way. | ||
21 | */ | ||
22 | int this_is_starfire = 0; | ||
23 | |||
24 | void check_if_starfire(void) | ||
25 | { | ||
26 | int ssnode = prom_finddevice("/ssp-serial"); | ||
27 | if (ssnode != 0 && ssnode != -1) | ||
28 | this_is_starfire = 1; | ||
29 | } | ||
30 | |||
31 | void starfire_cpu_setup(void) | ||
32 | { | ||
33 | /* Currently, nothing to do. */ | ||
34 | } | ||
35 | |||
36 | int starfire_hard_smp_processor_id(void) | ||
37 | { | ||
38 | return upa_readl(0x1fff40000d0UL); | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * Each Starfire board has 32 registers which perform translation | ||
43 | * and delivery of traditional interrupt packets into the extended | ||
44 | * Starfire hardware format. Essentially UPAID's now have 2 more | ||
45 | * bits than in all previous Sun5 systems. | ||
46 | */ | ||
47 | struct starfire_irqinfo { | ||
48 | unsigned long imap_slots[32]; | ||
49 | unsigned long tregs[32]; | ||
50 | struct starfire_irqinfo *next; | ||
51 | int upaid, hwmid; | ||
52 | }; | ||
53 | |||
54 | static struct starfire_irqinfo *sflist = NULL; | ||
55 | |||
56 | /* Beam me up Scott(McNeil)y... */ | ||
57 | void *starfire_hookup(int upaid) | ||
58 | { | ||
59 | struct starfire_irqinfo *p; | ||
60 | unsigned long treg_base, hwmid, i; | ||
61 | |||
62 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
63 | if (!p) { | ||
64 | prom_printf("starfire_hookup: No memory, this is insane.\n"); | ||
65 | prom_halt(); | ||
66 | } | ||
67 | treg_base = 0x100fc000000UL; | ||
68 | hwmid = ((upaid & 0x3c) << 1) | | ||
69 | ((upaid & 0x40) >> 4) | | ||
70 | (upaid & 0x3); | ||
71 | p->hwmid = hwmid; | ||
72 | treg_base += (hwmid << 33UL); | ||
73 | treg_base += 0x200UL; | ||
74 | for (i = 0; i < 32; i++) { | ||
75 | p->imap_slots[i] = 0UL; | ||
76 | p->tregs[i] = treg_base + (i * 0x10UL); | ||
77 | /* Lets play it safe and not overwrite existing mappings */ | ||
78 | if (upa_readl(p->tregs[i]) != 0) | ||
79 | p->imap_slots[i] = 0xdeadbeaf; | ||
80 | } | ||
81 | p->upaid = upaid; | ||
82 | p->next = sflist; | ||
83 | sflist = p; | ||
84 | |||
85 | return (void *) p; | ||
86 | } | ||
87 | |||
88 | unsigned int starfire_translate(unsigned long imap, | ||
89 | unsigned int upaid) | ||
90 | { | ||
91 | struct starfire_irqinfo *p; | ||
92 | unsigned int bus_hwmid; | ||
93 | unsigned int i; | ||
94 | |||
95 | bus_hwmid = (((unsigned long)imap) >> 33) & 0x7f; | ||
96 | for (p = sflist; p != NULL; p = p->next) | ||
97 | if (p->hwmid == bus_hwmid) | ||
98 | break; | ||
99 | if (p == NULL) { | ||
100 | prom_printf("XFIRE: Cannot find irqinfo for imap %016lx\n", | ||
101 | ((unsigned long)imap)); | ||
102 | prom_halt(); | ||
103 | } | ||
104 | for (i = 0; i < 32; i++) { | ||
105 | if (p->imap_slots[i] == imap || | ||
106 | p->imap_slots[i] == 0UL) | ||
107 | break; | ||
108 | } | ||
109 | if (i == 32) { | ||
110 | printk("starfire_translate: Are you kidding me?\n"); | ||
111 | panic("Lucy in the sky...."); | ||
112 | } | ||
113 | p->imap_slots[i] = imap; | ||
114 | |||
115 | /* map to real upaid */ | ||
116 | upaid = (((upaid & 0x3c) << 1) | | ||
117 | ((upaid & 0x40) >> 4) | | ||
118 | (upaid & 0x3)); | ||
119 | |||
120 | upa_writel(upaid, p->tregs[i]); | ||
121 | |||
122 | return i; | ||
123 | } | ||