mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-05 10:37:31 +02:00
157 lines
4.4 KiB
COBOL
157 lines
4.4 KiB
COBOL
#pypp 0
|
|
// Iris: micro-kernel for a capability-based operating system.
|
|
// interrupts.ccp: Functions called by mips/entry.S.
|
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
|
//
|
|
// 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 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#define ARCH
|
|
#include "../kernel.hh"
|
|
|
|
/// A TLB miss has occurred. This is the slow version. It is only used
|
|
/// when k0 or k1 is not 0, or when an error occurs.
|
|
/// Otherwise, the ultra-fast code in entry.S is used.
|
|
Thread *tlb_refill ():
|
|
//panic (0x88776655, "TLB refill")
|
|
if !directory:
|
|
panic (0x44449999, "No directory")
|
|
unsigned EntryHi
|
|
cp0_get (CP0_ENTRY_HI, EntryHi)
|
|
unsigned *t = directory[EntryHi >> 21]
|
|
if !t:
|
|
unsigned a
|
|
cp0_get (CP0_EPC, a)
|
|
dbg_send (a)
|
|
cp0_get (CP0_BAD_V_ADDR, a)
|
|
dbg_send (a)
|
|
panic (0x99992222, "No page table")
|
|
// - 2 instead of - 1 means reset bit 0
|
|
unsigned idx = (EntryHi >> 12) & ((1 << 9) - 2)
|
|
cp0_set (CP0_ENTRY_LO0, t[idx])
|
|
cp0_set (CP0_ENTRY_LO1, t[idx + 1])
|
|
__asm__ volatile ("tlbwr")
|
|
return current
|
|
|
|
/// An interrupt which is not an exception has occurred.
|
|
Thread *interrupt ():
|
|
panic (0x88877722, "Interrupt")
|
|
unsigned cause, status
|
|
cp0_get (CP0_CAUSE, cause)
|
|
cp0_get (CP0_STATUS, status)
|
|
for unsigned i = 0; i < 8; ++i:
|
|
if cause & (1 << (i + 8)):
|
|
// Disable the interrupt while handling it.
|
|
status &= ~(1 << (i + 8))
|
|
// Send message to interrupt handler.
|
|
if arch_interrupt_receiver[i]:
|
|
Capability::Context c
|
|
for unsigned j = 0; j < 4; ++j:
|
|
c.data[j] = 0
|
|
c.cap[j] = NULL
|
|
c.copy[j] = false
|
|
arch_interrupt_receiver[i]->send_message (i, &c)
|
|
return current
|
|
|
|
/// A general exception has occurred.
|
|
Thread *exception ():
|
|
unsigned cause
|
|
cp0_get (CP0_CAUSE, cause)
|
|
switch (cause >> 2) & 0x1f:
|
|
case 0:
|
|
// Interrupt. This shouldn't happen, since CAUSE[IV] == 1.
|
|
panic (0x11223344, "Interrupt on exception vector.")
|
|
case 1:
|
|
// TLB modification.
|
|
panic (0x21223344, "TLB modification.")
|
|
case 2:
|
|
// TLB load or instruction fetch.
|
|
unsigned a
|
|
cp0_get (CP0_EPC, a)
|
|
dbg_send (a)
|
|
panic (0x31223344, "TLB load or instruction fetch.")
|
|
case 3:
|
|
// TLB store.
|
|
panic (0x41223344, "TLB store.")
|
|
case 4:
|
|
// Address error load or instruction fetch.
|
|
panic (0x51223344, "Address error load or instruction fetch.")
|
|
case 5:
|
|
// Address error store.
|
|
unsigned a
|
|
cp0_get (CP0_EPC, a)
|
|
dbg_send (a, 16)
|
|
panic (0x61223344, "Address error store.")
|
|
case 6:
|
|
// Bus error instruction fetch.
|
|
panic (0x71223344, "Bus error instruction fetch.")
|
|
case 7:
|
|
// Bus error load or store.
|
|
panic (0x81223344, "Bus error load or store.")
|
|
case 8:
|
|
// Syscall.
|
|
current->pc += 4
|
|
arch_invoke ()
|
|
break
|
|
case 9:
|
|
// Breakpoint.
|
|
panic (0x91223344, "Breakpoint.")
|
|
case 10:
|
|
// Reserved instruction.
|
|
panic (0xa1223344, "Reserved instruction.")
|
|
case 11:
|
|
// Coprocessor unusable.
|
|
panic (0xb1223344, "Coprocessor unusable.")
|
|
case 12:
|
|
// Arithmetic overflow.
|
|
panic (0xc1223344, "Arithmetic overflow.")
|
|
case 13:
|
|
// Trap.
|
|
panic (0xe1223344, "Trap.")
|
|
case 15:
|
|
// Floating point exception.
|
|
panic (0xf1223344, "Floating point exception.")
|
|
case 23:
|
|
// Reference to WatchHi/WatchLo address.
|
|
panic (0xf2223344, "Reference to WatchHi/WatchLo address.")
|
|
case 24:
|
|
// Machine check.
|
|
panic (0xf3223344, "Machine check.")
|
|
case 30:
|
|
// Cache error (EJTAG only).
|
|
panic (0xf4223344, "Cache error (EJTAG only).")
|
|
case 14:
|
|
case 16:
|
|
case 17:
|
|
case 18:
|
|
case 19:
|
|
case 20:
|
|
case 21:
|
|
case 22:
|
|
case 25:
|
|
case 26:
|
|
case 27:
|
|
case 28:
|
|
case 29:
|
|
case 31:
|
|
// Reserved.
|
|
panic (0xf5223344, "Reserved exception code")
|
|
default:
|
|
panic (0xf6223344, "Impossible exception code")
|
|
return current
|
|
|
|
/// There's a cache error. Big trouble. Probably not worth trying to recover.
|
|
Thread *cache_error ():
|
|
panic (0x33333333, "cache error")
|
|
return current
|