Root/
| 1 | #pypp 0 |
| 2 | // Iris: micro-kernel for a capability-based operating system. |
| 3 | // mips/arch.hhp: mips-specific declarations and type definitions. |
| 4 | // Copyright 2009 Bas Wijnen <wijnen@debian.org> |
| 5 | // |
| 6 | // This program is free software: you can redistribute it and/or modify |
| 7 | // it under the terms of the GNU General Public License as published by |
| 8 | // the Free Software Foundation, either version 3 of the License, or |
| 9 | // (at your option) any later version. |
| 10 | // |
| 11 | // This program is distributed in the hope that it will be useful, |
| 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | // GNU General Public License for more details. |
| 15 | // |
| 16 | // You should have received a copy of the GNU General Public License |
| 17 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | |
| 19 | #ifndef _ARCH_HH |
| 20 | #define _ARCH_HH |
| 21 | |
| 22 | #ifdef ARCH |
| 23 | |
| 24 | #ifndef ASM |
| 25 | #include "board.hh" |
| 26 | #endif |
| 27 | |
| 28 | #define reg_hack(x...) #x |
| 29 | #define cp0_get(reg, target) do { __asm__ volatile ("mfc0 %0, $" reg_hack(reg) : "=r" (target)); } while (0) |
| 30 | #define cp0_set(reg, value) do { __asm__ volatile ("mtc0 %0, $" reg_hack(reg) :: "r" (value)); } while (0) |
| 31 | #define cp0_set0(reg) do { __asm__ volatile ("mtc0 $zero, $" reg_hack(reg)); } while (0) |
| 32 | |
| 33 | // cp0 registers. |
| 34 | #define CP0_INDEX 0 |
| 35 | #define CP0_RANDOM 1 |
| 36 | #define CP0_ENTRY_LO0 2 |
| 37 | #define CP0_ENTRY_LO1 3 |
| 38 | #define CP0_CONTEXT 4 |
| 39 | #define CP0_PAGE_MASK 5 |
| 40 | #define CP0_WIRED 6 |
| 41 | #define CP0_BAD_V_ADDR 8 |
| 42 | #define CP0_COUNT 9 |
| 43 | #define CP0_ENTRY_HI 10 |
| 44 | #define CP0_COMPARE 11 |
| 45 | #define CP0_STATUS 12 |
| 46 | #define CP0_INT_CTL 12, 1 |
| 47 | #define CP0_CAUSE 13 |
| 48 | #define CP0_EPC 14 |
| 49 | #define CP0_P_R_ID 15 |
| 50 | #define CP0_EBASE 15, 1 |
| 51 | #define CP0_CONFIG 16 |
| 52 | #define CP0_CONFIG1 16, 1 |
| 53 | #define CP0_CONFIG2 16, 2 |
| 54 | #define CP0_CONFIG3 16, 3 |
| 55 | #define CP0_L_L_ADDR 17 |
| 56 | #define CP0_WATCH_LO 18 |
| 57 | #define CP0_WATCH_HI 19 |
| 58 | #define CP0_DEBUG 23 |
| 59 | #define CP0_DEPC 24 |
| 60 | #define CP0_PERF_CNT 25 |
| 61 | #define CP0_ERR_CTL 26 |
| 62 | #define CP0_CACHE_ERR 27 |
| 63 | #define CP0_TAG_LO 28, 0 |
| 64 | #define CP0_DATA_LO 28, 1 |
| 65 | #define CP0_TAG_HI 29, 0 |
| 66 | #define CP0_DATA_HI 29, 1 |
| 67 | #define CP0_ERROR_EPC 30 |
| 68 | #define CP0_DESAVE 31 |
| 69 | |
| 70 | #endif |
| 71 | |
| 72 | #ifdef __KERNEL__ |
| 73 | // register save positions in kThread |
| 74 | #define SAVE_PC (6 * 4) |
| 75 | #define SAVE_SP (SAVE_PC + 4) |
| 76 | #define SAVE_AT (SAVE_SP + 4) |
| 77 | #define SAVE_V (SAVE_AT + 4) |
| 78 | #define SAVE_A (SAVE_V + 2 * 4) |
| 79 | #define SAVE_T (SAVE_A + 4 * 4) |
| 80 | #define SAVE_S (SAVE_T + 10 * 4) |
| 81 | #define SAVE_GP (SAVE_S + 8 * 4) |
| 82 | #define SAVE_FP (SAVE_GP + 4) |
| 83 | #define SAVE_RA (SAVE_FP + 4) |
| 84 | #define SAVE_HI (SAVE_RA + 4) |
| 85 | #define SAVE_LO (SAVE_HI + 4) |
| 86 | |
| 87 | #ifndef ASM |
| 88 | |
| 89 | void flush_tlb (unsigned asid) |
| 90 | void arch_flush_cache () |
| 91 | |
| 92 | struct kThread_arch: |
| 93 | unsigned at, v[2], a[4], t[10], s[8], gp, fp, ra, hi, lo |
| 94 | |
| 95 | // The following is used for page mapping. |
| 96 | // Each Memory has a directory with 0x400 page tables. |
| 97 | // Page tables are pages which contain 0x200 EntryLo. values and 0x200 |
| 98 | // kPage pointers. |
| 99 | // For a virtual address, bits 0-11 are in the physical address, bits 12-20 are |
| 100 | // an index in the page table, bits 21-30 are an index in the page directory |
| 101 | // and bit 31 is always 0. |
| 102 | |
| 103 | struct kPage_arch: |
| 104 | kPageP prev_mapped, next_mapped |
| 105 | |
| 106 | struct Table: |
| 107 | unsigned entrylo[0x200] |
| 108 | kPage *page[0x200] |
| 109 | |
| 110 | struct kMemory_arch: |
| 111 | unsigned asid |
| 112 | Table **directory |
| 113 | kPageP *shadow |
| 114 | unsigned first_table |
| 115 | |
| 116 | // Pointers to kMemory when asid is taken, index of next free, or 0, if free. |
| 117 | // asid[0] is used as index to first free asid. |
| 118 | // asid value 0 is only used by the idle task. |
| 119 | EXTERN unsigned asids[64] |
| 120 | EXTERN kReceiverP arch_interrupt_receiver[32] |
| 121 | |
| 122 | // Functions which can be called from assembly must not be mangled. |
| 123 | extern "C": |
| 124 | // Kernel entry points, called from entry.S. |
| 125 | kThread *interrupt () |
| 126 | kThread *cache_error () |
| 127 | kThread *exception () |
| 128 | kThread *tlb_refill () |
| 129 | |
| 130 | #ifdef INIT |
| 131 | // Initialize most things (the rest is done in boot.S) |
| 132 | void init (unsigned mem) |
| 133 | void board_init () |
| 134 | // Start running the idle task for the first time. |
| 135 | void run_idle (kThread *self) |
| 136 | #endif |
| 137 | |
| 138 | // These are "extern", not "EXTERN", because they really are defined elsewhere. |
| 139 | #ifdef INIT |
| 140 | extern unsigned thread_start[] |
| 141 | #endif |
| 142 | // Fast pointer to page directory, for tlb miss events |
| 143 | extern Table **directory |
| 144 | |
| 145 | #endif // not defined ASM |
| 146 | |
| 147 | #endif // defined __KERNEL__ |
| 148 | |
| 149 | #endif |
| 150 |
Branches:
master
