cpu_machdep.c (24690) | cpu_machdep.c (24691) |
---|---|
1/*- 2 * Copyright (c) 1992 Terrence R. Lambert. 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * --- 21 unchanged lines hidden (view full) --- 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 | 1/*- 2 * Copyright (c) 1992 Terrence R. Lambert. 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * --- 21 unchanged lines hidden (view full) --- 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 |
38 * $Id: machdep.c,v 1.234 1997/03/31 11:10:37 davidg Exp $ | 38 * $Id: machdep.c,v 1.235 1997/04/07 06:45:13 peter Exp $ |
39 */ 40 41#include "npx.h" 42#include "opt_sysvipc.h" 43#include "opt_ddb.h" 44#include "opt_bounce.h" 45#include "opt_machdep.h" 46#include "opt_perfmon.h" --- 703 unchanged lines hidden (view full) --- 750union descriptor ldt[NLDT]; /* local descriptor table */ 751struct i386tss common_tss; 752 753static struct i386tss dblfault_tss; 754static char dblfault_stack[PAGE_SIZE]; 755 756extern struct user *proc0paddr; 757 | 39 */ 40 41#include "npx.h" 42#include "opt_sysvipc.h" 43#include "opt_ddb.h" 44#include "opt_bounce.h" 45#include "opt_machdep.h" 46#include "opt_perfmon.h" --- 703 unchanged lines hidden (view full) --- 750union descriptor ldt[NLDT]; /* local descriptor table */ 751struct i386tss common_tss; 752 753static struct i386tss dblfault_tss; 754static char dblfault_stack[PAGE_SIZE]; 755 756extern struct user *proc0paddr; 757 |
758#ifdef TSS_IS_CACHED /* cpu_switch helper */ 759struct segment_descriptor *tssptr; 760int gsel_tss; 761#endif 762 |
|
758/* software prototypes -- in more palatable form */ 759struct soft_segment_descriptor gdt_segs[] = { 760/* GNULL_SEL 0 Null Descriptor */ 761{ 0x0, /* segment base address */ 762 0x0, /* length */ 763 0, /* segment type */ 764 0, /* segment descriptor priority level */ 765 0, /* segment descriptor present */ --- 41 unchanged lines hidden (view full) --- 807 sizeof(struct i386tss)-1,/* length - all address space */ 808 SDT_SYS386TSS, /* segment type */ 809 0, /* segment descriptor priority level */ 810 1, /* segment descriptor present */ 811 0, 0, 812 0, /* unused - default 32 vs 16 bit size */ 813 0 /* limit granularity (byte/page units)*/ }, 814/* GPROC0_SEL 6 Proc 0 Tss Descriptor */ | 763/* software prototypes -- in more palatable form */ 764struct soft_segment_descriptor gdt_segs[] = { 765/* GNULL_SEL 0 Null Descriptor */ 766{ 0x0, /* segment base address */ 767 0x0, /* length */ 768 0, /* segment type */ 769 0, /* segment descriptor priority level */ 770 0, /* segment descriptor present */ --- 41 unchanged lines hidden (view full) --- 812 sizeof(struct i386tss)-1,/* length - all address space */ 813 SDT_SYS386TSS, /* segment type */ 814 0, /* segment descriptor priority level */ 815 1, /* segment descriptor present */ 816 0, 0, 817 0, /* unused - default 32 vs 16 bit size */ 818 0 /* limit granularity (byte/page units)*/ }, 819/* GPROC0_SEL 6 Proc 0 Tss Descriptor */ |
815{ (int) &common_tss, /* segment base address */ | 820{ (int) &common_tss, /* segment base address */ |
816 sizeof(struct i386tss)-1,/* length - all address space */ 817 SDT_SYS386TSS, /* segment type */ 818 0, /* segment descriptor priority level */ 819 1, /* segment descriptor present */ 820 0, 0, 821 0, /* unused - default 32 vs 16 bit size */ 822 0 /* limit granularity (byte/page units)*/ }, 823/* GUSERLDT_SEL 7 User LDT Descriptor per process */ --- 127 unchanged lines hidden (view full) --- 951 952void 953init386(first) 954 int first; 955{ 956 int x; 957 unsigned biosbasemem, biosextmem; 958 struct gate_descriptor *gdp; | 821 sizeof(struct i386tss)-1,/* length - all address space */ 822 SDT_SYS386TSS, /* segment type */ 823 0, /* segment descriptor priority level */ 824 1, /* segment descriptor present */ 825 0, 0, 826 0, /* unused - default 32 vs 16 bit size */ 827 0 /* limit granularity (byte/page units)*/ }, 828/* GUSERLDT_SEL 7 User LDT Descriptor per process */ --- 127 unchanged lines hidden (view full) --- 956 957void 958init386(first) 959 int first; 960{ 961 int x; 962 unsigned biosbasemem, biosextmem; 963 struct gate_descriptor *gdp; |
964#ifndef TSS_IS_CACHED |
|
959 int gsel_tss; | 965 int gsel_tss; |
966#endif |
|
960 struct isa_device *idp; 961 /* table descriptors - used to load tables by microp */ 962 struct region_descriptor r_gdt, r_idt; 963 int pagesinbase, pagesinext; 964 int target_page, pa_indx; 965 int off; 966 967 proc0.p_addr = proc0paddr; --- 327 unchanged lines hidden (view full) --- 1295 /* now running on new page tables, configured,and u/iom is accessible */ 1296 1297 /* Map the message buffer. */ 1298 for (off = 0; off < round_page(sizeof(struct msgbuf)); off += PAGE_SIZE) 1299 pmap_enter(kernel_pmap, (vm_offset_t)msgbufp + off, 1300 avail_end + off, VM_PROT_ALL, TRUE); 1301 msgbufmapped = 1; 1302 | 967 struct isa_device *idp; 968 /* table descriptors - used to load tables by microp */ 969 struct region_descriptor r_gdt, r_idt; 970 int pagesinbase, pagesinext; 971 int target_page, pa_indx; 972 int off; 973 974 proc0.p_addr = proc0paddr; --- 327 unchanged lines hidden (view full) --- 1302 /* now running on new page tables, configured,and u/iom is accessible */ 1303 1304 /* Map the message buffer. */ 1305 for (off = 0; off < round_page(sizeof(struct msgbuf)); off += PAGE_SIZE) 1306 pmap_enter(kernel_pmap, (vm_offset_t)msgbufp + off, 1307 avail_end + off, VM_PROT_ALL, TRUE); 1308 msgbufmapped = 1; 1309 |
1303 /* make a initial tss so microp can get interrupt stack on syscall! */ 1304 common_tss.tss_esp0 = (int) kstack + UPAGES*PAGE_SIZE; | 1310 /* make an initial tss so cpu can get interrupt stack on syscall! */ 1311 common_tss.tss_esp0 = (int) proc0.p_addr + UPAGES*PAGE_SIZE; |
1305 common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; 1306 common_tss.tss_ioopt = (sizeof common_tss) << 16; 1307 gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 1308 ltr(gsel_tss); 1309 1310 dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = 1311 dblfault_tss.tss_esp2 = (int) &dblfault_stack[sizeof(dblfault_stack)]; 1312 dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = 1313 dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); 1314 dblfault_tss.tss_cr3 = IdlePTD; 1315 dblfault_tss.tss_eip = (int) dblfault_handler; 1316 dblfault_tss.tss_eflags = PSL_KERNEL; | 1312 common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; 1313 common_tss.tss_ioopt = (sizeof common_tss) << 16; 1314 gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 1315 ltr(gsel_tss); 1316 1317 dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = 1318 dblfault_tss.tss_esp2 = (int) &dblfault_stack[sizeof(dblfault_stack)]; 1319 dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = 1320 dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); 1321 dblfault_tss.tss_cr3 = IdlePTD; 1322 dblfault_tss.tss_eip = (int) dblfault_handler; 1323 dblfault_tss.tss_eflags = PSL_KERNEL; |
1317 dblfault_tss.tss_ds = dblfault_tss.tss_es = dblfault_tss.tss_fs = dblfault_tss.tss_gs = 1318 GSEL(GDATA_SEL, SEL_KPL); | 1324 dblfault_tss.tss_ds = dblfault_tss.tss_es = dblfault_tss.tss_fs = 1325 dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL); |
1319 dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); 1320 dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); 1321 | 1326 dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); 1327 dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); 1328 |
1329#ifdef TSS_IS_CACHED /* cpu_switch helper */ 1330 tssptr = &gdt[GPROC0_SEL].sd; 1331#endif 1332 |
|
1322 /* make a call gate to reenter kernel with */ 1323 gdp = &ldt[LSYS5CALLS_SEL].gd; 1324 1325 x = (int) &IDTVEC(syscall); 1326 gdp->gd_looffset = x++; 1327 gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL); 1328 gdp->gd_stkcpy = 1; 1329 gdp->gd_type = SDT_SYS386CGT; --- 18 unchanged lines hidden (view full) --- 1348 * The registers are in the frame; the frame is in the user area of 1349 * the process in question; when the process is active, the registers 1350 * are in "the kernel stack"; when it's not, they're still there, but 1351 * things get flipped around. So, since p->p_md.md_regs is the whole address 1352 * of the register set, take its offset from the kernel stack, and 1353 * index into the user block. Don't you just *love* virtual memory? 1354 * (I'm starting to think seymour is right...) 1355 */ | 1333 /* make a call gate to reenter kernel with */ 1334 gdp = &ldt[LSYS5CALLS_SEL].gd; 1335 1336 x = (int) &IDTVEC(syscall); 1337 gdp->gd_looffset = x++; 1338 gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL); 1339 gdp->gd_stkcpy = 1; 1340 gdp->gd_type = SDT_SYS386CGT; --- 18 unchanged lines hidden (view full) --- 1359 * The registers are in the frame; the frame is in the user area of 1360 * the process in question; when the process is active, the registers 1361 * are in "the kernel stack"; when it's not, they're still there, but 1362 * things get flipped around. So, since p->p_md.md_regs is the whole address 1363 * of the register set, take its offset from the kernel stack, and 1364 * index into the user block. Don't you just *love* virtual memory? 1365 * (I'm starting to think seymour is right...) 1366 */ |
1356#define TF_REGP(p) ((struct trapframe *) \ 1357 ((char *)(p)->p_addr \ 1358 + ((char *)(p)->p_md.md_regs - kstack))) | 1367#define TF_REGP(p) ((struct trapframe *)(p)->p_md.md_regs) |
1359 1360int 1361ptrace_set_pc(p, addr) 1362 struct proc *p; 1363 unsigned int addr; 1364{ 1365 TF_REGP(p)->tf_eip = addr; 1366 return (0); --- 15 unchanged lines hidden (view full) --- 1382 struct trapframe frame_copy; 1383 vm_offset_t min; 1384 struct trapframe *tp; 1385 1386 /* 1387 * Privileged kernel state is scattered all over the user area. 1388 * Only allow write access to parts of regs and to fpregs. 1389 */ | 1368 1369int 1370ptrace_set_pc(p, addr) 1371 struct proc *p; 1372 unsigned int addr; 1373{ 1374 TF_REGP(p)->tf_eip = addr; 1375 return (0); --- 15 unchanged lines hidden (view full) --- 1391 struct trapframe frame_copy; 1392 vm_offset_t min; 1393 struct trapframe *tp; 1394 1395 /* 1396 * Privileged kernel state is scattered all over the user area. 1397 * Only allow write access to parts of regs and to fpregs. 1398 */ |
1390 min = (char *)p->p_md.md_regs - kstack; | 1399 min = (char *)p->p_md.md_regs - (char *)p->p_addr; |
1391 if (off >= min && off <= min + sizeof(struct trapframe) - sizeof(int)) { 1392 tp = TF_REGP(p); 1393 frame_copy = *tp; 1394 *(int *)((char *)&frame_copy + (off - min)) = data; 1395 if (!EFLAGS_SECURE(frame_copy.tf_eflags, tp->tf_eflags) || 1396 !CS_SECURE(frame_copy.tf_cs)) 1397 return (EINVAL); 1398 *(int*)((char *)p->p_addr + off) = data; --- 175 unchanged lines hidden --- | 1400 if (off >= min && off <= min + sizeof(struct trapframe) - sizeof(int)) { 1401 tp = TF_REGP(p); 1402 frame_copy = *tp; 1403 *(int *)((char *)&frame_copy + (off - min)) = data; 1404 if (!EFLAGS_SECURE(frame_copy.tf_eflags, tp->tf_eflags) || 1405 !CS_SECURE(frame_copy.tf_cs)) 1406 return (EINVAL); 1407 *(int*)((char *)p->p_addr + off) = data; --- 175 unchanged lines hidden --- |