sys_nautilus.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:14k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/alpha/kernel/sys_nautilus.c
  3.  *
  4.  * Copyright (C) 1995 David A Rusling
  5.  * Copyright (C) 1998 Richard Henderson
  6.  * Copyright (C) 1999 Alpha Processor, Inc.,
  7.  * (David Daniel, Stig Telfer, Soohoon Lee)
  8.  *
  9.  * Code supporting NAUTILUS systems.
  10.  *
  11.  *
  12.  * NAUTILUS has the following I/O features:
  13.  *
  14.  * a) Driven by AMD 751 aka IRONGATE (northbridge):
  15.  *     4 PCI slots
  16.  *     1 AGP slot
  17.  *
  18.  * b) Driven by ALI M1543C (southbridge)
  19.  *     2 ISA slots
  20.  *     2 IDE connectors
  21.  *     1 dual drive capable FDD controller
  22.  *     2 serial ports
  23.  *     1 ECP/EPP/SP parallel port
  24.  *     2 USB ports
  25.  */
  26. #include <linux/kernel.h>
  27. #include <linux/types.h>
  28. #include <linux/mm.h>
  29. #include <linux/sched.h>
  30. #include <linux/pci.h>
  31. #include <linux/init.h>
  32. #include <linux/reboot.h>
  33. #include <asm/ptrace.h>
  34. #include <asm/system.h>
  35. #include <asm/dma.h>
  36. #include <asm/irq.h>
  37. #include <asm/bitops.h>
  38. #include <asm/mmu_context.h>
  39. #include <asm/io.h>
  40. #include <asm/pci.h>
  41. #include <asm/pgtable.h>
  42. #include <asm/core_irongate.h>
  43. #include <asm/hwrpb.h>
  44. #include "proto.h"
  45. #include "irq_impl.h"
  46. #include "pci_impl.h"
  47. #include "machvec_impl.h"
  48. static void __init
  49. nautilus_init_irq(void)
  50. {
  51. if (alpha_using_srm) {
  52. alpha_mv.device_interrupt = srm_device_interrupt;
  53. }
  54. init_i8259a_irqs();
  55. common_init_isa_dma();
  56. }
  57. static int __init
  58. nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  59. {
  60. /* Preserve the IRQ set up by the console.  */
  61. u8 irq;
  62. pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
  63. return irq;
  64. }
  65. void
  66. nautilus_kill_arch(int mode)
  67. {
  68. switch (mode) {
  69. case LINUX_REBOOT_CMD_RESTART:
  70. if (! alpha_using_srm) {
  71. u8 t8;
  72. pcibios_read_config_byte(0, 0x38, 0x43, &t8);
  73. pcibios_write_config_byte(0, 0x38, 0x43, t8 | 0x80);
  74. outb(1, 0x92);
  75. outb(0, 0x92);
  76. /* NOTREACHED */
  77. }
  78. break;
  79. case LINUX_REBOOT_CMD_POWER_OFF:
  80. {
  81. u32 pmuport;
  82. pcibios_read_config_dword(0, 0x88, 0x10, &pmuport);
  83. pmuport &= 0xfffe;
  84. outl(0xffff, pmuport); /* clear pending events */
  85. outw(0x2000, pmuport+4); /* power off */
  86. /* NOTREACHED */
  87. }
  88. break;
  89. }
  90. }
  91. /* Machine check handler code
  92.  *
  93.  * Perform analysis of a machine check that was triggered by the EV6
  94.  * CPU's fault-detection mechanism.
  95.  */
  96. /* IPR structures for EV6, containing the necessary data for the
  97.  * machine check handler to unpick the logout frame
  98.  */
  99. /* I_STAT */
  100. #define EV6__I_STAT__PAR                ( 1 << 29 )
  101. /* MM_STAT */
  102. #define EV6__MM_STAT__DC_TAG_PERR       ( 1 << 10 )
  103. /* DC_STAT */
  104. #define EV6__DC_STAT__SEO               ( 1 << 4 )
  105. #define EV6__DC_STAT__ECC_ERR_LD        ( 1 << 3 )
  106. #define EV6__DC_STAT__ECC_ERR_ST        ( 1 << 2 )
  107. #define EV6__DC_STAT__TPERR_P1          ( 1 << 1 )
  108. #define EV6__DC_STAT__TPERR_P0          ( 1      )
  109. /* C_STAT */
  110. #define EV6__C_STAT__BC_PERR            ( 0x01 )
  111. #define EV6__C_STAT__DC_PERR            ( 0x02 )
  112. #define EV6__C_STAT__DSTREAM_MEM_ERR    ( 0x03 )
  113. #define EV6__C_STAT__DSTREAM_BC_ERR     ( 0x04 )
  114. #define EV6__C_STAT__DSTREAM_DC_ERR     ( 0x05 )
  115. #define EV6__C_STAT__PROBE_BC_ERR0      ( 0x06 )
  116. #define EV6__C_STAT__PROBE_BC_ERR1      ( 0x07 )
  117. #define EV6__C_STAT__ISTREAM_MEM_ERR    ( 0x0B )
  118. #define EV6__C_STAT__ISTREAM_BC_ERR     ( 0x0C )
  119. #define EV6__C_STAT__DSTREAM_MEM_DBL    ( 0x13 )
  120. #define EV6__C_STAT__DSTREAM_BC_DBL     ( 0x14 )
  121. #define EV6__C_STAT__ISTREAM_MEM_DBL    ( 0x1B )
  122. #define EV6__C_STAT__ISTREAM_BC_DBL     ( 0x1C )
  123. /* Take the two syndromes from the CBOX error chain and convert them
  124.  * into a bit number.  */
  125. /* NOTE - since I don't know of any difference between C0 and C1 I
  126.    just ignore C1, since in all cases I've seen so far they are
  127.    identical.  */
  128. static const unsigned char ev6_bit_to_syndrome[72] =
  129. {
  130. 0xce, 0xcb, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc,     /* 0 */
  131. 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34,     /* 8 */
  132. 0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,     /* 16 */
  133. 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xf1, 0xf4,     /* 24 */
  134. 0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d,     /* 32 */
  135. 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xb0, 0xb5,     /* 40 */
  136. 0x8f, 0x8a, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d,     /* 48 */
  137. 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75,     /* 56 */
  138. 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80      /* 64 */
  139. };
  140. static int ev6_syn2bit(unsigned long c0, unsigned long c1)
  141. {
  142. int bit;
  143. for (bit = 0; bit < 72; bit++)
  144. if (ev6_bit_to_syndrome[bit] == c0) return bit;
  145. for (bit = 0; bit < 72; bit++)
  146. if (ev6_bit_to_syndrome[bit] == c1) return bit + 64;
  147. return -1;                  /* not found */
  148. }
  149. /* Single bit ECC errors are categorized here.  */
  150. #if 0
  151. static const char *interr = "CPU internal error";
  152. static const char *slotb= "Slot-B error";
  153. static const char *membus= "Memory/EV6-bus error";
  154. #else
  155. static const char *interr = "";
  156. static const char *slotb = "";
  157. static const char *membus = "";
  158. #endif
  159. static void
  160. ev6_crd_interp(char *interp, struct el_common_EV6_mcheck * L)
  161. {
  162. /* Icache data or tag parity error.  */
  163. if (L->I_STAT & EV6__I_STAT__PAR) {
  164. sprintf(interp, "%s: I_STAT[PAR]n "
  165. "Icache data or tag parity error", interr);
  166. return;
  167. }
  168. /* Dcache tag parity error (on issue) (DFAULT).  */
  169. if (L->MM_STAT & EV6__MM_STAT__DC_TAG_PERR) {
  170. sprintf(interp, "%s: MM_STAT[DC_TAG_PERR]n "
  171. "Dcache tag parity error(on issue)", interr);
  172. return;
  173. }
  174. /* Errors relating to D-stream set non-zero DC_STAT.
  175.    Mask CRD bits.  */
  176. switch (L->DC_STAT & (EV6__DC_STAT__ECC_ERR_ST
  177.       | EV6__DC_STAT__ECC_ERR_LD)) {
  178. case EV6__DC_STAT__ECC_ERR_ST:
  179. /* Dcache single-bit ECC error on small store */
  180. sprintf(interp, "%s: DC_STAT[ECC_ERR_ST]n "
  181. "Dcache single-bit ECC error on small store", interr);
  182. return;
  183. case EV6__DC_STAT__ECC_ERR_LD:
  184. switch (L->C_STAT) {
  185. case 0:
  186. /* Dcache single-bit error on speculative load */
  187. /* Bcache victim read on Dcache/Bcache miss */
  188. sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT=0n "
  189. "Dcache single-bit ECC error on speculative load",
  190. slotb);
  191. return;
  192. case EV6__C_STAT__DSTREAM_DC_ERR:
  193. /* Dcache single bit error on load */
  194. sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_DC_ERR]n"
  195. " Dcache single-bit ECC error on speculative load, bit %d",
  196. interr, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
  197. return;
  198. case EV6__C_STAT__DSTREAM_BC_ERR:
  199. /* Bcache single-bit error on Dcache fill */
  200. sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_BC_ERR]n"
  201. " Bcache single-bit error on Dcache fill, bit %d",
  202. slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
  203. return;
  204. case EV6__C_STAT__DSTREAM_MEM_ERR:
  205. /* Memory single-bit error on Dcache fill */
  206. sprintf(interp, "%s (to Dcache): DC_STAT[ECC_ERR_LD] "
  207. "C_STAT[DSTREAM_MEM_ERR]n "
  208. "Memory single-bit error on Dcache fill, "
  209. "Address 0x%lX, bit %d",
  210. membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
  211.        L->DC1_SYNDROME));
  212. return;
  213. }
  214. }
  215. /* I-stream, other misc errors go on C_STAT alone */
  216. switch (L->C_STAT) {
  217. case EV6__C_STAT__ISTREAM_BC_ERR:
  218. /* Bcache single-bit error on Icache fill (also MCHK) */
  219. sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]n "
  220. "Bcache single-bit error on Icache fill, bit %d",
  221. slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
  222. return;
  223. case EV6__C_STAT__ISTREAM_MEM_ERR:
  224. /* Memory single-bit error on Icache fill (also MCHK) */
  225. sprintf(interp, "%s : C_STATISTREAM_MEM_ERR]n "
  226. "Memory single-bit error on Icache fill "
  227. "addr 0x%lX, bit %d",
  228. membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
  229.        L->DC1_SYNDROME));
  230. return;
  231. case EV6__C_STAT__PROBE_BC_ERR0:
  232. case EV6__C_STAT__PROBE_BC_ERR1:
  233. /* Bcache single-bit error on a probe hit */
  234. sprintf(interp, "%s: C_STAT[PROBE_BC_ERR]n "
  235. "Bcache single-bit error on a probe hit, "
  236. "addr 0x%lx, bit %d",
  237. slotb, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
  238.       L->DC1_SYNDROME));
  239. return;
  240. }
  241. }
  242. static void
  243. ev6_mchk_interp(char *interp, struct el_common_EV6_mcheck * L)
  244. {
  245. /* Machine check errors described by DC_STAT */
  246. switch (L->DC_STAT) {
  247. case EV6__DC_STAT__TPERR_P0:
  248. case EV6__DC_STAT__TPERR_P1:
  249. /* Dcache tag parity error (on retry) */
  250. sprintf(interp, "%s: DC_STAT[TPERR_P0|TPERR_P1]n "
  251. "Dcache tag parity error(on retry)", interr);
  252. return;
  253. case EV6__DC_STAT__SEO:
  254. /* Dcache second error on store */
  255. sprintf(interp, "%s: DC_STAT[SEO]n "
  256. "Dcache second error during mcheck", interr);
  257. return;
  258. }
  259. /* Machine check errors described by C_STAT */
  260. switch (L->C_STAT) {
  261. case EV6__C_STAT__DC_PERR:
  262. /* Dcache duplicate tag parity error */
  263. sprintf(interp, "%s: C_STAT[DC_PERR]n "
  264. "Dcache duplicate tag parity error at 0x%lX",
  265. interr, L->C_ADDR);
  266. return;
  267. case EV6__C_STAT__BC_PERR:
  268. /* Bcache tag parity error */
  269. sprintf(interp, "%s: C_STAT[BC_PERR]n "
  270. "Bcache tag parity error at 0x%lX",
  271. slotb, L->C_ADDR);
  272. return;
  273. case EV6__C_STAT__ISTREAM_BC_ERR:
  274. /* Bcache single-bit error on Icache fill (also CRD) */
  275. sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]n "
  276. "Bcache single-bit error on Icache fill 0x%lX bit %d",
  277. slotb, L->C_ADDR,
  278. ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
  279. return;
  280. case EV6__C_STAT__ISTREAM_MEM_ERR:
  281. /* Memory single-bit error on Icache fill (also CRD) */
  282. sprintf(interp, "%s: C_STAT[ISTREAM_MEM_ERR]n "
  283. "Memory single-bit error on Icache fill 0x%lX, bit %d",
  284. membus, L->C_ADDR,
  285. ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
  286. return;
  287. case EV6__C_STAT__ISTREAM_BC_DBL:
  288. /* Bcache double-bit error on Icache fill */
  289. sprintf(interp, "%s: C_STAT[ISTREAM_BC_DBL]n "
  290. "Bcache double-bit error on Icache fill at 0x%lX",
  291. slotb, L->C_ADDR);
  292. return;
  293. case EV6__C_STAT__DSTREAM_BC_DBL:
  294. /* Bcache double-bit error on Dcache fill */
  295. sprintf(interp, "%s: C_STAT[DSTREAM_BC_DBL]n "
  296. "Bcache double-bit error on Dcache fill at 0x%lX",
  297. slotb, L->C_ADDR);
  298. return;
  299. case EV6__C_STAT__ISTREAM_MEM_DBL:
  300. /* Memory double-bit error on Icache fill */
  301. sprintf(interp, "%s: C_STAT[ISTREAM_MEM_DBL]n "
  302. "Memory double-bit error on Icache fill at 0x%lX",
  303. membus, L->C_ADDR);
  304. return;
  305. case EV6__C_STAT__DSTREAM_MEM_DBL:
  306. /* Memory double-bit error on Dcache fill */
  307. sprintf(interp, "%s: C_STAT[DSTREAM_MEM_DBL]n "
  308. "Memory double-bit error on Dcache fill at 0x%lX",
  309. membus, L->C_ADDR);
  310. return;
  311. }
  312. }
  313. static void
  314. ev6_cpu_machine_check(unsigned long vector, struct el_common_EV6_mcheck *L,
  315.       struct pt_regs *regs)
  316. {
  317. char interp[80];
  318. /* This is verbose and looks intimidating.  Should it be printed for
  319.    corrected (CRD) machine checks? */
  320. printk(KERN_CRIT "PALcode logout frame:  "
  321.        "MCHK_Code       %d  "
  322.        "MCHK_Frame_Rev  %dn"
  323.        "I_STAT  %016lx  "
  324.        "DC_STAT %016lx  "
  325.        "C_ADDR  %016lxn"
  326.        "SYND1   %016lx  "
  327.        "SYND0   %016lx  "
  328.        "C_STAT  %016lxn"
  329.        "C_STS   %016lx  "
  330.        "RES     %016lx  "
  331.        "EXC_ADDR%016lxn"
  332.        "IER_CM  %016lx  "
  333.        "ISUM    %016lx  "
  334.        "MM_STAT %016lxn"
  335.        "PALBASE %016lx  "
  336.        "I_CTL   %016lx  "
  337.        "PCTX    %016lxn"
  338.        "CPU registers: "
  339.        "PC      %016lx  "
  340.        "Return  %016lxn",
  341.        L->MCHK_Code, L->MCHK_Frame_Rev, L->I_STAT, L->DC_STAT,
  342.        L->C_ADDR, L->DC1_SYNDROME, L->DC0_SYNDROME, L->C_STAT,
  343.        L->C_STS, L->RESERVED0, L->EXC_ADDR, L->IER_CM, L->ISUM,
  344.        L->MM_STAT, L->PAL_BASE, L->I_CTL, L->PCTX,
  345.        regs->pc, regs->r26);
  346. /* Attempt an interpretation on the meanings of the fields above.  */
  347. sprintf(interp, "No interpretation available!" );
  348. if (vector == SCB_Q_PROCERR)
  349. ev6_crd_interp(interp, L);
  350. else if (vector == SCB_Q_PROCMCHK)
  351. ev6_mchk_interp(interp, L);
  352. printk(KERN_CRIT "interpretation: %snn", interp);
  353. }
  354. /* Perform analysis of a machine check that arrived from the system (NMI) */
  355. static void
  356. naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
  357.        struct pt_regs *regs)
  358. {
  359. printk("xtime %lxn", CURRENT_TIME);
  360. printk("PC %lx RA %lxn", regs->pc, regs->r26);
  361. irongate_pci_clr_err();
  362. }
  363. /* Machine checks can come from two sources - those on the CPU and those
  364.    in the system.  They are analysed separately but all starts here.  */
  365. void
  366. nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
  367.        struct pt_regs *regs)
  368. {
  369. char *mchk_class;
  370. unsigned cpu_analysis=0, sys_analysis=0;
  371. /* Now for some analysis.  Machine checks fall into two classes --
  372.    those picked up by the system, and those picked up by the CPU.
  373.    Add to that the two levels of severity - correctable or not.  */
  374. if (vector == SCB_Q_SYSMCHK
  375.     && ((IRONGATE0->dramms & 0x300) == 0x300)) {
  376. unsigned long nmi_ctl;
  377. /* Clear ALI NMI */
  378. nmi_ctl = inb(0x61);
  379. nmi_ctl |= 0x0c;
  380. outb(nmi_ctl, 0x61);
  381. nmi_ctl &= ~0x0c;
  382. outb(nmi_ctl, 0x61);
  383. /* Write again clears error bits.  */
  384. IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;
  385. mb();
  386. IRONGATE0->stat_cmd;
  387. /* Write again clears error bits.  */
  388. IRONGATE0->dramms = IRONGATE0->dramms;
  389. mb();
  390. IRONGATE0->dramms;
  391. draina();
  392. wrmces(0x7);
  393. mb();
  394. return;
  395. }
  396. switch (vector) {
  397. case SCB_Q_SYSERR:
  398. mchk_class = "Correctable System Machine Check (NMI)";
  399. sys_analysis = 1;
  400. break;
  401. case SCB_Q_SYSMCHK:
  402. mchk_class = "Fatal System Machine Check (NMI)";
  403. sys_analysis = 1;
  404. break;
  405. case SCB_Q_PROCERR:
  406. mchk_class = "Correctable Processor Machine Check";
  407. cpu_analysis = 1;
  408. break;
  409. case SCB_Q_PROCMCHK:
  410. mchk_class = "Fatal Processor Machine Check";
  411. cpu_analysis = 1;
  412. break;
  413. default:
  414. mchk_class = "Unknown vector!";
  415. break;
  416. }
  417. printk(KERN_CRIT "NAUTILUS Machine check 0x%lx [%s]n",
  418.        vector, mchk_class);
  419. if (cpu_analysis)
  420. ev6_cpu_machine_check(vector,
  421.       (struct el_common_EV6_mcheck *)la_ptr,
  422.       regs);
  423. if (sys_analysis)
  424. naut_sys_machine_check(vector, la_ptr, regs);
  425. /* Tell the PALcode to clear the machine check */
  426. draina();
  427. wrmces(0x7);
  428. mb();
  429. }
  430. /*
  431.  * The System Vectors
  432.  */
  433. struct alpha_machine_vector nautilus_mv __initmv = {
  434. vector_name: "Nautilus",
  435. DO_EV6_MMU,
  436. DO_DEFAULT_RTC,
  437. DO_IRONGATE_IO,
  438. DO_IRONGATE_BUS,
  439. machine_check: nautilus_machine_check,
  440. max_dma_address: ALPHA_NAUTILUS_MAX_DMA_ADDRESS,
  441. min_io_address: DEFAULT_IO_BASE,
  442. min_mem_address: IRONGATE_DEFAULT_MEM_BASE,
  443. nr_irqs: 16,
  444. device_interrupt: isa_device_interrupt,
  445. init_arch: irongate_init_arch,
  446. init_irq: nautilus_init_irq,
  447. init_rtc: common_init_rtc,
  448. init_pci: common_init_pci,
  449. kill_arch: nautilus_kill_arch,
  450. pci_map_irq: nautilus_map_irq,
  451. pci_swizzle: common_swizzle,
  452. };
  453. ALIAS_MV(nautilus)