Commit d3791f47 authored by Ralf Bächle's avatar Ralf Bächle Committed by Linus Torvalds

[PATCH] 2.7.73 SGI IP27 update

An update of the SGI IP27 aka Origin 200/2000/Onyx 2 support.
parent 80b11f5a
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
# Makefile for the IP27 specific kernel interface routines under Linux. # Makefile for the IP27 specific kernel interface routines under Linux.
# #
EXTRA_AFLAGS := $(CFLAGS)
obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \ ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o ip27-setup.o ip27-timer.o
EXTRA_AFLAGS := $(CFLAGS)
1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay 1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay
not to write to the IOC3 ever. not to write to the IOC3 ever.
2. Need to figure out RRB allocation in bridge_startup(). 2. Need to figure out RRB allocation in bridge_startup().
3. Need to figure out why address swaizzling is needed in inw/outw for 3. Need to figure out why address swaizzling is needed in inw/outw for
Qlogic scsi controllers. Qlogic scsi controllers.
4. Need to integrate ip27-klconfig.c:find_lboard and 4. Need to integrate ip27-klconfig.c:find_lboard and
ip27-init.c:find_lbaord_real. DONE ip27-init.c:find_lbaord_real. DONE
5. Is it okay to set calias space on all nodes as 0, instead of 8k as 5. Is it okay to set calias space on all nodes as 0, instead of 8k as
in irix? in irix?
6. Investigate why things do not work without the setup_test() call 6. Investigate why things do not work without the setup_test() call
being invoked on all nodes in ip27-memory.c. being invoked on all nodes in ip27-memory.c.
7. Too many CLIs in the locore handlers : 7. Too many CLIs in the locore handlers :
For the low level handlers set up by set_except_vector(), For the low level handlers set up by set_except_vector(),
__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror, __tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
investigate whether the code should do CLI, STI or KMODE. investigate whether the code should do CLI, STI or KMODE.
8. Too many do_page_faults invoked - investigate. 8. Too many do_page_faults invoked - investigate.
9. start_thread must turn off UX64 ... and define tlb_refill_debug. 9. start_thread must turn off UX64 ... and define tlb_refill_debug.
10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* *
* Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
* Copyright (C) 1999, 2000 by Silicon Graphics * Copyright (C) 1999, 2000 by Silicon Graphics
* Copyright (C) 2002 Maciej W. Rozycki
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -14,86 +15,13 @@ ...@@ -14,86 +15,13 @@
#include <asm/sn/addrs.h> #include <asm/sn/addrs.h>
#include <asm/sn/arch.h> #include <asm/sn/arch.h>
#include <asm/sn/sn0/hub.h> #include <asm/sn/sn0/hub.h>
#include <asm/tlbdebug.h>
#include <asm/traps.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
extern void dump_tlb_addr(unsigned long addr); extern void dump_tlb_addr(unsigned long addr);
extern void dump_tlb_all(void); extern void dump_tlb_all(void);
extern asmlinkage void handle_ibe(void);
extern asmlinkage void handle_dbe(void);
extern const struct exception_table_entry __start___dbe_table[];
extern const struct exception_table_entry __stop___dbe_table[];
static inline unsigned long
search_one_table(const struct exception_table_entry *first,
const struct exception_table_entry *last,
unsigned long value)
{
while (first <= last) {
const struct exception_table_entry *mid;
long diff;
mid = (last - first) / 2 + first;
diff = mid->insn - value;
if (diff == 0)
return mid->nextinsn;
else if (diff < 0)
first = mid+1;
else
last = mid-1;
}
return 0;
}
extern spinlock_t modlist_lock;
static inline unsigned long
search_dbe_table(unsigned long addr)
{
unsigned long ret;
#ifndef CONFIG_MODULES
/* There is only the kernel to search. */
ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
return ret;
#else
unsigned long flags;
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
struct archdata *ap;
spin_lock_irqsave(&modlist_lock, flags);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (!mod_member_present(mp, archdata_end) ||
!mod_archdata_member_present(mp, struct archdata,
dbe_table_end))
continue;
ap = (struct archdata *)(mod->archdata_start);
if (ap->dbe_table_start == NULL ||
!(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
continue;
ret = search_one_table(ap->dbe_table_start,
ap->dbe_table_end - 1, addr);
if (ret)
break;
}
spin_unlock_irqrestore(&modlist_lock, flags);
return ret;
#endif
}
void do_ibe(struct pt_regs *regs)
{
printk("Got ibe at 0x%lx\n", regs->cp0_epc);
show_regs(regs);
dump_tlb_addr(regs->cp0_epc);
force_sig(SIGBUS, current);
while(1);
}
static void dump_hub_information(unsigned long errst0, unsigned long errst1) static void dump_hub_information(unsigned long errst0, unsigned long errst1)
{ {
static char *err_type[2][8] = { static char *err_type[2][8] = {
...@@ -109,7 +37,7 @@ static void dump_hub_information(unsigned long errst0, unsigned long errst1) ...@@ -109,7 +37,7 @@ static void dump_hub_information(unsigned long errst0, unsigned long errst1)
return; return;
} }
printk("Hub has valid error information:\n"); printk("Hub has valid error information:\n");
if (errst0 & PI_ERR_ST0_OVERRUN_MASK) if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
printk("Overrun is set. Error stack may contain additional " printk("Overrun is set. Error stack may contain additional "
...@@ -127,21 +55,17 @@ static void dump_hub_information(unsigned long errst0, unsigned long errst1) ...@@ -127,21 +55,17 @@ static void dump_hub_information(unsigned long errst0, unsigned long errst1)
? : "invalid"); ? : "invalid");
} }
void do_dbe(struct pt_regs *regs) int ip27_be_handler(struct pt_regs *regs, int is_fixup)
{ {
unsigned long fixup, errst0, errst1; unsigned long errst0, errst1;
int data = regs->cp0_cause & 4;
int cpu = LOCAL_HUB_L(PI_CPU_NUM); int cpu = LOCAL_HUB_L(PI_CPU_NUM);
fixup = search_dbe_table(regs->cp0_epc); if (is_fixup)
if (fixup) { return MIPS_BE_FIXUP;
long new_epc;
new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
regs->cp0_epc = new_epc;
return;
}
printk("Slice %c got dbe at 0x%lx\n", 'A' + cpu, regs->cp0_epc); printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
regs->cp0_epc);
printk("Hub information:\n"); printk("Hub information:\n");
printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND)); printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A); errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
...@@ -153,15 +77,13 @@ void do_dbe(struct pt_regs *regs) ...@@ -153,15 +77,13 @@ void do_dbe(struct pt_regs *regs)
force_sig(SIGBUS, current); force_sig(SIGBUS, current);
} }
void __init void __init ip27_be_init(void)
bus_error_init(void)
{ {
/* XXX Initialize all the Hub & Bridge error handling here. */ /* XXX Initialize all the Hub & Bridge error handling here. */
int cpu = LOCAL_HUB_L(PI_CPU_NUM); int cpu = LOCAL_HUB_L(PI_CPU_NUM);
int cpuoff = cpu << 8; int cpuoff = cpu << 8;
set_except_vector(6, handle_ibe); board_be_handler = ip27_be_handler;
set_except_vector(7, handle_dbe);
LOCAL_HUB_S(PI_ERR_INT_PEND, LOCAL_HUB_S(PI_ERR_INT_PEND,
cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A); cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
......
...@@ -3,25 +3,35 @@ ...@@ -3,25 +3,35 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 2001 Ralf Baechle * Copyright (C) 2001, 2002 Ralf Baechle
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/serial.h>
#include <asm/page.h>
#include <asm/sn/addrs.h> #include <asm/sn/addrs.h>
#include <asm/sn/sn0/hub.h> #include <asm/sn/sn0/hub.h>
#include <asm/sn/klconfig.h> #include <asm/sn/klconfig.h>
#include <asm/sn/ioc3.h> #include <asm/sn/ioc3.h>
#include <asm/sn/sn_private.h> #include <asm/sn/sn_private.h>
void prom_putchar(char c) #define IOC3_BAUD (22000000 / (3*16))
#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
static inline struct ioc3_uartregs *console_uart(void)
{ {
struct ioc3 *ioc3; struct ioc3 *ioc3;
struct ioc3_uartregs *uart;
ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base; ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
uart = &ioc3->sregs.uarta;
return &ioc3->sregs.uarta;
}
void prom_putchar(char c)
{
struct ioc3_uartregs *uart = console_uart();
while ((uart->iu_lsr & 0x20) == 0); while ((uart->iu_lsr & 0x20) == 0);
uart->iu_thr = c; uart->iu_thr = c;
...@@ -32,27 +42,24 @@ char __init prom_getchar(void) ...@@ -32,27 +42,24 @@ char __init prom_getchar(void)
return 0; return 0;
} }
static void static void inline ioc3_console_probe(void)
ip27prom_console_write(struct console *con, const char *s, unsigned n)
{ {
prom_printf("%s", s); struct serial_struct req;
}
static kdev_t /* Register to interrupt zero because we share the interrupt with
ip27prom_console_dev(struct console *c) the serial driver which we don't properly support yet. */
{ memset(&req, 0, sizeof(req));
return MKDEV(TTY_MAJOR, 64 + c->index); req.irq = 0;
} req.flags = IOC3_COM_FLAGS;
req.io_type = SERIAL_IO_MEM;
req.iomem_reg_shift = 0;
req.baud_base = IOC3_BAUD;
static struct console ip27_prom_console = { req.iomem_base = (unsigned char *) console_uart();
.name = "prom", register_serial(&req);
.write = ip27prom_console_write, }
.device = ip27prom_console_dev,
.flags = CON_PRINTBUFFER,
.index = -1,
};
__init void ip27_setup_console(void) __init void ip27_setup_console(void)
{ {
register_console(&ip27_prom_console); ioc3_console_probe();
} }
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/param.h> #include <linux/param.h>
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <asm/sn/klconfig.h> #include <asm/sn/klconfig.h>
#include <asm/sn/arch.h> #include <asm/sn/arch.h>
...@@ -92,7 +92,7 @@ klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice) ...@@ -92,7 +92,7 @@ klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
do { do {
if ((acpu->cpu_info.physid) == slice) if ((acpu->cpu_info.physid) == slice)
return acpu; return acpu;
} while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, } while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
KLSTRUCT_CPU))); KLSTRUCT_CPU)));
return (klcpu_t *)NULL; return (klcpu_t *)NULL;
} }
......
...@@ -65,7 +65,7 @@ static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid) ...@@ -65,7 +65,7 @@ static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
cnodeid_t client_cnode; cnodeid_t client_cnode;
client_cnode = NASID_TO_COMPACT_NODEID(client_nasid); client_cnode = NASID_TO_COMPACT_NODEID(client_nasid);
kvp = &(PLAT_NODE_DATA(client_cnode)->kern_vars); kvp = &(PLAT_NODE_DATA(client_cnode)->kern_vars);
KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp; KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp;
...@@ -121,7 +121,7 @@ void __init replicate_kernel_text(int maxnodes) ...@@ -121,7 +121,7 @@ void __init replicate_kernel_text(int maxnodes)
/* /*
* Return pfn of first free page of memory on a node. PROM may allocate * Return pfn of first free page of memory on a node. PROM may allocate
* data structures on the first couple of pages of the first slot of each * data structures on the first couple of pages of the first slot of each
* node. If this is the case, getfirstfree(node) > getslotstart(node, 0). * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
*/ */
pfn_t node_getfirstfree(cnodeid_t cnode) pfn_t node_getfirstfree(cnodeid_t cnode)
...@@ -137,7 +137,7 @@ pfn_t node_getfirstfree(cnodeid_t cnode) ...@@ -137,7 +137,7 @@ pfn_t node_getfirstfree(cnodeid_t cnode)
if ((cnode == 0) || (CPUMASK_TSTB(ktext_repmask, cnode))) if ((cnode == 0) || (CPUMASK_TSTB(ktext_repmask, cnode)))
return (TO_NODE(nasid, offset) >> PAGE_SHIFT); return (TO_NODE(nasid, offset) >> PAGE_SHIFT);
else else
return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >>
PAGE_SHIFT); PAGE_SHIFT);
} }
...@@ -142,7 +142,7 @@ pfn_t szmem(pfn_t fpage, pfn_t maxpmem) ...@@ -142,7 +142,7 @@ pfn_t szmem(pfn_t fpage, pfn_t maxpmem)
for (slot = 0; slot < numslots; slot++) { for (slot = 0; slot < numslots; slot++) {
slot_psize = slot_psize_compute(node, slot); slot_psize = slot_psize_compute(node, slot);
if (slot == 0) slot0sz = slot_psize; if (slot == 0) slot0sz = slot_psize;
/* /*
* We need to refine the hack when we have replicated * We need to refine the hack when we have replicated
* kernel text. * kernel text.
*/ */
...@@ -158,7 +158,7 @@ pfn_t szmem(pfn_t fpage, pfn_t maxpmem) ...@@ -158,7 +158,7 @@ pfn_t szmem(pfn_t fpage, pfn_t maxpmem)
continue; continue;
} }
num_pages += slot_psize; num_pages += slot_psize;
slot_psize_cache[node][slot] = slot_psize_cache[node][slot] =
(unsigned short) slot_psize; (unsigned short) slot_psize;
if (slot_psize) if (slot_psize)
slot_lastfilled_cache[node] = slot; slot_lastfilled_cache[node] = slot;
...@@ -201,9 +201,9 @@ void __init prom_meminit(void) ...@@ -201,9 +201,9 @@ void __init prom_meminit(void)
<< PAGE_SHIFT)); << PAGE_SHIFT));
NODE_DATA(node)->bdata = plat_node_bdata + node; NODE_DATA(node)->bdata = plat_node_bdata + node;
slot_freepfn += node_datasz; slot_freepfn += node_datasz;
bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn,
slot_firstpfn, slot_lastpfn); slot_firstpfn, slot_lastpfn);
free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
(slot_lastpfn - slot_firstpfn) << PAGE_SHIFT); (slot_lastpfn - slot_firstpfn) << PAGE_SHIFT);
reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size); ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size);
...@@ -224,7 +224,7 @@ prom_free_prom_memory (void) ...@@ -224,7 +224,7 @@ prom_free_prom_memory (void)
#ifdef CONFIG_DISCONTIGMEM #ifdef CONFIG_DISCONTIGMEM
static pfn_t pagenr = 0; static pfn_t pagenr;
void __init paging_init(void) void __init paging_init(void)
{ {
...@@ -241,10 +241,10 @@ void __init paging_init(void) ...@@ -241,10 +241,10 @@ void __init paging_init(void)
memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE); memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
/* This is for vmalloc */ /* This is for vmalloc */
memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER); memset((void *)kptbl, 0, PAGE_SIZE << PGD_ORDER);
memset((void *)kpmdtbl, 0, PAGE_SIZE); memset((void *)kpmdtbl, 0, PAGE_SIZE);
pgd_set(swapper_pg_dir, kpmdtbl); set_pgd(swapper_pg_dir, __pgd(kpmdtbl));
for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE) for (i = 0; i < (1 << PGD_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
pmd_val(*pmd) = (unsigned long)pte; pmd_val(*pmd) = (unsigned long)pte;
for (node = 0; node < numnodes; node++) { for (node = 0; node < numnodes; node++) {
...@@ -252,7 +252,7 @@ void __init paging_init(void) ...@@ -252,7 +252,7 @@ void __init paging_init(void)
pfn_t end_pfn = node_getmaxclick(node); pfn_t end_pfn = node_getmaxclick(node);
zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn; zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn;
free_area_init_node(node, NODE_DATA(node), 0, zones_size, free_area_init_node(node, NODE_DATA(node), 0, zones_size,
start_pfn, 0); start_pfn, 0);
} }
} }
...@@ -290,7 +290,7 @@ void __init mem_init(void) ...@@ -290,7 +290,7 @@ void __init mem_init(void)
pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0); pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0);
numslots = node_getlastslot(nid); numslots = node_getlastslot(nid);
for (slot = 1; slot <= numslots; slot++) { for (slot = 1; slot <= numslots; slot++) {
pslot = NODE_DATA(nid)->node_mem_map + pslot = NODE_DATA(nid)->node_mem_map +
slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0); slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0);
/* /*
......
...@@ -62,7 +62,7 @@ nmi_cpu_eframe_save(nasid_t nasid, ...@@ -62,7 +62,7 @@ nmi_cpu_eframe_save(nasid_t nasid,
numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t); numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t);
/* Get the pointer to the current cpu's register set. */ /* Get the pointer to the current cpu's register set. */
prom_format = prom_format =
(machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
slice * IP27_NMI_KREGS_CPU_SIZE); slice * IP27_NMI_KREGS_CPU_SIZE);
...@@ -70,7 +70,7 @@ nmi_cpu_eframe_save(nasid_t nasid, ...@@ -70,7 +70,7 @@ nmi_cpu_eframe_save(nasid_t nasid,
for (i = 0; i < numberof_nmi_cpu_regs; i++) for (i = 0; i < numberof_nmi_cpu_regs; i++)
printk("0x%lx ", prom_format[i]); printk("0x%lx ", prom_format[i]);
printk("\n\n"); printk("\n\n");
} }
/* /*
* Copy the cpu registers which have been saved in the IP27prom format * Copy the cpu registers which have been saved in the IP27prom format
...@@ -91,7 +91,7 @@ nmi_node_eframe_save(cnodeid_t cnode) ...@@ -91,7 +91,7 @@ nmi_node_eframe_save(cnodeid_t cnode)
return; return;
/* Save the registers into eframe for each cpu */ /* Save the registers into eframe for each cpu */
for(cpu = 0; cpu < NODE_NUM_CPUS(cnode); cpu++) for(cpu = 0; cpu < NODE_NUM_CPUS(cnode); cpu++)
nmi_cpu_eframe_save(nasid, cpu); nmi_cpu_eframe_save(nasid, cpu);
} }
...@@ -103,7 +103,7 @@ nmi_eframes_save(void) ...@@ -103,7 +103,7 @@ nmi_eframes_save(void)
{ {
cnodeid_t cnode; cnodeid_t cnode;
for(cnode = 0 ; cnode < numnodes; cnode++) for(cnode = 0 ; cnode < numnodes; cnode++)
nmi_node_eframe_save(cnode); nmi_node_eframe_save(cnode);
} }
...@@ -115,7 +115,7 @@ cont_nmi_dump(void) ...@@ -115,7 +115,7 @@ cont_nmi_dump(void)
atomic_inc(&nmied_cpus); atomic_inc(&nmied_cpus);
#endif #endif
/* /*
* Use enter_panic_mode to allow only 1 cpu to proceed * Use enter_panic_mode to allow only 1 cpu to proceed
*/ */
enter_panic_mode(); enter_panic_mode();
...@@ -129,7 +129,7 @@ cont_nmi_dump(void) ...@@ -129,7 +129,7 @@ cont_nmi_dump(void)
* - on 512p SN0 system, the MMSC will only send NMIs to * - on 512p SN0 system, the MMSC will only send NMIs to
* half the cpus. Unfortunately, we don't know which cpus may be * half the cpus. Unfortunately, we don't know which cpus may be
* NMIed - it depends on how the site chooses to configure. * NMIed - it depends on how the site chooses to configure.
* *
* Note: it has been measure that it takes the MMSC up to 2.3 secs to * Note: it has been measure that it takes the MMSC up to 2.3 secs to
* send NMIs to all cpus on a 256p system. * send NMIs to all cpus on a 256p system.
*/ */
...@@ -145,19 +145,19 @@ cont_nmi_dump(void) ...@@ -145,19 +145,19 @@ cont_nmi_dump(void)
cpu = CNODE_TO_CPU_BASE(node); cpu = CNODE_TO_CPU_BASE(node);
for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) { for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
CPUMASK_SETB(nmied_cpus, cpu); CPUMASK_SETB(nmied_cpus, cpu);
/* /*
* cputonasid, cputoslice * cputonasid, cputoslice
* needs kernel cpuid * needs kernel cpuid
*/ */
SEND_NMI((cputonasid(cpu)), (cputoslice(cpu))); SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
} }
} }
} }
udelay(10000); udelay(10000);
} }
#else #else
while (atomic_read(&nmied_cpus) != smp_num_cpus); while (atomic_read(&nmied_cpus) != num_online_cpus());
#endif #endif
/* /*
......
...@@ -14,8 +14,10 @@ ...@@ -14,8 +14,10 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/mmzone.h> #include <linux/mmzone.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/reboot.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
#include <asm/sn/addrs.h> #include <asm/sn/addrs.h>
...@@ -30,7 +32,7 @@ void machine_power_off(void) __attribute__((noreturn)); ...@@ -30,7 +32,7 @@ void machine_power_off(void) __attribute__((noreturn));
#define noreturn while(1); /* Silence gcc. */ #define noreturn while(1); /* Silence gcc. */
/* XXX How to pass the reboot command to the firmware??? */ /* XXX How to pass the reboot command to the firmware??? */
void machine_restart(char *command) static void ip27_machine_restart(char *command)
{ {
#if 0 #if 0
int i; int i;
...@@ -42,7 +44,7 @@ void machine_restart(char *command) ...@@ -42,7 +44,7 @@ void machine_restart(char *command)
#endif #endif
#if 0 #if 0
for (i = 0; i < numnodes; i++) for (i = 0; i < numnodes; i++)
REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
PROMOP_REBOOT); PROMOP_REBOOT);
#else #else
LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
...@@ -50,7 +52,7 @@ void machine_restart(char *command) ...@@ -50,7 +52,7 @@ void machine_restart(char *command)
noreturn; noreturn;
} }
void machine_halt(void) static void ip27_machine_halt(void)
{ {
int i; int i;
...@@ -58,13 +60,13 @@ void machine_halt(void) ...@@ -58,13 +60,13 @@ void machine_halt(void)
smp_send_stop(); smp_send_stop();
#endif #endif
for (i = 0; i < numnodes; i++) for (i = 0; i < numnodes; i++)
REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
PROMOP_RESTART); PROMOP_RESTART);
LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
noreturn; noreturn;
} }
void machine_power_off(void) static void ip27_machine_power_off(void)
{ {
/* To do ... */ /* To do ... */
noreturn; noreturn;
...@@ -72,5 +74,7 @@ void machine_power_off(void) ...@@ -72,5 +74,7 @@ void machine_power_off(void)
void ip27_reboot_setup(void) void ip27_reboot_setup(void)
{ {
/* Nothing to do on IP27. */ _machine_restart = ip27_machine_restart;
_machine_halt = ip27_machine_halt;
_machine_power_off = ip27_machine_power_off;
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/sn/types.h> #include <asm/sn/types.h>
#include <asm/sn/sn0/addrs.h> #include <asm/sn/sn0/addrs.h>
...@@ -21,12 +22,14 @@ ...@@ -21,12 +22,14 @@
#include <asm/sn/sn0/hubio.h> #include <asm/sn/sn0/hubio.h>
#include <asm/sn/klconfig.h> #include <asm/sn/klconfig.h>
#include <asm/sn/ioc3.h> #include <asm/sn/ioc3.h>
#include <asm/time.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/sn/arch.h> #include <asm/sn/arch.h>
#include <asm/sn/sn_private.h> #include <asm/sn/sn_private.h>
#include <asm/pci/bridge.h> #include <asm/pci/bridge.h>
#include <asm/paccess.h> #include <asm/paccess.h>
#include <asm/sn/sn0/ip27.h> #include <asm/sn/sn0/ip27.h>
#include <asm/traps.h>
/* Check against user dumbness. */ /* Check against user dumbness. */
#ifdef CONFIG_VT #ifdef CONFIG_VT
...@@ -40,7 +43,7 @@ ...@@ -40,7 +43,7 @@
#define DBG(x...) #define DBG(x...)
#endif #endif
unsigned long mips_io_port_base = IO_BASE; extern void ip27_be_init(void) __init;
/* /*
* get_nasid() returns the physical node id number of the caller. * get_nasid() returns the physical node id number of the caller.
...@@ -112,7 +115,7 @@ void __init pcibr_setup(cnodeid_t nid) ...@@ -112,7 +115,7 @@ void __init pcibr_setup(cnodeid_t nid)
{ {
int i, start, num; int i, start, num;
unsigned long masterwid; unsigned long masterwid;
bridge_t *bridge; bridge_t *bridge;
volatile u64 hubreg; volatile u64 hubreg;
nasid_t nasid, masternasid; nasid_t nasid, masternasid;
xwidget_part_num_t partnum; xwidget_part_num_t partnum;
...@@ -122,8 +125,8 @@ void __init pcibr_setup(cnodeid_t nid) ...@@ -122,8 +125,8 @@ void __init pcibr_setup(cnodeid_t nid)
/* /*
* If the master is doing this for headless node, nothing to do. * If the master is doing this for headless node, nothing to do.
* This is because currently we require at least one of the hubs * This is because currently we require at least one of the hubs
* (master hub) connected to the xbow to have at least one enabled * (master hub) connected to the xbow to have at least one enabled
* cpu to receive intrs. Else we need an array bus_to_intrnasid[] * cpu to receive intrs. Else we need an array bus_to_intrnasid[]
* that bridge_startup() needs to use to target intrs. All dma is * that bridge_startup() needs to use to target intrs. All dma is
* routed thru the widget of the master hub. The master hub wid * routed thru the widget of the master hub. The master hub wid
* is selectable by WIDGET_A below. * is selectable by WIDGET_A below.
...@@ -174,8 +177,8 @@ void __init pcibr_setup(cnodeid_t nid) ...@@ -174,8 +177,8 @@ void __init pcibr_setup(cnodeid_t nid)
else { else {
/* /*
* Okay, here's a xbow. Lets arbitrate and find * Okay, here's a xbow. Lets arbitrate and find
* out if we should initialize it. Set enabled * out if we should initialize it. Set enabled
* hub connected at highest or lowest widget as * hub connected at highest or lowest widget as
* master. * master.
*/ */
#ifdef WIDGET_A #ifdef WIDGET_A
...@@ -213,7 +216,7 @@ void __init pcibr_setup(cnodeid_t nid) ...@@ -213,7 +216,7 @@ void __init pcibr_setup(cnodeid_t nid)
} }
} else if (partnum == XXBOW_WIDGET_PART_NUM) { } else if (partnum == XXBOW_WIDGET_PART_NUM) {
/* /*
* found xbridge, assume ibrick for now * found xbridge, assume ibrick for now
*/ */
printk("...is xbridge\n"); printk("...is xbridge\n");
bus_to_wid[0] = 0xb; bus_to_wid[0] = 0xb;
...@@ -261,7 +264,7 @@ void __init pcibr_setup(cnodeid_t nid) ...@@ -261,7 +264,7 @@ void __init pcibr_setup(cnodeid_t nid)
bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP; bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;
/* /*
* Hmm... IRIX sets additional bits in the address which * Hmm... IRIX sets additional bits in the address which
* are documented as reserved in the bridge docs. * are documented as reserved in the bridge docs.
*/ */
bridge->b_int_mode = 0x0; /* Don't clear ints */ bridge->b_int_mode = 0x0; /* Don't clear ints */
...@@ -275,6 +278,8 @@ void __init pcibr_setup(cnodeid_t nid) ...@@ -275,6 +278,8 @@ void __init pcibr_setup(cnodeid_t nid)
} }
extern void ip27_setup_console(void); extern void ip27_setup_console(void);
extern void ip27_time_init(void);
extern void ip27_reboot_setup(void);
void __init ip27_setup(void) void __init ip27_setup(void)
{ {
...@@ -282,6 +287,7 @@ void __init ip27_setup(void) ...@@ -282,6 +287,7 @@ void __init ip27_setup(void)
hubreg_t p, e; hubreg_t p, e;
ip27_setup_console(); ip27_setup_console();
ip27_reboot_setup();
num_bridges = 0; num_bridges = 0;
/* /*
...@@ -307,4 +313,7 @@ void __init ip27_setup(void) ...@@ -307,4 +313,7 @@ void __init ip27_setup(void)
ioc3_sio_init(); ioc3_sio_init();
ioc3_eth_init(); ioc3_eth_init();
per_cpu_init(); per_cpu_init();
mips_io_port_base = IO_BASE;
board_time_init = ip27_time_init;
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
* Copytight (C) 1999, 2000 Silicon Graphics, Inc. * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
*/ */
#include <linux/bcd.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -11,9 +12,10 @@ ...@@ -11,9 +12,10 @@
#include <linux/param.h> #include <linux/param.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <asm/time.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
#include <asm/sn/ioc3.h> #include <asm/sn/ioc3.h>
...@@ -27,17 +29,18 @@ ...@@ -27,17 +29,18 @@
/* /*
* This is a hack; we really need to figure these values out dynamically * This is a hack; we really need to figure these values out dynamically
* *
* Since 800 ns works very well with various HUB frequencies, such as * Since 800 ns works very well with various HUB frequencies, such as
* 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time. * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
* *
* Ralf: which clock rate is used to feed the counter? * Ralf: which clock rate is used to feed the counter?
*/ */
#define NSEC_PER_CYCLE 800 #define NSEC_PER_CYCLE 800
#define NSEC_PER_SEC 1000000000
#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE) #define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE)
#define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ) #define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ)
#define TICK_SIZE (tick_nsec / 1000)
static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */ static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */
static long last_rtc_update; /* Last time the rtc clock got updated */ static long last_rtc_update; /* Last time the rtc clock got updated */
...@@ -52,12 +55,11 @@ static int set_rtc_mmss(unsigned long nowtime) ...@@ -52,12 +55,11 @@ static int set_rtc_mmss(unsigned long nowtime)
nasid_t nid; nasid_t nid;
nid = get_nasid(); nid = get_nasid();
rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
IOC3_BYTEBUS_DEV0); IOC3_BYTEBUS_DEV0);
rtc->control |= M48T35_RTC_READ; rtc->control |= M48T35_RTC_READ;
cmos_minutes = rtc->min; cmos_minutes = BCD2BIN(rtc->min);
BCD_TO_BIN(cmos_minutes);
rtc->control &= ~M48T35_RTC_READ; rtc->control &= ~M48T35_RTC_READ;
/* /*
...@@ -72,8 +74,8 @@ static int set_rtc_mmss(unsigned long nowtime) ...@@ -72,8 +74,8 @@ static int set_rtc_mmss(unsigned long nowtime)
real_minutes %= 60; real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) { if (abs(real_minutes - cmos_minutes) < 30) {
BIN_TO_BCD(real_seconds); real_seconds = BIN2BCD(real_seconds);
BIN_TO_BCD(real_minutes); real_minutes = BIN2BCD(real_minutes);
rtc->control |= M48T35_RTC_SET; rtc->control |= M48T35_RTC_SET;
rtc->sec = real_seconds; rtc->sec = real_seconds;
rtc->min = real_minutes; rtc->min = real_minutes;
...@@ -92,8 +94,9 @@ void rt_timer_interrupt(struct pt_regs *regs) ...@@ -92,8 +94,9 @@ void rt_timer_interrupt(struct pt_regs *regs)
{ {
int cpu = smp_processor_id(); int cpu = smp_processor_id();
int cpuA = ((cputoslice(cpu)) == 0); int cpuA = ((cputoslice(cpu)) == 0);
int irq = 7; /* XXX Assign number */ int irq = 9; /* XXX Assign number */
irq_enter();
write_seqlock(&xtime_lock); write_seqlock(&xtime_lock);
again: again:
...@@ -110,101 +113,40 @@ void rt_timer_interrupt(struct pt_regs *regs) ...@@ -110,101 +113,40 @@ void rt_timer_interrupt(struct pt_regs *regs)
do_timer(regs); do_timer(regs);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
{ update_process_times(user_mode(regs));
int user = user_mode(regs);
/*
* update_process_times() expects us to have done irq_enter().
* Besides, if we don't timer interrupts ignore the global
* interrupt lock, which is the WrongThing (tm) to do.
* Picked from i386 code.
*/
irq_enter(cpu, 0);
update_process_times(user);
irq_exit(cpu, 0);
}
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
/* /*
* If we have an externally synchronized Linux clock, then update * If we have an externally synchronized Linux clock, then update
* RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to when a second starts. * called as close as possible to when a second starts.
*/ */
if ((time_status & STA_UNSYNC) == 0 && if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660) { xtime.tv_sec > last_rtc_update + 660 &&
if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) { (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
if (set_rtc_mmss(xtime.tv_sec + 1) == 0) (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
last_rtc_update = xtime.tv_sec; if (rtc_set_time(xtime.tv_sec) == 0) {
else last_rtc_update = xtime.tv_sec;
last_rtc_update = xtime.tv_sec - 600; } else {
} else if (xtime.tv_usec <= ((unsigned) tick) / 2) { last_rtc_update = xtime.tv_sec - 600;
if (set_rtc_mmss(xtime.tv_sec) == 0) /* do it again in 60 s */
last_rtc_update = xtime.tv_sec;
else
last_rtc_update = xtime.tv_sec - 600;
} }
} }
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
irq_exit();
if (softirq_pending(cpu)) if (softirq_pending(cpu))
do_softirq(); do_softirq();
} }
unsigned long inline do_gettimeoffset(void) unsigned long ip27_do_gettimeoffset(void)
{ {
unsigned long ct_cur1; unsigned long ct_cur1;
ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY; ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000; return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
} }
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
unsigned long usec, sec;
unsigned long seq;
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
{
unsigned long lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
}
sec = xtime.tv_sec;
usec += xtime.tv_usec;
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
while (usec >= 1000000) {
usec -= 1000000;
sec++;
}
tv->tv_sec = sec;
tv->tv_usec = usec;
}
void do_settimeofday(struct timeval *tv)
{
write_seqlock_irq(&xtime_lock);
tv->tv_usec -= do_gettimeoffset();
tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
tv->tv_sec--;
}
xtime = *tv;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
write_sequnlock_irq(&xtime_lock);
}
/* Includes for ioc3_init(). */ /* Includes for ioc3_init(). */
#include <asm/sn/types.h> #include <asm/sn/types.h>
#include <asm/sn/sn0/addrs.h> #include <asm/sn/sn0/addrs.h>
...@@ -219,7 +161,7 @@ static __init unsigned long get_m48t35_time(void) ...@@ -219,7 +161,7 @@ static __init unsigned long get_m48t35_time(void)
nasid_t nid; nasid_t nid;
nid = get_nasid(); nid = get_nasid();
rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
IOC3_BYTEBUS_DEV0); IOC3_BYTEBUS_DEV0);
rtc->control |= M48T35_RTC_READ; rtc->control |= M48T35_RTC_READ;
...@@ -231,22 +173,24 @@ static __init unsigned long get_m48t35_time(void) ...@@ -231,22 +173,24 @@ static __init unsigned long get_m48t35_time(void)
year = rtc->year; year = rtc->year;
rtc->control &= ~M48T35_RTC_READ; rtc->control &= ~M48T35_RTC_READ;
BCD_TO_BIN(sec); sec = BCD2BIN(sec);
BCD_TO_BIN(min); min = BCD2BIN(min);
BCD_TO_BIN(hour); hour = BCD2BIN(hour);
BCD_TO_BIN(date); date = BCD2BIN(date);
BCD_TO_BIN(month); month = BCD2BIN(month);
BCD_TO_BIN(year); year = BCD2BIN(year);
year += 1970; year += 1970;
return mktime(year, month, date, hour, min, sec); return mktime(year, month, date, hour, min, sec);
} }
void __init time_init(void) void __init ip27_time_init(void)
{ {
xtime.tv_sec = get_m48t35_time(); xtime.tv_sec = get_m48t35_time();
xtime.tv_usec = 0; xtime.tv_nsec = 0;
do_gettimeoffset = ip27_do_gettimeoffset;
} }
void __init cpu_time_init(void) void __init cpu_time_init(void)
...@@ -267,7 +211,7 @@ void __init cpu_time_init(void) ...@@ -267,7 +211,7 @@ void __init cpu_time_init(void)
printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK); set_c0_status(SRB_TIMOCLK);
} }
void __init hub_rtc_init(cnodeid_t cnode) void __init hub_rtc_init(cnodeid_t cnode)
......
This diff is collapsed.
This diff is collapsed.
/*
* Dynamic DMA mapping support.
*
* On the Origin there is dynamic DMA address translation for all PCI DMA.
* However we don't use this facility yet but rely on the 2gb direct
* mapped DMA window for PCI64. So consistent alloc/free are merely page
* allocation/freeing. The rest of the dynamic DMA mapping interface is
* implemented in <asm/pci.h>. So this code will fail with more than
* 2gb of memory.
*/
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <asm/io.h>
/* Pure 2^n version of get_order */
extern __inline__ int __get_order(unsigned long size)
{
int order;
size = (size-1) >> (PAGE_SHIFT-1);
order = -1;
do {
size >>= 1;
order++;
} while (size);
return order;
}
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC;
int order = __get_order(size);
if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
gfp |= GFP_DMA;
ret = (void *)__get_free_pages(gfp, order);
if (ret != NULL) {
memset(ret, 0, size);
*dma_handle = (bus_to_baddr[hwdev->bus->number] | __pa(ret));
}
return ret;
}
void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
free_pages((unsigned long)vaddr, __get_order(size));
}
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
*
* Once the device is given the dma address, the device owns this memory
* until either pci_unmap_single or pci_dma_sync_single is performed.
*/
dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
int direction)
{
if (direction == PCI_DMA_NONE)
BUG();
return (bus_to_baddr[hwdev->bus->number] | __pa(ptr));
}
/*
* Unmap a single streaming mode DMA translation. The dma_addr and size
* must match what was provided for in a previous pci_map_single call. All
* other usages are undefined.
*
* After this call, reads by the cpu to the buffer are guaranteed to see
* whatever the device wrote there.
*/
void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
BUG();
/* Nothing to do */
}
/*
* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
* above pci_map_single interface. Here the scatter gather list
* elements are each tagged with the appropriate dma address
* and length. They are obtained via sg_dma_{address,length}(SG).
*
* NOTE: An implementation may be able to use a smaller number of
* DMA address/length pairs than there are SG table elements.
* (for example via virtual mapping capabilities)
* The routine returns the number of addr/length pairs actually
* used, at most nents.
*
* Device ownership issues as mentioned above for pci_map_single are
* the same here.
*/
int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
int direction)
{
int i;
if (direction == PCI_DMA_NONE)
BUG();
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nents; i++, sg++) {
sg->address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(sg->address));
}
return nents;
}
/*
* Unmap a set of streaming mode DMA translations.
* Again, cpu read rules concerning calls here are the same as for
* pci_unmap_single() above.
*/
void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
int direction)
{
if (direction == PCI_DMA_NONE)
BUG();
/* Nothing to do */
}
/*
* Make physical memory consistent for a single
* streaming mode DMA translation after a transfer.
*
* If you perform a pci_map_single() but wish to interrogate the
* buffer using the cpu, yet do not wish to teardown the PCI dma
* mapping, you must call this function before doing so. At the
* next point you give the PCI dma address back to the card, the
* device again owns the buffer.
*/
void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle,
size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
BUG();
}
/*
* Make physical memory consistent for a set of streaming
* mode DMA translations after a transfer.
*
* The same as pci_dma_sync_single but for a scatter-gather list,
* same rules and usage.
*/
void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nelems, int direction)
{
if (direction == PCI_DMA_NONE)
BUG();
}
This diff is collapsed.
/*
* Driver for the SGS-Thomson M48T35 Timekeeper RAM chip
*
* Real Time Clock interface for Linux
*
* TODO: Implement periodic interrupts.
*
* Copyright (C) 2000 Silicon Graphics, Inc.
* Written by Ulf Carlsson (ulfc@engr.sgi.com)
*
* Based on code written by Paul Gortmaker.
*
* This driver allows use of the real time clock (built into
* nearly all computers) from user space. It exports the /dev/rtc
* interface supporting various ioctl() and also the /proc/rtc
* pseudo-file for status information.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
*/
#define RTC_VERSION "1.09b"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/rtc.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <linux/bcd.h>
#include <asm/m48t35.h>
#include <asm/sn/ioc3.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/sn/klconfig.h>
#include <asm/sn/sn0/ip27.h>
#include <asm/sn/sn0/hub.h>
static int rtc_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
static int rtc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data);
static void get_rtc_time(struct rtc_time *rtc_tm);
static atomic_t rtc_ready = ATOMIC_INIT(1);
static unsigned long rtc_freq; /* Current periodic IRQ rate */
static struct m48t35_rtc *rtc;
/*
* If this driver ever becomes modularised, it will be really nice
* to make the epoch retain its value across module reload...
*/
static unsigned long epoch = 1970; /* year corresponding to 0x00 */
static const unsigned char days_in_mo[] =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct rtc_time wtime;
switch (cmd) {
case RTC_RD_TIME: /* Read the time/date from RTC */
{
get_rtc_time(&wtime);
break;
}
case RTC_SET_TIME: /* Set the RTC */
{
struct rtc_time rtc_tm;
unsigned char mon, day, hrs, min, sec, leap_yr;
unsigned int yrs;
unsigned long flags;
if (!capable(CAP_SYS_TIME))
return -EACCES;
if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
sizeof(struct rtc_time)))
return -EFAULT;
yrs = rtc_tm.tm_year + 1900;
mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
day = rtc_tm.tm_mday;
hrs = rtc_tm.tm_hour;
min = rtc_tm.tm_min;
sec = rtc_tm.tm_sec;
if (yrs < 1970)
return -EINVAL;
leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
if ((mon > 12) || (day == 0))
return -EINVAL;
if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
return -EINVAL;
if ((hrs >= 24) || (min >= 60) || (sec >= 60))
return -EINVAL;
if ((yrs -= epoch) > 255) /* They are unsigned */
return -EINVAL;
save_flags(flags);
cli();
if (yrs > 169) {
restore_flags(flags);
return -EINVAL;
}
if (yrs >= 100)
yrs -= 100;
BIN_TO_BCD(sec);
BIN_TO_BCD(min);
BIN_TO_BCD(hrs);
BIN_TO_BCD(day);
BIN_TO_BCD(mon);
BIN_TO_BCD(yrs);
rtc->control &= ~M48T35_RTC_SET;
rtc->year = yrs;
rtc->month = mon;
rtc->date = day;
rtc->hour = hrs;
rtc->min = min;
rtc->sec = sec;
rtc->control &= ~M48T35_RTC_SET;
restore_flags(flags);
return 0;
}
default:
return -EINVAL;
}
return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
}
/*
* We enforce only one user at a time here with the open/close.
* Also clear the previous interrupt data on an open, and clean
* up things on a close.
*/
static int rtc_open(struct inode *inode, struct file *file)
{
if( atomic_dec_and_test( &rtc_ready ) )
{
atomic_inc( &rtc_ready );
return -EBUSY;
}
return 0;
}
static int rtc_release(struct inode *inode, struct file *file)
{
atomic_inc( &rtc_ready );
return 0;
}
/*
* The various file operations we support.
*/
static struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.ioctl = rtc_ioctl,
.open = rtc_open,
.release = rtc_release,
};
static struct miscdevice rtc_dev=
{
RTC_MINOR,
"rtc",
&rtc_fops
};
static int __init rtc_init(void)
{
unsigned long flags;
nasid_t nid;
nid = get_nasid();
rtc = (struct m48t35_rtc *)
KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
if (misc_register(&rtc_dev)) {
printk(KERN_ERR "rtc: cannot register misc device.\n");
return -ENODEV;
}
if (!create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL)) {
printk(KERN_ERR "rtc: cannot create /proc/rtc.\n");
misc_deregister(&rtc_dev);
return -ENOENT;
}
save_flags(flags);
cli();
restore_flags(flags);
rtc_freq = 1024;
return 0;
}
static void __exit rtc_exit (void)
{
/* interrupts and timer disabled at this point by rtc_release */
remove_proc_entry ("rtc", NULL);
misc_deregister(&rtc_dev);
}
module_init(rtc_init);
module_exit(rtc_exit);
/*
* Info exported via "/proc/rtc".
*/
static int rtc_get_status(char *buf)
{
char *p;
struct rtc_time tm;
/*
* Just emulate the standard /proc/rtc
*/
p = buf;
get_rtc_time(&tm);
/*
* There is no way to tell if the luser has the RTC set for local
* time or for Universal Standard Time (GMT). Probably local though.
*/
p += sprintf(p,
"rtc_time\t: %02d:%02d:%02d\n"
"rtc_date\t: %04d-%02d-%02d\n"
"rtc_epoch\t: %04lu\n"
"24hr\t\t: yes\n",
tm.tm_hour, tm.tm_min, tm.tm_sec,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
return p - buf;
}
static int rtc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = rtc_get_status(page);
if (len <= off+count) *eof = 1;
*start = page + off;
len -= off;
if (len>count) len = count;
if (len<0) len = 0;
return len;
}
static void get_rtc_time(struct rtc_time *rtc_tm)
{
unsigned long flags;
/*
* Do we need to wait for the last update to finish?
*/
/*
* Only the values that we read from the RTC are set. We leave
* tm_wday, tm_yday and tm_isdst untouched. Even though the
* RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
* by the RTC when initially set to a non-zero value.
*/
save_flags(flags);
cli();
rtc->control |= M48T35_RTC_READ;
rtc_tm->tm_sec = rtc->sec;
rtc_tm->tm_min = rtc->min;
rtc_tm->tm_hour = rtc->hour;
rtc_tm->tm_mday = rtc->date;
rtc_tm->tm_mon = rtc->month;
rtc_tm->tm_year = rtc->year;
rtc->control &= ~M48T35_RTC_READ;
restore_flags(flags);
BCD_TO_BIN(rtc_tm->tm_sec);
BCD_TO_BIN(rtc_tm->tm_min);
BCD_TO_BIN(rtc_tm->tm_hour);
BCD_TO_BIN(rtc_tm->tm_mday);
BCD_TO_BIN(rtc_tm->tm_mon);
BCD_TO_BIN(rtc_tm->tm_year);
/*
* Account for differences between how the RTC uses the values
* and how they are defined in a struct rtc_time;
*/
if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
rtc_tm->tm_year += 100;
rtc_tm->tm_mon--;
}
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
* Bridge address map * Bridge address map
*/ */
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) #ifndef __ASSEMBLY__
/* /*
* All accesses to bridge hardware registers must be done * All accesses to bridge hardware registers must be done
...@@ -283,7 +283,7 @@ typedef struct bridge_err_cmdword_s { ...@@ -283,7 +283,7 @@ typedef struct bridge_err_cmdword_s {
} bridge_err_cmdword_t; } bridge_err_cmdword_t;
#define berr_field berr_un.berr_st #define berr_field berr_un.berr_st
#endif /* LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
/* /*
* The values of these macros can and should be crosschecked * The values of these macros can and should be crosschecked
...@@ -612,7 +612,7 @@ typedef struct bridge_err_cmdword_s { ...@@ -612,7 +612,7 @@ typedef struct bridge_err_cmdword_s {
/* Bridge INT_DEV register bits definition */ /* Bridge INT_DEV register bits definition */
#define BRIDGE_INT_DEV_SHFT(n) ((n)*3) #define BRIDGE_INT_DEV_SHFT(n) ((n)*3)
#define BRIDGE_INT_DEV_MASK(n) (0x7 << BRIDGE_INT_DEV_SHFT(n)) #define BRIDGE_INT_DEV_MASK(n) (0x7 << BRIDGE_INT_DEV_SHFT(n))
#define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line)) #define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line))
/* Bridge interrupt(x) register bits definition */ /* Bridge interrupt(x) register bits definition */
#define BRIDGE_INT_ADDR_HOST 0x0003FF00 #define BRIDGE_INT_ADDR_HOST 0x0003FF00
...@@ -793,7 +793,7 @@ typedef struct bridge_err_cmdword_s { ...@@ -793,7 +793,7 @@ typedef struct bridge_err_cmdword_s {
#define PCI64_ATTR_RMF_MASK 0x00ff000000000000 #define PCI64_ATTR_RMF_MASK 0x00ff000000000000
#define PCI64_ATTR_RMF_SHFT 48 #define PCI64_ATTR_RMF_SHFT 48
#if LANGUAGE_C #ifndef __ASSEMBLY__
/* Address translation entry for mapped pci32 accesses */ /* Address translation entry for mapped pci32 accesses */
typedef union ate_u { typedef union ate_u {
u64 ent; u64 ent;
...@@ -809,7 +809,7 @@ typedef union ate_u { ...@@ -809,7 +809,7 @@ typedef union ate_u {
u64 valid:1; u64 valid:1;
} field; } field;
} ate_t; } ate_t;
#endif /* LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
#define ATE_V 0x01 #define ATE_V 0x01
#define ATE_CO 0x02 #define ATE_CO 0x02
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
#include <linux/config.h> #include <linux/config.h>
#if _LANGUAGE_C #ifndef __ASSEMBLY__
#include <linux/types.h> #include <linux/types.h>
#endif /* _LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <asm/reg.h> #include <asm/reg.h>
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#endif #endif
#if _LANGUAGE_C #ifndef __ASSEMBLY__
#if defined(CONFIG_SGI_IO) /* FIXME */ #if defined(CONFIG_SGI_IO) /* FIXME */
#define PS_UINT_CAST (__psunsigned_t) #define PS_UINT_CAST (__psunsigned_t)
...@@ -38,13 +38,13 @@ ...@@ -38,13 +38,13 @@
#define HUBREG_CAST (volatile hubreg_t *) #define HUBREG_CAST (volatile hubreg_t *)
#elif _LANGUAGE_ASSEMBLY #else /* __ASSEMBLY__ */
#define PS_UINT_CAST #define PS_UINT_CAST
#define UINT64_CAST #define UINT64_CAST
#define HUBREG_CAST #define HUBREG_CAST
#endif #endif /* __ASSEMBLY__ */
#define NASID_GET_META(_n) ((_n) >> NASID_LOCAL_BITS) #define NASID_GET_META(_n) ((_n) >> NASID_LOCAL_BITS)
...@@ -278,7 +278,7 @@ ...@@ -278,7 +278,7 @@
0x800000 + (_x))) 0x800000 + (_x)))
#endif /* CONFIG_SGI_IP27 */ #endif /* CONFIG_SGI_IP27 */
#if _LANGUAGE_C #ifndef __ASSEMBLY__
#define HUB_L(_a) *(_a) #define HUB_L(_a) *(_a)
#define HUB_S(_a, _d) *(_a) = (_d) #define HUB_S(_a, _d) *(_a) = (_d)
...@@ -290,7 +290,7 @@ ...@@ -290,7 +290,7 @@
#define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r))) #define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
#define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d)) #define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
#endif /* _LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
/* /*
* The following macros are used to get to a hub/bridge register, given * The following macros are used to get to a hub/bridge register, given
...@@ -367,7 +367,7 @@ ...@@ -367,7 +367,7 @@
#define KLI_KERN_XP 8 #define KLI_KERN_XP 8
#define KLI_KERN_PARTID 9 #define KLI_KERN_PARTID 9
#if _LANGUAGE_C #ifndef __ASSEMBLY__
#define KLD_BASE(nasid) ((kldir_ent_t *) KLDIR_ADDR(nasid)) #define KLD_BASE(nasid) ((kldir_ent_t *) KLDIR_ADDR(nasid))
#define KLD_LAUNCH(nasid) (KLD_BASE(nasid) + KLI_LAUNCH) #define KLD_LAUNCH(nasid) (KLD_BASE(nasid) + KLI_LAUNCH)
...@@ -453,7 +453,7 @@ ...@@ -453,7 +453,7 @@
#define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET) #define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET)
#endif /* _LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_SN_ADDRS_H */ #endif /* _ASM_SN_ADDRS_H */
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#endif #endif
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) #ifndef __ASSEMBLY__
#if !defined(CONFIG_SGI_IO) #if !defined(CONFIG_SGI_IO)
typedef u64 hubreg_t; typedef u64 hubreg_t;
typedef u64 nic_t; typedef u64 nic_t;
...@@ -44,7 +44,7 @@ typedef u64 nic_t; ...@@ -44,7 +44,7 @@ typedef u64 nic_t;
#define makespnum(_nasid, _slice) \ #define makespnum(_nasid, _slice) \
(((_nasid) << CPUS_PER_NODE_SHFT) | (_slice)) (((_nasid) << CPUS_PER_NODE_SHFT) | (_slice))
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) #ifndef __ASSEMBLY__
#define INVALID_NASID (nasid_t)-1 #define INVALID_NASID (nasid_t)-1
#define INVALID_CNODEID (cnodeid_t)-1 #define INVALID_CNODEID (cnodeid_t)-1
...@@ -102,7 +102,7 @@ nasid_t compact_to_nasid_nodeid(cnodeid_t cnode); ...@@ -102,7 +102,7 @@ nasid_t compact_to_nasid_nodeid(cnodeid_t cnode);
extern int node_getlastslot(cnodeid_t); extern int node_getlastslot(cnodeid_t);
#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */ #endif /* !__ASSEMBLY__ */
#define SLOT_BITMASK (MAX_MEM_SLOTS - 1) #define SLOT_BITMASK (MAX_MEM_SLOTS - 1)
#define SLOT_SIZE (1LL<<SLOT_SHIFT) #define SLOT_SIZE (1LL<<SLOT_SHIFT)
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* gda.h -- Contains the data structure for the global data area, * gda.h -- Contains the data structure for the global data area,
* The GDA contains information communicated between the * The GDA contains information communicated between the
* PROM, SYMMON, and the kernel. * PROM, SYMMON, and the kernel.
*/ */
#ifndef _ASM_SN_GDA_H #ifndef _ASM_SN_GDA_H
#define _ASM_SN_GDA_H #define _ASM_SN_GDA_H
...@@ -23,9 +23,9 @@ ...@@ -23,9 +23,9 @@
* *
* Version # | Change * Version # | Change
* -------------+------------------------------------------------------- * -------------+-------------------------------------------------------
* 1 | Initial SN0 version * 1 | Initial SN0 version
* 2 | Prom sets g_partid field to the partition number. 0 IS * 2 | Prom sets g_partid field to the partition number. 0 IS
* | a valid partition #. * | a valid partition #.
*/ */
#define GDA_VERSION 2 /* Current GDA version # */ #define GDA_VERSION 2 /* Current GDA version # */
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#define G_PARTIDOFF 40 #define G_PARTIDOFF 40
#define G_TABLEOFF 128 #define G_TABLEOFF 128
#ifdef _LANGUAGE_C #ifndef __ASSEMBLY__
typedef struct gda { typedef struct gda {
u32 g_magic; /* GDA magic number */ u32 g_magic; /* GDA magic number */
...@@ -67,10 +67,10 @@ typedef struct gda { ...@@ -67,10 +67,10 @@ typedef struct gda {
#define GDA ((gda_t*) GDA_ADDR(get_nasid())) #define GDA ((gda_t*) GDA_ADDR(get_nasid()))
#endif /* __LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
/* /*
* Define: PART_GDA_VERSION * Define: PART_GDA_VERSION
* Purpose: Define the minimum version of the GDA required, lower * Purpose: Define the minimum version of the GDA required, lower
* revisions assume GDA is NOT set up, and read partition * revisions assume GDA is NOT set up, and read partition
* information from the board info. * information from the board info.
*/ */
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <asm/sn/intr_public.h> #include <asm/sn/intr_public.h>
#if _LANGUAGE_C #ifndef __ASSEMBLY__
/* /*
* Macros to manipulate the interrupt register on the calling hub chip. * Macros to manipulate the interrupt register on the calling hub chip.
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (0x100|(_level))) REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (0x100|(_level)))
/* /*
* When clearing the interrupt, make sure this clear does make it * When clearing the interrupt, make sure this clear does make it
* to the hub. Otherwise we could end up losing interrupts. * to the hub. Otherwise we could end up losing interrupts.
* We do an uncached load of the int_pend0 register to ensure this. * We do an uncached load of the int_pend0 register to ensure this.
*/ */
...@@ -43,9 +43,9 @@ ...@@ -43,9 +43,9 @@
REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (_level)), \ REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (_level)), \
REMOTE_HUB_L((_hub), PI_INT_PEND0) REMOTE_HUB_L((_hub), PI_INT_PEND0)
#else /* LANGUAGE_ASSEMBLY */ #else /* __ASSEMBLY__ */
#endif /* LANGUAGE_C */ #endif /* __ASSEMBLY__ */
/* /*
* Hard-coded interrupt levels: * Hard-coded interrupt levels:
......
/* /*
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#define INTPEND0_MAXMASK (N_INTPEND0_MASKS - 1) #define INTPEND0_MAXMASK (N_INTPEND0_MASKS - 1)
#define INTPEND1_MAXMASK (N_INTPEND1_MASKS - 1) #define INTPEND1_MAXMASK (N_INTPEND1_MASKS - 1)
#if _LANGUAGE_C #ifndef __ASSEMBLY__
#include <asm/sn/arch.h> #include <asm/sn/arch.h>
struct intr_vecblk_s; /* defined in asm/sn/intr.h */ struct intr_vecblk_s; /* defined in asm/sn/intr.h */
...@@ -40,14 +40,14 @@ typedef struct hub_intmasks_s { ...@@ -40,14 +40,14 @@ typedef struct hub_intmasks_s {
* in the lowest-numbered masks (i.e., 0, 1, 2...). * in the lowest-numbered masks (i.e., 0, 1, 2...).
*/ */
/* INT_PEND0: */ /* INT_PEND0: */
hubreg_t intpend0_masks[N_INTPEND0_MASKS]; hubreg_t intpend0_masks[N_INTPEND0_MASKS];
/* INT_PEND1: */ /* INT_PEND1: */
hubreg_t intpend1_masks[N_INTPEND1_MASKS]; hubreg_t intpend1_masks[N_INTPEND1_MASKS];
/* INT_PEND0: */ /* INT_PEND0: */
struct intr_vecblk_s *dispatch0; struct intr_vecblk_s *dispatch0;
/* INT_PEND1: */ /* INT_PEND1: */
struct intr_vecblk_s *dispatch1; struct intr_vecblk_s *dispatch1;
} hub_intmasks_t; } hub_intmasks_t;
#endif /* _LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
#endif /* __ASM_SN_INTR_PUBLIC_H */ #endif /* __ASM_SN_INTR_PUBLIC_H */
...@@ -11,19 +11,9 @@ ...@@ -11,19 +11,9 @@
#include <linux/config.h> #include <linux/config.h>
#if !defined(CONFIG_SGI_IO) #ifdef CONFIG_SGI_IO
#include <asm/sn/sn0/addrs.h>
#define IO_SPACE_BASE IO_BASE
/* Because we only have PCI I/O ports. */
#define IO_SPACE_LIMIT 0xffffffff
/* No isa_* versions, the Origin doesn't have ISA / EISA bridges. */
#else /* CONFIG_SGI_IO */ #define IIO_ITTE_BASE 0x400160 /* base of translation table entries */
#define IIO_ITTE_BASE 0x400160 /* base of translation table entries */
#define IIO_ITTE(bigwin) (IIO_ITTE_BASE + 8*(bigwin)) #define IIO_ITTE(bigwin) (IIO_ITTE_BASE + 8*(bigwin))
#define IIO_ITTE_OFFSET_BITS 5 /* size of offset field */ #define IIO_ITTE_OFFSET_BITS 5 /* size of offset field */
...@@ -56,9 +46,9 @@ ...@@ -56,9 +46,9 @@
#define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin)) #define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin))
/* /*
* Macro which takes the widget number, and returns the * Macro which takes the widget number, and returns the
* IO PRB address of that widget. * IO PRB address of that widget.
* value _x is expected to be a widget number in the range * value _x is expected to be a widget number in the range
* 0, 8 - 0xF * 0, 8 - 0xF
*/ */
#define IIO_IOPRB(_x) (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \ #define IIO_IOPRB(_x) (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
...@@ -69,6 +59,17 @@ ...@@ -69,6 +59,17 @@
#include <asm/sn/sn0/hubio.h> #include <asm/sn/sn0/hubio.h>
#endif #endif
#else /* CONFIG_SGI_IO */
#include <asm/sn/sn0/addrs.h>
#define IO_SPACE_BASE IO_BASE
/* Because we only have PCI I/O ports. */
#define IO_SPACE_LIMIT 0xffffffff
/* No isa_* versions, the Origin doesn't have ISA / EISA bridges. */
#endif /* CONFIG_SGI_IO */ #endif /* CONFIG_SGI_IO */
#endif /* _ASM_SN_IO_H */ #endif /* _ASM_SN_IO_H */
This diff is collapsed.
...@@ -127,14 +127,14 @@ ...@@ -127,14 +127,14 @@
* 0x0 (0K) +-----------------------------------------+ * 0x0 (0K) +-----------------------------------------+
*/ */
#ifdef LANGUAGE_ASSEMBLY #ifdef __ASSEMBLY__
#define KLDIR_OFF_MAGIC 0x00 #define KLDIR_OFF_MAGIC 0x00
#define KLDIR_OFF_OFFSET 0x08 #define KLDIR_OFF_OFFSET 0x08
#define KLDIR_OFF_POINTER 0x10 #define KLDIR_OFF_POINTER 0x10
#define KLDIR_OFF_SIZE 0x18 #define KLDIR_OFF_SIZE 0x18
#define KLDIR_OFF_COUNT 0x20 #define KLDIR_OFF_COUNT 0x20
#define KLDIR_OFF_STRIDE 0x28 #define KLDIR_OFF_STRIDE 0x28
#endif /* LANGUAGE_ASSEMBLY */ #endif /* __ASSEMBLY__ */
#if !defined(CONFIG_SGI_IO) #if !defined(CONFIG_SGI_IO)
...@@ -199,7 +199,7 @@ ...@@ -199,7 +199,7 @@
#define IP27_NMI_KREGS_OFFSET 0x11400 #define IP27_NMI_KREGS_OFFSET 0x11400
#define IP27_NMI_KREGS_CPU_SIZE 0x200 #define IP27_NMI_KREGS_CPU_SIZE 0x200
/* /*
* save area of kernel nmi regs in eframe format * save area of kernel nmi regs in eframe format
*/ */
#define IP27_NMI_EFRAME_OFFSET 0x11800 #define IP27_NMI_EFRAME_OFFSET 0x11800
#define IP27_NMI_EFRAME_SIZE 0x200 #define IP27_NMI_EFRAME_SIZE 0x200
...@@ -209,7 +209,7 @@ ...@@ -209,7 +209,7 @@
#endif /* !CONFIG_SGI_IO */ #endif /* !CONFIG_SGI_IO */
#ifdef _LANGUAGE_C #ifndef __ASSEMBLY__
typedef struct kldir_ent_s { typedef struct kldir_ent_s {
u64 magic; /* Indicates validity of entry */ u64 magic; /* Indicates validity of entry */
off_t offset; /* Offset from start of node space */ off_t offset; /* Offset from start of node space */
...@@ -225,7 +225,7 @@ typedef struct kldir_ent_s { ...@@ -225,7 +225,7 @@ typedef struct kldir_ent_s {
/* NOTE: These 16 bytes are used in the Partition KLDIR /* NOTE: These 16 bytes are used in the Partition KLDIR
entry to store partition info. Refer to klpart.h for this. */ entry to store partition info. Refer to klpart.h for this. */
} kldir_ent_t; } kldir_ent_t;
#endif /* _LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
#if defined(CONFIG_SGI_IO) #if defined(CONFIG_SGI_IO)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#define KV_MAGIC 0x5f4b565f #define KV_MAGIC 0x5f4b565f
#if _LANGUAGE_C #ifndef __ASSEMBLY__
#include <asm/sn/types.h> #include <asm/sn/types.h>
...@@ -23,7 +23,7 @@ typedef struct kern_vars_s { ...@@ -23,7 +23,7 @@ typedef struct kern_vars_s {
unsigned long kv_rw_baseaddr; unsigned long kv_rw_baseaddr;
} kern_vars_t; } kern_vars_t;
#endif /* _LANGUAGE_C */ #endif /* !__ASSEMBLY__ */
#endif /* __ASM_SN_KLKERNVARS_H */ #endif /* __ASM_SN_KLKERNVARS_H */
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
* clears the BUSY flag after control is returned to it. * clears the BUSY flag after control is returned to it.
*/ */
#ifdef _LANGUAGE_C #ifndef __ASSEMBLY__
typedef int launch_state_t; typedef int launch_state_t;
typedef void (*launch_proc_t)(u64 call_parm); typedef void (*launch_proc_t)(u64 call_parm);
...@@ -102,21 +102,6 @@ typedef struct launch_s { ...@@ -102,21 +102,6 @@ typedef struct launch_s {
#define LAUNCH_FLASH (*(void (*)(void)) \ #define LAUNCH_FLASH (*(void (*)(void)) \
IP27PROM_FLASHLEDS) IP27PROM_FLASHLEDS)
#ifdef _STANDALONE #endif /* !__ASSEMBLY__ */
launch_t *launch_get(int nasid, int cpu);
launch_t *launch_get_current(void);
void launch_loop(void);
void launch_slave(int nasid, int cpu,
launch_proc_t call_addr,
__int64_t call_parm,
void *stack_addr,
void *gp_addr);
int launch_wait(int nasid, int cpu, int timeout_msec);
launch_state_t launch_poll(int nasid, int cpu);
#endif /* _STANDALONE */
#endif /* _LANGUAGE_C */
#endif /* _ASM_SN_LAUNCH_H */ #endif /* _ASM_SN_LAUNCH_H */
...@@ -6,18 +6,18 @@ ...@@ -6,18 +6,18 @@
#define __ASM_SN_MAPPED_KERNEL_H #define __ASM_SN_MAPPED_KERNEL_H
/* /*
* Note on how mapped kernels work: the text and data section is * Note on how mapped kernels work: the text and data section is
* compiled at cksseg segment (LOADADDR = 0xc001c000), and the * compiled at cksseg segment (LOADADDR = 0xc001c000), and the
* init/setup/data section gets a 16M virtual address bump in the * init/setup/data section gets a 16M virtual address bump in the
* ld.script file (so that tlblo0 and tlblo1 maps the sections). * ld.script file (so that tlblo0 and tlblo1 maps the sections).
* The vmlinux.64 section addresses are put in the xkseg range * The vmlinux.64 section addresses are put in the xkseg range
* using the change-addresses makefile option. Use elfdump -of * using the change-addresses makefile option. Use elfdump -of
* on IRIX to see where the sections go. The Origin loader loads * on IRIX to see where the sections go. The Origin loader loads
* the two sections contiguously in physical memory. The loader * the two sections contiguously in physical memory. The loader
* sets the entry point into kernel_entry using a xkphys address, * sets the entry point into kernel_entry using a xkphys address,
* but instead of using 0xa800000001160000, it uses the address * but instead of using 0xa800000001160000, it uses the address
* 0xa800000000160000, which is where it physically loaded that * 0xa800000000160000, which is where it physically loaded that
* code. So no jumps can be done before we have switched to using * code. So no jumps can be done before we have switched to using
* cksseg addresses. * cksseg addresses.
*/ */
#include <linux/config.h> #include <linux/config.h>
......
This diff is collapsed.
This diff is collapsed.
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#define MAX_PREMIUM_REGIONS MAX_REGIONS #define MAX_PREMIUM_REGIONS MAX_REGIONS
/* /*
* MAX_PARITIONS refers to the maximum number of logically defined * MAX_PARITIONS refers to the maximum number of logically defined
* partitions the system can support. * partitions the system can support.
*/ */
#define MAX_PARTITIONS MAX_REGIONS #define MAX_PARTITIONS MAX_REGIONS
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment