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 @@
# 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 \
ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o
ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
ip27-setup.o ip27-timer.o
EXTRA_AFLAGS := $(CFLAGS)
......@@ -5,6 +5,7 @@
*
* Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
* Copyright (C) 1999, 2000 by Silicon Graphics
* Copyright (C) 2002 Maciej W. Rozycki
*/
#include <linux/init.h>
#include <linux/kernel.h>
......@@ -14,86 +15,13 @@
#include <asm/sn/addrs.h>
#include <asm/sn/arch.h>
#include <asm/sn/sn0/hub.h>
#include <asm/tlbdebug.h>
#include <asm/traps.h>
#include <asm/uaccess.h>
extern void dump_tlb_addr(unsigned long addr);
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 char *err_type[2][8] = {
......@@ -127,21 +55,17 @@ static void dump_hub_information(unsigned long errst0, unsigned long errst1)
? : "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);
fixup = search_dbe_table(regs->cp0_epc);
if (fixup) {
long new_epc;
new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
regs->cp0_epc = new_epc;
return;
}
if (is_fixup)
return MIPS_BE_FIXUP;
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("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);
......@@ -153,15 +77,13 @@ void do_dbe(struct pt_regs *regs)
force_sig(SIGBUS, current);
}
void __init
bus_error_init(void)
void __init ip27_be_init(void)
{
/* XXX Initialize all the Hub & Bridge error handling here. */
int cpu = LOCAL_HUB_L(PI_CPU_NUM);
int cpuoff = cpu << 8;
set_except_vector(6, handle_ibe);
set_except_vector(7, handle_dbe);
board_be_handler = ip27_be_handler;
LOCAL_HUB_S(PI_ERR_INT_PEND,
cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
......
......@@ -3,25 +3,35 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2001 Ralf Baechle
* Copyright (C) 2001, 2002 Ralf Baechle
*/
#include <linux/init.h>
#include <linux/console.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/serial.h>
#include <asm/page.h>
#include <asm/sn/addrs.h>
#include <asm/sn/sn0/hub.h>
#include <asm/sn/klconfig.h>
#include <asm/sn/ioc3.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_uartregs *uart;
ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base;
uart = &ioc3->sregs.uarta;
ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
return &ioc3->sregs.uarta;
}
void prom_putchar(char c)
{
struct ioc3_uartregs *uart = console_uart();
while ((uart->iu_lsr & 0x20) == 0);
uart->iu_thr = c;
......@@ -32,27 +42,24 @@ char __init prom_getchar(void)
return 0;
}
static void
ip27prom_console_write(struct console *con, const char *s, unsigned n)
static void inline ioc3_console_probe(void)
{
prom_printf("%s", s);
}
struct serial_struct req;
static kdev_t
ip27prom_console_dev(struct console *c)
{
return MKDEV(TTY_MAJOR, 64 + c->index);
}
/* Register to interrupt zero because we share the interrupt with
the serial driver which we don't properly support yet. */
memset(&req, 0, sizeof(req));
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 = {
.name = "prom",
.write = ip27prom_console_write,
.device = ip27prom_console_dev,
.flags = CON_PRINTBUFFER,
.index = -1,
};
req.iomem_base = (unsigned char *) console_uart();
register_serial(&req);
}
__init void ip27_setup_console(void)
{
register_console(&ip27_prom_console);
ioc3_console_probe();
}
......@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/mmzone.h> /* for numnodes */
#include <linux/mm.h>
#include <asm/cpu.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/sn/types.h>
......@@ -28,6 +29,7 @@
#include <asm/smp.h>
#include <asm/processor.h>
#include <asm/mmu_context.h>
#include <asm/thread_info.h>
#include <asm/sn/launch.h>
#include <asm/sn/sn_private.h>
#include <asm/sn/sn0/ip27.h>
......@@ -45,8 +47,8 @@
#define CNODEMASK_SETB(p, bit) ((p) |= 1ULL << (bit))
cpumask_t boot_cpumask;
hubreg_t region_mask = 0;
static int fine_mode = 0;
hubreg_t region_mask;
static int fine_mode;
int maxcpus;
static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED;
static cnodemask_t hub_init_mask;
......@@ -176,17 +178,17 @@ cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes)
* cpus are not numbered.
*/
return(highest + 1);
return highest + 1;
}
int cpu_enabled(cpuid_t cpu)
{
if (cpu == CPU_NONE)
return 0;
return (CPUMASK_TSTB(boot_cpumask, cpu) != 0);
return CPUMASK_TSTB(boot_cpumask, cpu) != 0;
}
void mlreset (void)
void mlreset(void)
{
int i;
void init_topology_matrix(void);
......@@ -332,8 +334,7 @@ void per_hub_init(cnodeid_t cnode)
memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
0x100);
flush_cache_l1();
flush_cache_l2();
__flush_cache_all();
}
#endif
}
......@@ -359,12 +360,11 @@ void per_cpu_init(void)
int cpu = smp_processor_id();
cnodeid_t cnode = get_compact_nodeid();
current_cpu_data.asid_cache = ASID_FIRST_VERSION;
TLBMISS_HANDLER_SETUP();
#if 0
intr_init();
#endif
set_cp0_status(ST0_IM, 0);
clear_c0_status(ST0_IM);
per_hub_init(cnode);
cpu_time_init();
if (smp_processor_id()) /* master can't do this early, no kmalloc */
......@@ -374,13 +374,13 @@ void per_cpu_init(void)
#if 0
install_tlbintr(cpu);
#endif
set_cp0_status(SRB_DEV0 | SRB_DEV1, SRB_DEV0 | SRB_DEV1);
set_c0_status(SRB_DEV0 | SRB_DEV1);
if (is_slave) {
set_cp0_status(ST0_BEV, 0);
if (mips4_available)
set_cp0_status(ST0_XX, ST0_XX);
set_cp0_status(ST0_KX|ST0_SX|ST0_UX, ST0_KX|ST0_SX|ST0_UX);
sti();
clear_c0_status(ST0_BEV);
if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
set_c0_status(ST0_XX);
set_c0_status(ST0_KX|ST0_SX|ST0_UX);
local_irq_enable();
load_mmu();
atomic_inc(&numstarted);
} else {
......@@ -420,100 +420,59 @@ static void alloc_cpupda(cpuid_t cpu, int cpunum)
cpu_data[cpunum].p_cpuid = cpu;
}
void __init smp_callin(void)
static struct task_struct * __init fork_by_hand(void)
{
#if 0
calibrate_delay();
smp_store_cpu_info(cpuid);
#endif
}
int __init start_secondary(void)
{
extern int cpu_idle(void);
extern atomic_t smp_commenced;
smp_callin();
while (!atomic_read(&smp_commenced));
return cpu_idle();
}
static volatile cpumask_t boot_barrier;
void cboot(void)
{
CPUMASK_CLRB(boot_barrier, getcpuid()); /* needs atomicity */
per_cpu_init();
#if 0
ecc_init();
bte_lateinit();
init_mfhi_war();
#endif
_flush_tlb_all();
flush_cache_l1();
flush_cache_l2();
start_secondary();
struct pt_regs regs;
/*
* don't care about the eip and regs settings since
* we'll never reschedule the forked task.
*/
return copy_process(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
}
void allowboot(void)
static int __init do_boot_cpu(int cpu, int num_cpus)
{
int num_cpus = 0;
cpuid_t cpu, mycpuid = getcpuid();
cnodeid_t cnode;
extern void bootstrap(void);
extern void smp_bootstrap(void);
cpuid_t mycpuid = getcpuid();
struct task_struct *idle;
sn_mp_setup();
/* Master has already done per_cpu_init() */
install_cpuintr(smp_processor_id());
#if 0
bte_lateinit();
ecc_init();
#endif
replicate_kernel_text(numnodes);
boot_barrier = boot_cpumask;
/* Launch slaves. */
for (cpu = 0; cpu < maxcpus; cpu++) {
if (cpu == mycpuid) {
alloc_cpupda(cpu, num_cpus);
num_cpus++;
/* We're already started, clear our bit */
CPUMASK_CLRB(boot_barrier, cpu);
continue;
return 1;
}
/* Skip holes in CPU space */
if (CPUMASK_TSTB(boot_cpumask, cpu)) {
struct task_struct *p;
if (!CPUMASK_TSTB(boot_cpumask, cpu))
return 0;
/*
* The following code is purely to make sure
* Linux can schedule processes on this slave.
*/
kernel_thread(0, NULL, CLONE_IDLETASK);
p = prev_task(&init_task);
sprintf(p->comm, "%s%d", "Idle", num_cpus);
init_tasks[num_cpus] = p;
idle = fork_by_hand();
if (IS_ERR(idle))
panic("failed fork for CPU %d", cpu);
/*
* We remove it from the pidhash and the runqueue
* once we got the process:
*/
init_idle(idle, cpu);
alloc_cpupda(cpu, num_cpus);
del_from_runqueue(p);
p->processor = num_cpus;
p->cpus_runnable = 1 << num_cpus; /* we schedule the first task manually */
unhash_process(p);
/* Attach to the address space of init_task. */
atomic_inc(&init_mm.mm_count);
p->active_mm = &init_mm;
unhash_process(idle);
/*
* Launch a slave into bootstrap().
* It doesn't take an argument, and we
* set sp to the kernel stack of the newly
* created idle process, gp to the proc struct
* (so that current-> works).
* Launch a slave into smp_bootstrap(). It doesn't take an
* argument, and we set sp to the kernel stack of the newly
* created idle process, gp to the proc struct so that
* current_thread_info() will work.
*/
LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus),
(launch_proc_t)MAPPED_KERN_RW_TO_K0(bootstrap),
0, (void *)((unsigned long)p +
KERNEL_STACK_SIZE - 32), (void *)p);
(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
0, (void *)((unsigned long)idle->thread_info +
KERNEL_STACK_SIZE - 32), (void *)idle);
/*
* Now optimistically set the mapping arrays. We
......@@ -522,7 +481,8 @@ void allowboot(void)
*/
__cpu_number_map[cpu] = num_cpus;
__cpu_logical_map[num_cpus] = cpu;
num_cpus++;
CPUMASK_SETB(cpu_online_map, cpu);
/*
* Wait this cpu to start up and initialize its hub,
* and discover the io devices it will control.
......@@ -531,10 +491,34 @@ void allowboot(void)
* at once. We have to preserve the order of the
* devices on the bridges first though.
*/
while(atomic_read(&numstarted) != num_cpus);
}
}
while (atomic_read(&numstarted) != num_cpus);
return 1;
}
void __init smp_boot_cpus(void)
{
int num_cpus = 0;
cpuid_t cpu;
cnodeid_t cnode;
init_new_context(current, &init_mm);
current_thread_info()->cpu = 0;
smp_tune_scheduling();
sn_mp_setup();
/* Master has already done per_cpu_init() */
install_cpuintr(smp_processor_id());
#if 0
bte_lateinit();
ecc_init();
#endif
replicate_kernel_text(numnodes);
/* Launch slaves. */
for (cpu = 0; cpu < maxcpus; cpu++) {
num_cpus += do_boot_cpu(cpu, num_cpus);
}
#ifdef LATER
Wait logic goes here.
......@@ -551,18 +535,19 @@ void allowboot(void)
cpu_io_setup();
init_mfhi_war();
#endif
smp_num_cpus = num_cpus;
}
#else /* CONFIG_SMP */
void cboot(void) {}
void __init start_secondary(void)
{
/* XXX Why do we need this empty definition at all? */
}
#endif /* CONFIG_SMP */
#define rou_rflag rou_flags
void
router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
{
klrou_t *router;
lboard_t *brd;
......@@ -598,8 +583,7 @@ router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
router_a->rou_rflag = 0;
}
int
node_distance(nasid_t nasid_a, nasid_t nasid_b)
int node_distance(nasid_t nasid_a, nasid_t nasid_b)
{
nasid_t nasid;
cnodeid_t cnode;
......@@ -666,8 +650,7 @@ node_distance(nasid_t nasid_a, nasid_t nasid_b)
return router_distance;
}
void
init_topology_matrix(void)
void init_topology_matrix(void)
{
nasid_t nasid, nasid2;
cnodeid_t row, col;
......@@ -685,8 +668,7 @@ init_topology_matrix(void)
}
}
void
dump_topology(void)
void dump_topology(void)
{
nasid_t nasid;
cnodeid_t cnode;
......@@ -837,4 +819,3 @@ dump_klcfg(void)
dump_topology();
}
#endif
......@@ -224,7 +224,7 @@ prom_free_prom_memory (void)
#ifdef CONFIG_DISCONTIGMEM
static pfn_t pagenr = 0;
static pfn_t pagenr;
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);
/* 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);
pgd_set(swapper_pg_dir, kpmdtbl);
for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
set_pgd(swapper_pg_dir, __pgd(kpmdtbl));
for (i = 0; i < (1 << PGD_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
pmd_val(*pmd) = (unsigned long)pte;
for (node = 0; node < numnodes; node++) {
......
......@@ -157,7 +157,7 @@ cont_nmi_dump(void)
udelay(10000);
}
#else
while (atomic_read(&nmied_cpus) != smp_num_cpus);
while (atomic_read(&nmied_cpus) != num_online_cpus());
#endif
/*
......
......@@ -14,8 +14,10 @@
#include <linux/timer.h>
#include <linux/smp.h>
#include <linux/mmzone.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/reboot.h>
#include <asm/system.h>
#include <asm/sgialib.h>
#include <asm/sn/addrs.h>
......@@ -30,7 +32,7 @@ void machine_power_off(void) __attribute__((noreturn));
#define noreturn while(1); /* Silence gcc. */
/* XXX How to pass the reboot command to the firmware??? */
void machine_restart(char *command)
static void ip27_machine_restart(char *command)
{
#if 0
int i;
......@@ -50,7 +52,7 @@ void machine_restart(char *command)
noreturn;
}
void machine_halt(void)
static void ip27_machine_halt(void)
{
int i;
......@@ -64,7 +66,7 @@ void machine_halt(void)
noreturn;
}
void machine_power_off(void)
static void ip27_machine_power_off(void)
{
/* To do ... */
noreturn;
......@@ -72,5 +74,7 @@ void machine_power_off(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 @@
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <asm/io.h>
#include <asm/sn/types.h>
#include <asm/sn/sn0/addrs.h>
......@@ -21,12 +22,14 @@
#include <asm/sn/sn0/hubio.h>
#include <asm/sn/klconfig.h>
#include <asm/sn/ioc3.h>
#include <asm/time.h>
#include <asm/mipsregs.h>
#include <asm/sn/arch.h>
#include <asm/sn/sn_private.h>
#include <asm/pci/bridge.h>
#include <asm/paccess.h>
#include <asm/sn/sn0/ip27.h>
#include <asm/traps.h>
/* Check against user dumbness. */
#ifdef CONFIG_VT
......@@ -40,7 +43,7 @@
#define DBG(x...)
#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.
......@@ -275,6 +278,8 @@ void __init pcibr_setup(cnodeid_t nid)
}
extern void ip27_setup_console(void);
extern void ip27_time_init(void);
extern void ip27_reboot_setup(void);
void __init ip27_setup(void)
{
......@@ -282,6 +287,7 @@ void __init ip27_setup(void)
hubreg_t p, e;
ip27_setup_console();
ip27_reboot_setup();
num_bridges = 0;
/*
......@@ -307,4 +313,7 @@ void __init ip27_setup(void)
ioc3_sio_init();
ioc3_eth_init();
per_cpu_init();
mips_io_port_base = IO_BASE;
board_time_init = ip27_time_init;
}
......@@ -2,6 +2,7 @@
* Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
* Copytight (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <linux/bcd.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
......@@ -14,6 +15,7 @@
#include <linux/mm.h>
#include <linux/bcd.h>
#include <asm/time.h>
#include <asm/pgtable.h>
#include <asm/sgialib.h>
#include <asm/sn/ioc3.h>
......@@ -34,10 +36,11 @@
* Ralf: which clock rate is used to feed the counter?
*/
#define NSEC_PER_CYCLE 800
#define NSEC_PER_SEC 1000000000
#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE)
#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 long last_rtc_update; /* Last time the rtc clock got updated */
......@@ -56,8 +59,7 @@ static int set_rtc_mmss(unsigned long nowtime)
IOC3_BYTEBUS_DEV0);
rtc->control |= M48T35_RTC_READ;
cmos_minutes = rtc->min;
BCD_TO_BIN(cmos_minutes);
cmos_minutes = BCD2BIN(rtc->min);
rtc->control &= ~M48T35_RTC_READ;
/*
......@@ -72,8 +74,8 @@ static int set_rtc_mmss(unsigned long nowtime)
real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) {
BIN_TO_BCD(real_seconds);
BIN_TO_BCD(real_minutes);
real_seconds = BIN2BCD(real_seconds);
real_minutes = BIN2BCD(real_minutes);
rtc->control |= M48T35_RTC_SET;
rtc->sec = real_seconds;
rtc->min = real_minutes;
......@@ -92,8 +94,9 @@ void rt_timer_interrupt(struct pt_regs *regs)
{
int cpu = smp_processor_id();
int cpuA = ((cputoslice(cpu)) == 0);
int irq = 7; /* XXX Assign number */
int irq = 9; /* XXX Assign number */
irq_enter();
write_seqlock(&xtime_lock);
again:
......@@ -110,19 +113,7 @@ void rt_timer_interrupt(struct pt_regs *regs)
do_timer(regs);
#ifdef CONFIG_SMP
{
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);
}
update_process_times(user_mode(regs));
#endif /* CONFIG_SMP */
/*
......@@ -131,80 +122,31 @@ void rt_timer_interrupt(struct pt_regs *regs)
* called as close as possible to when a second starts.
*/
if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660) {
if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) {
if (set_rtc_mmss(xtime.tv_sec + 1) == 0)
xtime.tv_sec > last_rtc_update + 660 &&
(xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
(xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
if (rtc_set_time(xtime.tv_sec) == 0) {
last_rtc_update = xtime.tv_sec;
else
last_rtc_update = xtime.tv_sec - 600;
} else if (xtime.tv_usec <= ((unsigned) tick) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
} else {
last_rtc_update = xtime.tv_sec - 600;
/* do it again in 60 s */
}
}
write_sequnlock(&xtime_lock);
irq_exit();
if (softirq_pending(cpu))
do_softirq();
}
unsigned long inline do_gettimeoffset(void)
unsigned long ip27_do_gettimeoffset(void)
{
unsigned long ct_cur1;
ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
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(). */
#include <asm/sn/types.h>
#include <asm/sn/sn0/addrs.h>
......@@ -231,22 +173,24 @@ static __init unsigned long get_m48t35_time(void)
year = rtc->year;
rtc->control &= ~M48T35_RTC_READ;
BCD_TO_BIN(sec);
BCD_TO_BIN(min);
BCD_TO_BIN(hour);
BCD_TO_BIN(date);
BCD_TO_BIN(month);
BCD_TO_BIN(year);
sec = BCD2BIN(sec);
min = BCD2BIN(min);
hour = BCD2BIN(hour);
date = BCD2BIN(date);
month = BCD2BIN(month);
year = BCD2BIN(year);
year += 1970;
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_usec = 0;
xtime.tv_nsec = 0;
do_gettimeoffset = ip27_do_gettimeoffset;
}
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);
set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK);
set_c0_status(SRB_TIMOCLK);
}
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 @@
* Bridge address map
*/
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
#ifndef __ASSEMBLY__
/*
* All accesses to bridge hardware registers must be done
......@@ -283,7 +283,7 @@ typedef struct bridge_err_cmdword_s {
} bridge_err_cmdword_t;
#define berr_field berr_un.berr_st
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/*
* The values of these macros can and should be crosschecked
......@@ -793,7 +793,7 @@ typedef struct bridge_err_cmdword_s {
#define PCI64_ATTR_RMF_MASK 0x00ff000000000000
#define PCI64_ATTR_RMF_SHFT 48
#if LANGUAGE_C
#ifndef __ASSEMBLY__
/* Address translation entry for mapped pci32 accesses */
typedef union ate_u {
u64 ent;
......@@ -809,7 +809,7 @@ typedef union ate_u {
u64 valid:1;
} field;
} ate_t;
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#define ATE_V 0x01
#define ATE_CO 0x02
......
......@@ -11,9 +11,9 @@
#include <linux/config.h>
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
#include <linux/types.h>
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#include <asm/addrspace.h>
#include <asm/reg.h>
......@@ -26,7 +26,7 @@
#endif
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
#if defined(CONFIG_SGI_IO) /* FIXME */
#define PS_UINT_CAST (__psunsigned_t)
......@@ -38,13 +38,13 @@
#define HUBREG_CAST (volatile hubreg_t *)
#elif _LANGUAGE_ASSEMBLY
#else /* __ASSEMBLY__ */
#define PS_UINT_CAST
#define UINT64_CAST
#define HUBREG_CAST
#endif
#endif /* __ASSEMBLY__ */
#define NASID_GET_META(_n) ((_n) >> NASID_LOCAL_BITS)
......@@ -278,7 +278,7 @@
0x800000 + (_x)))
#endif /* CONFIG_SGI_IP27 */
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
#define HUB_L(_a) *(_a)
#define HUB_S(_a, _d) *(_a) = (_d)
......@@ -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_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
......@@ -367,7 +367,7 @@
#define KLI_KERN_XP 8
#define KLI_KERN_PARTID 9
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
#define KLD_BASE(nasid) ((kldir_ent_t *) KLDIR_ADDR(nasid))
#define KLD_LAUNCH(nasid) (KLD_BASE(nasid) + KLI_LAUNCH)
......@@ -453,7 +453,7 @@
#define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET)
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_SN_ADDRS_H */
......@@ -20,7 +20,7 @@
#endif
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
#ifndef __ASSEMBLY__
#if !defined(CONFIG_SGI_IO)
typedef u64 hubreg_t;
typedef u64 nic_t;
......@@ -44,7 +44,7 @@ typedef u64 nic_t;
#define makespnum(_nasid, _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_CNODEID (cnodeid_t)-1
......@@ -102,7 +102,7 @@ nasid_t compact_to_nasid_nodeid(cnodeid_t cnode);
extern int node_getlastslot(cnodeid_t);
#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */
#endif /* !__ASSEMBLY__ */
#define SLOT_BITMASK (MAX_MEM_SLOTS - 1)
#define SLOT_SIZE (1LL<<SLOT_SHIFT)
......
......@@ -41,7 +41,7 @@
#define G_PARTIDOFF 40
#define G_TABLEOFF 128
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef struct gda {
u32 g_magic; /* GDA magic number */
......@@ -67,7 +67,7 @@ typedef struct gda {
#define GDA ((gda_t*) GDA_ADDR(get_nasid()))
#endif /* __LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/*
* Define: PART_GDA_VERSION
* Purpose: Define the minimum version of the GDA required, lower
......
......@@ -19,7 +19,7 @@
#include <asm/sn/intr_public.h>
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
/*
* Macros to manipulate the interrupt register on the calling hub chip.
......@@ -43,9 +43,9 @@
REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (_level)), \
REMOTE_HUB_L((_hub), PI_INT_PEND0)
#else /* LANGUAGE_ASSEMBLY */
#else /* __ASSEMBLY__ */
#endif /* LANGUAGE_C */
#endif /* __ASSEMBLY__ */
/*
* Hard-coded interrupt levels:
......
......@@ -20,7 +20,7 @@
#define INTPEND0_MAXMASK (N_INTPEND0_MASKS - 1)
#define INTPEND1_MAXMASK (N_INTPEND1_MASKS - 1)
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
#include <asm/sn/arch.h>
struct intr_vecblk_s; /* defined in asm/sn/intr.h */
......@@ -49,5 +49,5 @@ typedef struct hub_intmasks_s {
struct intr_vecblk_s *dispatch1;
} hub_intmasks_t;
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_SN_INTR_PUBLIC_H */
......@@ -11,17 +11,7 @@
#include <linux/config.h>
#if !defined(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 */
#ifdef CONFIG_SGI_IO
#define IIO_ITTE_BASE 0x400160 /* base of translation table entries */
#define IIO_ITTE(bigwin) (IIO_ITTE_BASE + 8*(bigwin))
......@@ -69,6 +59,17 @@
#include <asm/sn/sn0/hubio.h>
#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 /* _ASM_SN_IO_H */
......@@ -127,14 +127,14 @@
* 0x0 (0K) +-----------------------------------------+
*/
#ifdef LANGUAGE_ASSEMBLY
#ifdef __ASSEMBLY__
#define KLDIR_OFF_MAGIC 0x00
#define KLDIR_OFF_OFFSET 0x08
#define KLDIR_OFF_POINTER 0x10
#define KLDIR_OFF_SIZE 0x18
#define KLDIR_OFF_COUNT 0x20
#define KLDIR_OFF_STRIDE 0x28
#endif /* LANGUAGE_ASSEMBLY */
#endif /* __ASSEMBLY__ */
#if !defined(CONFIG_SGI_IO)
......@@ -209,7 +209,7 @@
#endif /* !CONFIG_SGI_IO */
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef struct kldir_ent_s {
u64 magic; /* Indicates validity of entry */
off_t offset; /* Offset from start of node space */
......@@ -225,7 +225,7 @@ typedef struct kldir_ent_s {
/* NOTE: These 16 bytes are used in the Partition KLDIR
entry to store partition info. Refer to klpart.h for this. */
} kldir_ent_t;
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#if defined(CONFIG_SGI_IO)
......
......@@ -11,7 +11,7 @@
#define KV_MAGIC 0x5f4b565f
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
#include <asm/sn/types.h>
......@@ -23,7 +23,7 @@ typedef struct kern_vars_s {
unsigned long kv_rw_baseaddr;
} kern_vars_t;
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_SN_KLKERNVARS_H */
......@@ -60,7 +60,7 @@
* clears the BUSY flag after control is returned to it.
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef int launch_state_t;
typedef void (*launch_proc_t)(u64 call_parm);
......@@ -102,21 +102,6 @@ typedef struct launch_s {
#define LAUNCH_FLASH (*(void (*)(void)) \
IP27PROM_FLASHLEDS)
#ifdef _STANDALONE
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 /* !__ASSEMBLY__ */
#endif /* _ASM_SN_LAUNCH_H */
......@@ -8,7 +8,7 @@
#ifndef __ASM_SN_NMI_H
#define __ASM_SN_NMI_H
#ident "$Revision: 1.2 $"
#ident "$Revision: 1.5 $"
#include <asm/sn/addrs.h>
......@@ -48,7 +48,7 @@
*
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef struct nmi_s {
volatile unsigned long magic; /* Magic number */
......@@ -59,13 +59,13 @@ typedef struct nmi_s {
volatile unsigned long gmaster; /* Flag true only on global master*/
} nmi_t;
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/* Following definitions are needed both in the prom & the kernel
* to identify the format of the nmi cpu register save area in the
* low memory on each node.
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
struct reg_struct {
unsigned long gpr[32];
......@@ -78,7 +78,7 @@ struct reg_struct {
unsigned long nmi_sr;
};
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/* These are the assembly language offsets into the reg_struct structure */
......
......@@ -99,14 +99,15 @@
#define NASID_GET(_pa) (int) ((UINT64_CAST (_pa) >> \
NASID_SHFT) & NASID_BITMASK)
#if _LANGUAGE_C && !defined(_STANDALONE)
#if !defined(__ASSEMBLY__) && !defined(_STANDALONE)
#define NODE_SWIN_BASE(nasid, widget) \
((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN) \
: RAW_NODE_SWIN_BASE(nasid, widget))
#else
#else /* __ASSEMBLY__ || _STANDALONE */
#define NODE_SWIN_BASE(nasid, widget) \
(NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
#endif /* _LANGUAGE_C */
#endif /* __ASSEMBLY__ || _STANDALONE */
/*
* The following definitions pertain to the IO special address
......@@ -163,11 +164,11 @@
#define SABLE_LOG_TRIGGER(_map)
#endif /* SABLE */
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
#define KERN_NMI_ADDR(nasid, slice) \
TO_NODE_UNCAC((nasid), IP27_NMI_KREGS_OFFSET + \
(IP27_NMI_KREGS_CPU_SIZE * (slice)))
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#ifdef PROM
......@@ -272,7 +273,8 @@
#define KL_UART_DATA LOCAL_HUB_ADDR(MD_UREG0_1) /* UART data reg */
#define KL_I2C_REG MD_UREG0_0 /* I2C reg */
#if !_LANGUAGE_ASSEMBLY
#ifndef __ASSEMBLY__
/* Address 0x400 to 0x1000 ualias points to cache error eframe + misc
* CACHE_ERR_SP_PTR could either contain an address to the stack, or
* the stack could start at CACHE_ERR_SP_PTR
......@@ -289,7 +291,7 @@
#define CACHE_ERR_SP (CACHE_ERR_SP_PTR - 16)
#define CACHE_ERR_AREA_SIZE (ARCS_SPB_OFFSET - CACHE_ERR_EFRAME)
#endif /* !_LANGUAGE_ASSEMBLY */
#endif /* !__ASSEMBLY__ */
#define _ARCSPROM
......@@ -314,7 +316,7 @@
* is in place.
*/
#if _LANGUAGE_C
#ifndef __ASSEMBLY__
#define uchar unsigned char
......@@ -359,7 +361,7 @@
#define PUT_INSTALL_STATUS(c,s) c->Revision = s
#define GET_INSTALL_STATUS(c) c->Revision
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#endif /* _STANDALONE */
......
......@@ -169,7 +169,7 @@
/*
* The IO LLP control status register and widget control register
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union hubii_wid_u {
u64 wid_reg_value;
......@@ -292,7 +292,7 @@ typedef union io_perf_cnt {
} perf_cnt_bits;
} io_perf_cnt_t;
#endif
#endif /* !__ASSEMBLY__ */
#define LNK_STAT_WORKING 0x2
......@@ -440,7 +440,7 @@ typedef union io_perf_cnt {
/*
* Fields in CRB Register A
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union icrba_u {
u64 reg_value;
struct {
......@@ -500,7 +500,7 @@ typedef union h1_icrba_u {
#define a_valid icrba_fields_s.valid
#define a_iow icrba_fields_s.iow
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#define IIO_ICRB_ADDR_SHFT 2 /* Shift to get proper address */
......@@ -523,7 +523,7 @@ typedef union h1_icrba_u {
/*
* Fields in CRB Register B
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union icrbb_u {
u64 reg_value;
struct {
......@@ -622,7 +622,7 @@ typedef union h1_icrbb_u {
#define b_imsg icrbb_field_s.imsg
#define b_initiator icrbb_field_s.initiator
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/*
* values for field xtsize
......@@ -680,7 +680,7 @@ typedef union h1_icrbb_u {
* Fields in CRB Register C
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union icrbc_s {
u64 reg_value;
......@@ -712,13 +712,13 @@ typedef union icrbc_s {
#define c_barrop icrbc_field_s.barrop
#define c_doresp icrbc_field_s.doresp
#define c_gbr icrbc_field_s.gbr
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/*
* Fields in CRB Register D
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union icrbd_s {
u64 reg_value;
struct {
......@@ -751,7 +751,7 @@ typedef union hubii_ifdr_u {
} hi_ifdr_fields;
} hubii_ifdr_t;
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/*
* Hardware designed names for the BTE control registers.
......@@ -798,7 +798,7 @@ typedef union hubii_ifdr_u {
* IO PIO Read Table Entry format
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union iprte_a {
u64 entry;
......@@ -820,7 +820,7 @@ typedef union iprte_a {
#define iprte_init iprte_fields.initiator
#define iprte_addr iprte_fields.addr
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#define IPRTE_ADDRSHFT 3
......@@ -828,7 +828,7 @@ typedef union iprte_a {
* Hub IIO PRB Register format.
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
/*
* Note: Fields bnakctr, anakctr, xtalkctrmode, ovflow fields are
* "Status" fields, and should only be used in case of clean up after errors.
......@@ -860,7 +860,7 @@ typedef union iprb_u {
#define iprb_anakctr iprb_fields_s.anakctr
#define iprb_xtalkctr iprb_fields_s.xtalkctr
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/*
* values for mode field in iprb_t.
......@@ -875,7 +875,7 @@ typedef union iprb_u {
/*
* IO CRB entry C_A to E_A : Partial (cache) CRBS
*/
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union icrbp_a {
u64 ip_reg; /* the entire register value */
struct {
......@@ -909,7 +909,7 @@ typedef union icrbp_a {
} ip_fmt;
} icrbp_a_t;
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/*
* A couple of defines to go with the above structure.
......@@ -917,7 +917,7 @@ typedef union icrbp_a {
#define ICRBP_A_CERR_SHFT 54
#define ICRBP_A_ERR_MASK 0x3ff
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union hubii_idsr {
u64 iin_reg;
struct {
......@@ -931,7 +931,7 @@ typedef union hubii_idsr {
level : 7;
} iin_fmt;
} hubii_idsr_t;
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/*
* IO BTE Length/Status (IIO_IBLS) register bit field definitions
......
......@@ -424,8 +424,7 @@
* Operations on page migration threshold register
*/
#if _LANGUAGE_C
#ifndef _STANDALONE
#ifndef __ASSEMBLY__
/*
* LED register macros
......@@ -538,8 +537,6 @@
#define MD_SPROT_MIGMD_GET(value) ( \
((value) & MD_SPROT_MIGMD_MASK) >> MD_SPROT_MIGMD_SHFT)
#endif /* _STANDALONE */
/*
* Format of dir_error, mem_error, protocol_error and misc_error registers
*/
......@@ -739,7 +736,7 @@ typedef union md_perf_cnt {
} md_perf_cnt_t;
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#define DIR_ERROR_VALID_MASK 0xe000000000000000
......
......@@ -11,7 +11,7 @@
#ifndef _ASM_SGI_SN0_HUBNI_H
#define _ASM_SGI_SN0_HUBNI_H
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
#include <linux/types.h>
#endif
......@@ -226,7 +226,7 @@
#define NLT_EXIT_PORT_MASK (UINT64_CAST 0xf)
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
typedef union hubni_port_error_u {
u64 nipe_reg_value;
......@@ -250,6 +250,6 @@ typedef union hubni_port_error_u {
#define NI_LLP_CB_MAX 0xff
#define NI_LLP_SN_MAX 0xff
#endif /* LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_SGI_SN0_HUBNI_H */
......@@ -306,7 +306,7 @@
#define ERR_STACK_SIZE_BYTES(_sz) \
((_sz) ? (PI_MIN_STACK_SIZE << ((_sz) - 1)) : 0)
#ifdef _LANGUAGE_C
#ifndef __ASSEMBLY__
/*
* format of error stack and error status registers.
*/
......@@ -359,7 +359,7 @@ typedef union pi_err_stat1 {
typedef u64 rtc_time_t;
#endif /* _LANGUAGE_C */
#endif /* !__ASSEMBLY__ */
/* Bits in PI_SYSAD_ERRCHK_EN */
......
......@@ -19,7 +19,7 @@
#define TLBLO_HWBITSHIFT 0 /* Shift value, for masking */
#if !_LANGUAGE_ASSEMBLY
#ifndef __ASSEMBLY__
#define CAUSE_BERRINTR IE_IRQ5
......@@ -30,9 +30,9 @@
#define ECCF_PADDR 4
#define ECCF_SIZE (5 * sizeof(long))
#endif /* !_LANGUAGE_ASSEMBLY */
#endif /* !__ASSEMBLY__ */
#if _LANGUAGE_ASSEMBLY
#ifdef __ASSEMBLY__
/*
* KL_GET_CPUNUM (similar to EV_GET_SPNUM for EVEREST platform) reads
......@@ -43,7 +43,7 @@
dli proc, LOCAL_HUB(0); \
ld proc, PI_CPU_NUM(proc)
#endif /* _LANGUAGE_ASSEMBLY */
#endif /* __ASSEMBLY__ */
/*
* R10000 status register interrupt bit mask usage for IP27.
......
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