Some SH4 (Dreamcast) work in progress
[newos.git] / kernel / arch / sh4 / arch_cpu.c
blobc2321344121a0d66c9e8f17dcad19ee6328dc838
1 /*
2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #include <kernel/arch/cpu.h>
6 #include <kernel/debug.h>
7 #include <kernel/int.h>
8 #include <boot/stage2.h>
10 static vcpu_struct *vcpu;
12 int arch_cpu_preboot_init(kernel_args *ka)
14 return 0;
17 int arch_cpu_init(kernel_args *ka)
19 vcpu = ka->arch_args.vcpu;
21 vcpu->kernel_asid = 0;
22 vcpu->user_asid = 0;
24 return 0;
27 int arch_cpu_init2(kernel_args *ka)
29 return 0;
32 void sh4_set_kstack(addr_t kstack)
34 // dprintf("sh4_set_kstack: setting kstack to 0x%x\n", kstack);
35 vcpu->kstack = (unsigned int *)kstack;
38 void sh4_set_user_pgdir(addr_t pgdir)
40 // dprintf("sh4_set_user_pgdir: setting pgdir to 0x%x\n", pgdir);
41 if((addr_t)vcpu->user_pgdir != pgdir)
42 arch_cpu_global_TLB_invalidate();
43 vcpu->user_pgdir = (unsigned int *)pgdir;
46 void sh4_invl_page(addr_t va)
48 int i;
50 va = ROUNDOWN(va, PAGE_SIZE);
52 int_disable_interrupts();
54 // wipe it out of the data tlbs
55 for(i=0; i<UTLB_COUNT; i++) {
56 struct utlb_addr_array *ua = (struct utlb_addr_array *)(UTLB + (i << UTLB_ADDR_SHIFT));
57 if(ua->vpn == (va >> 10))
58 ua->valid = 0;
61 // wipe it out of the instruction tlbs
62 for(i=0; i<ITLB_COUNT; i++) {
63 struct itlb_addr_array *ia = (struct itlb_addr_array *)(ITLB + (i << ITLB_ADDR_SHIFT));
64 if(ia->vpn == (va >> 10))
65 ia->valid = 0;
68 int_restore_interrupts();
71 void arch_cpu_invalidate_TLB_range(addr_t start, addr_t end)
73 for(; start < end; start += PAGE_SIZE) {
74 sh4_invl_page(start);
78 void arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages)
80 int i;
81 for(i=0; i<num_pages; i++) {
82 sh4_invl_page(pages[i]);
86 void arch_cpu_global_TLB_invalidate()
88 int i;
90 int_disable_interrupts();
92 // wipe out the data tlbs
93 for(i=0; i<UTLB_COUNT; i++) {
94 struct utlb_addr_array *ua = (struct utlb_addr_array *)(UTLB + (i << UTLB_ADDR_SHIFT));
95 ua->valid = 0;
98 // wipe out the instruction tlbs
99 for(i=0; i<ITLB_COUNT; i++) {
100 struct itlb_addr_array *ia = (struct itlb_addr_array *)(ITLB + (i << ITLB_ADDR_SHIFT));
101 ia->valid = 0;
104 int_restore_interrupts();
107 void arch_cpu_sync_icache(void *address, size_t len)
109 PANIC_UNIMPLEMENTED();
112 int arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *fault_handler)
114 char *tmp = (char *)to;
115 char *s = (char *)from;
117 *fault_handler = (addr_t)&&error;
119 while(size--)
120 *tmp++ = *s++;
122 *fault_handler = 0;
124 return 0;
125 error:
126 *fault_handler = 0;
127 return ERR_VM_BAD_USER_MEMORY;
130 int arch_cpu_user_strcpy(char *to, const char *from, addr_t *fault_handler)
132 *fault_handler = (addr_t)&&error;
134 while((*to++ = *from++) != '\0')
137 *fault_handler = 0;
139 return 0;
140 error:
141 *fault_handler = 0;
142 return ERR_VM_BAD_USER_MEMORY;
145 int arch_cpu_user_strncpy(char *to, const char *from, size_t size, addr_t *fault_handler)
147 *fault_handler = (addr_t)&&error;
149 while(size-- && (*to++ = *from++) != '\0')
152 *fault_handler = 0;
154 return 0;
155 error:
156 *fault_handler = 0;
157 return ERR_VM_BAD_USER_MEMORY;
160 int arch_cpu_user_memset(void *s, char c, size_t count, addr_t *fault_handler)
162 char *xs = (char *) s;
164 *fault_handler = (addr_t)&&error;
166 while (count--)
167 *xs++ = c;
169 *fault_handler = 0;
171 return 0;
172 error:
173 *fault_handler = 0;
174 return ERR_VM_BAD_USER_MEMORY;
177 void arch_cpu_idle(void)