BOOK.TXT
上传用户:jnzhq888
上传日期:2007-01-18
资源大小:51694k
文件大小:1020k
源码类别:

操作系统开发

开发平台:

WINDOWS

  1. 04337 #define BREAKPOINT_VECTOR  3    /* software breakpoint */
  2. 04338 #define OVERFLOW_VECTOR    4    /* from INTO */
  3. 04339
  4. 04340 /* Fixed system call vector. */
  5. 04341 #define SYS_VECTOR        32    /* system calls are made with int SYSVEC */
  6. 04342 #define SYS386_VECTOR     33    /* except 386 system calls use this */
  7. 04343 #define LEVEL0_VECTOR     34    /* for execution of a function at level 0 */
  8. 04344
  9. 04345 /* Suitable irq bases for hardware interrupts.  Reprogram the 8259(s) from
  10. 04346  * the PC BIOS defaults since the BIOS doesn't respect all the processor's
  11. 04347  * reserved vectors (0 to 31).
  12. 04348  */
  13. 04349 #define BIOS_IRQ0_VEC   0x08    /* base of IRQ0-7 vectors used by BIOS */
  14. 04350 #define BIOS_IRQ8_VEC   0x70    /* base of IRQ8-15 vectors used by BIOS */
  15. 04351 #define IRQ0_VECTOR     0x28    /* more or less arbitrary, but > SYS_VECTOR */
  16. 04352 #define IRQ8_VECTOR     0x30    /* together for simplicity */
  17. 04353
  18. 04354 /* Hardware interrupt numbers. */
  19. 04355 #define NR_IRQ_VECTORS    16
  20. 04356 #define CLOCK_IRQ          0
  21. 04357 #define KEYBOARD_IRQ       1
  22. 04358 #define CASCADE_IRQ        2    /* cascade enable for 2nd AT controller */
  23. 04359 #define ETHER_IRQ          3    /* default ethernet interrupt vector */
  24. 04360 #define SECONDARY_IRQ      3    /* RS232 interrupt vector for port 2 */
  25. 04361 #define RS232_IRQ          4    /* RS232 interrupt vector for port 1 */
  26. 04362 #define XT_WINI_IRQ        5    /* xt winchester */
  27. 04363 #define FLOPPY_IRQ         6    /* floppy disk */
  28. 04364 #define PRINTER_IRQ        7
  29. 04365 #define AT_WINI_IRQ       14    /* at winchester */
  30. 04366
  31. 04367 /* Interrupt number to hardware vector. */
  32. 04368 #define BIOS_VECTOR(irq)        
  33. 04369         (((irq) < 8 ? BIOS_IRQ0_VEC : BIOS_IRQ8_VEC) + ((irq) & 0x07))
  34. 04370 #define VECTOR(irq)     
  35. 04371         (((irq) < 8 ? IRQ0_VECTOR : IRQ8_VECTOR) + ((irq) & 0x07))
  36. 04372
  37. 04373 /* BIOS hard disk parameter vectors. */
  38. 04374 #define WINI_0_PARM_VEC 0x41
  39. 04375 #define WINI_1_PARM_VEC 0x46
  40. 04376
  41. 04377 /* 8259A interrupt controller ports. */
  42. 04378 #define INT_CTL         0x20    /* I/O port for interrupt controller */
  43. 04379 #define INT_CTLMASK     0x21    /* setting bits in this port disables ints */
  44. 04380 #define INT2_CTL        0xA0    /* I/O port for second interrupt controller */
  45. 04381 #define INT2_CTLMASK    0xA1    /* setting bits in this port disables ints */
  46. 04382
  47. 04383 /* Magic numbers for interrupt controller. */
  48. 04384 #define ENABLE          0x20    /* code used to re-enable after an interrupt */
  49. 04385
  50. 04386 /* Sizes of memory tables. */
  51. 04387 #define NR_MEMS            3    /* number of chunks of memory */
  52. 04388
  53. 04389 /* Miscellaneous ports. */
  54. 04390 #define PCR             0x65    /* Planar Control Register */
  55. 04391 #define PORT_B          0x61    /* I/O port for 8255 port B (kbd, beeper...) */
  56. 04392 #define TIMER0          0x40    /* I/O port for timer channel 0 */
  57. 04393 #define TIMER2          0x42    /* I/O port for timer channel 2 */
  58. 04394 #define TIMER_MODE      0x43    /* I/O port for timer mode control */
  59. 04395
  60. 04396 #endif /* (CHIP == INTEL) */
  61. 04397
  62. 04398 #if (CHIP == M68000)
  63. 04399
  64. 04400 #define K_STACK_BYTES   1024    /* how many bytes for the kernel stack */
  65. 04401
  66. 04402 /* Sizes of memory tables. */
  67. 04403 #define NR_MEMS            2    /* number of chunks of memory */
  68. 04404
  69. 04405 /* p_reg contains: d0-d7, a0-a6,   in that order. */
  70. 04406 #define NR_REGS           15    /* number of general regs in each proc slot */
  71. 04407  
  72. 04408 #define TRACEBIT      0x8000    /* or this with psw in proc[] for tracing */
  73. 04409 #define SETPSW(rp, new)         /* permits only certain bits to be set */ 
  74. 04410         ((rp)->p_reg.psw = (rp)->p_reg.psw & ~0xFF | (new) & 0xFF)
  75. 04411  
  76. 04412 #define MEM_BYTES  0xffffffff   /* memory size for /dev/mem */
  77. 04413  
  78. 04414 #ifdef __ACK__
  79. 04415 #define FSTRUCOPY
  80. 04416 #endif
  81. 04417
  82. 04418 #endif /* (CHIP == M68000) */
  83. 04419
  84. 04420 /* The following items pertain to the scheduling queues. */
  85. 04421 #define TASK_Q             0    /* ready tasks are scheduled via queue 0 */
  86. 04422 #define SERVER_Q           1    /* ready servers are scheduled via queue 1 */
  87. 04423 #define USER_Q             2    /* ready users are scheduled via queue 2 */
  88. 04424
  89. 04425 #if (MACHINE == ATARI)
  90. 04426 #define SHADOW_Q           3    /* runnable, but shadowed processes */
  91. 04427 #define NQ                 4    /* # of scheduling queues */
  92. 04428 #else
  93. 04429 #define NQ                 3    /* # of scheduling queues */
  94. 04430 #endif
  95. 04431
  96. 04432 /* Env_parse() return values. */
  97. 04433 #define EP_UNSET        0       /* variable not set */
  98. 04434 #define EP_OFF          1       /* var = off */
  99. 04435 #define EP_ON           2       /* var = on (or field left blank) */
  100. 04436 #define EP_SET          3       /* var = 1:2:3 (nonblank field) */
  101. 04437
  102. 04438 /* To translate an address in kernel space to a physical address.  This is
  103. 04439  * the same as umap(proc_ptr, D, vir, sizeof(*vir)), but a lot less costly.
  104. 04440  */
  105. 04441 #define vir2phys(vir)   (data_base + (vir_bytes) (vir))
  106. 04442
  107. 04443 #define printf        printk    /* the kernel really uses printk, not printf */
  108. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  109. src/kernel/type.h    
  110. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  111. 04500 #ifndef TYPE_H
  112. 04501 #define TYPE_H
  113. 04502
  114. 04503 typedef _PROTOTYPE( void task_t, (void) );
  115. 04504 typedef _PROTOTYPE( int (*rdwt_t), (message *m_ptr) );
  116. 04505 typedef _PROTOTYPE( void (*watchdog_t), (void) );
  117. 04506
  118. 04507 struct tasktab {
  119. 04508   task_t *initial_pc;
  120. 04509   int stksize;
  121. 04510   char name[8];
  122. 04511 };
  123. 04512
  124. 04513 struct memory {
  125. 04514   phys_clicks base;
  126. 04515   phys_clicks size;
  127. 04516 };
  128. 04517
  129. 04518 /* Administration for clock polling. */
  130. 04519 struct milli_state {
  131. 04520   unsigned long accum_count;    /* accumulated clock ticks */
  132. 04521   unsigned prev_count;          /* previous clock value */
  133. 04522 };
  134. 04523
  135. 04524 #if (CHIP == INTEL)
  136. 04525 typedef unsigned port_t;
  137. 04526 typedef unsigned segm_t;
  138. 04527 typedef unsigned reg_t;         /* machine register */
  139. 04528
  140. 04529 /* The stack frame layout is determined by the software, but for efficiency
  141. 04530  * it is laid out so the assembly code to use it is as simple as possible.
  142. 04531  * 80286 protected mode and all real modes use the same frame, built with
  143. 04532  * 16-bit registers.  Real mode lacks an automatic stack switch, so little
  144. 04533  * is lost by using the 286 frame for it.  The 386 frame differs only in
  145. 04534  * having 32-bit registers and more segment registers.  The same names are
  146. 04535  * used for the larger registers to avoid differences in the code.
  147. 04536  */
  148. 04537 struct stackframe_s {           /* proc_ptr points here */
  149. 04538 #if _WORD_SIZE == 4
  150. 04539   u16_t gs;                     /* last item pushed by save */
  151. 04540   u16_t fs;                     /*  ^ */
  152. 04541 #endif
  153. 04542   u16_t es;                     /*  | */
  154. 04543   u16_t ds;                     /*  | */
  155. 04544   reg_t di;                     /* di through cx are not accessed in C */
  156. 04545   reg_t si;                     /* order is to match pusha/popa */
  157. 04546   reg_t fp;                     /* bp */
  158. 04547   reg_t st;                     /* hole for another copy of sp */
  159. 04548   reg_t bx;                     /*  | */
  160. 04549   reg_t dx;                     /*  | */
  161. 04550   reg_t cx;                     /*  | */
  162. 04551   reg_t retreg;                 /* ax and above are all pushed by save */
  163. 04552   reg_t retadr;                 /* return address for assembly code save() */
  164. 04553   reg_t pc;                     /*  ^  last item pushed by interrupt */
  165. 04554   reg_t cs;                     /*  | */
  166. 04555   reg_t psw;                    /*  | */
  167. 04556   reg_t sp;                     /*  | */
  168. 04557   reg_t ss;                     /* these are pushed by CPU during interrupt */
  169. 04558 };
  170. 04559
  171. 04560 struct segdesc_s {              /* segment descriptor for protected mode */
  172. 04561   u16_t limit_low;
  173. 04562   u16_t base_low;
  174. 04563   u8_t base_middle;
  175. 04564   u8_t access;                  /* |P|DL|1|X|E|R|A| */
  176. 04565 #if _WORD_SIZE == 4
  177. 04566   u8_t granularity;             /* |G|X|0|A|LIMT| */
  178. 04567   u8_t base_high;
  179. 04568 #else
  180. 04569   u16_t reserved;
  181. 04570 #endif
  182. 04571 };
  183. 04572
  184. 04573 typedef _PROTOTYPE( int (*irq_handler_t), (int irq) );
  185. 04574
  186. 04575 #endif /* (CHIP == INTEL) */
  187. 04576
  188. 04577 #if (CHIP == M68000)
  189. 04578 typedef _PROTOTYPE( void (*dmaint_t), (void) );
  190. 04579
  191. 04580 typedef u32_t reg_t;            /* machine register */
  192. 04581
  193. 04582 /* The name and fields of this struct were chosen for PC compatibility. */
  194. 04583 struct stackframe_s {
  195. 04584   reg_t retreg;                 /* d0 */
  196. 04585   reg_t d1;
  197. 04586   reg_t d2;
  198. 04587   reg_t d3;
  199. 04588   reg_t d4;
  200. 04589   reg_t d5;
  201. 04590   reg_t d6;
  202. 04591   reg_t d7;
  203. 04592   reg_t a0;
  204. 04593   reg_t a1;
  205. 04594   reg_t a2;
  206. 04595   reg_t a3;
  207. 04596   reg_t a4;
  208. 04597   reg_t a5;
  209. 04598   reg_t fp;                     /* also known as a6 */
  210. 04599   reg_t sp;                     /* also known as a7 */
  211. 04600   reg_t pc;
  212. 04601   u16_t psw;
  213. 04602   u16_t dummy;                  /* make size multiple of reg_t for system.c */
  214. 04603 };
  215. 04604
  216. 04605 struct fsave {
  217. 04606   struct cpu_state {
  218. 04607         u16_t i_format;
  219. 04608         u32_t i_addr;
  220. 04609         u16_t i_state[4];
  221. 04610   } cpu_state;
  222. 04611   struct state_frame {
  223. 04612         u8_t frame_type;
  224. 04613         u8_t frame_size;
  225. 04614         u16_t reserved;
  226. 04615         u8_t frame[212];
  227. 04616   } state_frame;
  228. 04617   struct fpp_model {
  229. 04618         u32_t fpcr;
  230. 04619         u32_t fpsr;
  231. 04620         u32_t fpiar;
  232. 04621         struct fpN {
  233. 04622                 u32_t high;
  234. 04623                 u32_t low;
  235. 04624                 u32_t mid;
  236. 04625         } fpN[8];
  237. 04626   } fpp_model;
  238. 04627 };
  239. 04628 #endif /* (CHIP == M68000) */
  240. 04629
  241. 04630 #endif /* TYPE_H */
  242. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  243. src/kernel/proto.h    
  244. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  245. 04700 /* Function prototypes. */
  246. 04701
  247. 04702 #ifndef PROTO_H
  248. 04703 #define PROTO_H
  249. 04704
  250. 04705 /* Struct declarations. */
  251. 04706 struct proc;
  252. 04707 struct tty;
  253. 04708
  254. 04709 /* at_wini.c, wini.c */
  255. 04710 _PROTOTYPE( void winchester_task, (void)                                );
  256. 04711 _PROTOTYPE( void at_winchester_task, (void)                             );
  257. 04712
  258. 04713 /* clock.c */
  259. 04714 _PROTOTYPE( void clock_task, (void)                                     );
  260. 04715 _PROTOTYPE( void clock_stop, (void)                                     );
  261. 04716 _PROTOTYPE( clock_t get_uptime, (void)                                  );
  262. 04717 _PROTOTYPE( void syn_alrm_task, (void)                                  );
  263. 04718
  264. 04719 /* dmp.c */
  265. 04720 _PROTOTYPE( void map_dmp, (void)                                        );
  266. 04721 _PROTOTYPE( void p_dmp, (void)                                          );
  267. 04722 _PROTOTYPE( void reg_dmp, (struct proc *rp)                             );
  268. 04723
  269. 04724 /* dp8390.c */
  270. 04725 _PROTOTYPE( void dp8390_task, (void)                                    );
  271. 04726 _PROTOTYPE( void dp_dump, (void)                                        );
  272. 04727 _PROTOTYPE( void dp8390_stop, (void)                                    );
  273. 04728
  274. 04729 /* floppy.c, stfloppy.c */
  275. 04730 _PROTOTYPE( void floppy_task, (void)                                    );
  276. 04731 _PROTOTYPE( void floppy_stop, (void)                                    );
  277. 04732
  278. 04733 /* main.c, stmain.c */
  279. 04734 _PROTOTYPE( void main, (void)                                           );
  280. 04735 _PROTOTYPE( void panic, (const char *s, int n)                          );
  281. 04736
  282. 04737 /* memory.c */
  283. 04738 _PROTOTYPE( void mem_task, (void)                                       );
  284. 04739
  285. 04740 /* misc.c */
  286. 04741 _PROTOTYPE( int env_parse, (char *env, char *fmt, int field,
  287. 04742                         long *param, long min, long max)                );
  288. 04743
  289. 04744 /* printer.c, stprint.c */
  290. 04745 _PROTOTYPE( void printer_task, (void)                                   );
  291. 04746
  292. 04747 /* proc.c */
  293. 04748 _PROTOTYPE( void interrupt, (int task)                                  );
  294. 04749 _PROTOTYPE( int lock_mini_send, (struct proc *caller_ptr,
  295. 04750                 int dest, message *m_ptr)                               );
  296. 04751 _PROTOTYPE( void lock_pick_proc, (void)                                 );
  297. 04752 _PROTOTYPE( void lock_ready, (struct proc *rp)                          );
  298. 04753 _PROTOTYPE( void lock_sched, (void)                                     );
  299. 04754 _PROTOTYPE( void lock_unready, (struct proc *rp)                        );
  300. 04755 _PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr)  );
  301. 04756 _PROTOTYPE( void unhold, (void)                                         );
  302. 04757
  303. 04758 /* rs232.c */
  304. 04759 _PROTOTYPE( void rs_init, (struct tty *tp)                              );
  305. 04760
  306. 04761 /* system.c */
  307. 04762 _PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr)                   );
  308. 04763 _PROTOTYPE( void inform, (void)                                         );
  309. 04764 _PROTOTYPE( phys_bytes numap, (int proc_nr, vir_bytes vir_addr, 
  310. 04765                 vir_bytes bytes)                                        );
  311. 04766 _PROTOTYPE( void sys_task, (void)                                       );
  312. 04767 _PROTOTYPE( phys_bytes umap, (struct proc *rp, int seg, vir_bytes vir_addr,
  313. 04768                 vir_bytes bytes)                                        );
  314. 04769
  315. 04770 /* tty.c */
  316. 04771 _PROTOTYPE( void handle_events, (struct tty *tp)                        );
  317. 04772 _PROTOTYPE( void sigchar, (struct tty *tp, int sig)                     );
  318. 04773 _PROTOTYPE( void tty_task, (void)                                       );
  319. 04774 _PROTOTYPE( int in_process, (struct tty *tp, char *buf, int count)      );
  320. 04775 _PROTOTYPE( void out_process, (struct tty *tp, char *bstart, char *bpos,
  321. 04776                                 char *bend, int *icount, int *ocount)   );
  322. 04777 _PROTOTYPE( void tty_wakeup, (clock_t now)                              );
  323. 04778 _PROTOTYPE( void tty_reply, (int code, int replyee, int proc_nr,
  324. 04779                                                         int status)     );
  325. 04780 _PROTOTYPE( void tty_devnop, (struct tty *tp)                           );
  326. 04781
  327. 04782 /* library */
  328. 04783 _PROTOTYPE( void *memcpy, (void *_s1, const void *_s2, size_t _n)       );
  329. 04784
  330. 04785 #if (CHIP == INTEL)
  331. 04786
  332. 04787 /* clock.c */
  333. 04788 _PROTOTYPE( void milli_start, (struct milli_state *msp)                 );
  334. 04789 _PROTOTYPE( unsigned milli_elapsed, (struct milli_state *msp)           );
  335. 04790 _PROTOTYPE( void milli_delay, (unsigned millisec)                       );
  336. 04791
  337. 04792 /* console.c */
  338. 04793 _PROTOTYPE( void cons_stop, (void)                                      );
  339. 04794 _PROTOTYPE( void putk, (int c)                                          );
  340. 04795 _PROTOTYPE( void scr_init, (struct tty *tp)                             );
  341. 04796 _PROTOTYPE( void toggle_scroll, (void)                                  );
  342. 04797 _PROTOTYPE( int con_loadfont, (phys_bytes user_phys)                    );
  343. 04798 _PROTOTYPE( void select_console, (int cons_line)                        );
  344. 04799
  345. 04800 /* cstart.c */
  346. 04801 _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mcs, U16_t mds,
  347. 04802                                 U16_t parmoff, U16_t parmsize)          );
  348. 04803 _PROTOTYPE( char *k_getenv, (char *name)                                );
  349. 04804
  350. 04805 /* exception.c */
  351. 04806 _PROTOTYPE( void exception, (unsigned vec_nr)                           );
  352. 04807
  353. 04808 /* i8259.c */
  354. 04809 _PROTOTYPE( irq_handler_t get_irq_handler, (int irq)                    );
  355. 04810 _PROTOTYPE( void put_irq_handler, (int irq, irq_handler_t handler)      );
  356. 04811 _PROTOTYPE( void intr_init, (int mine)                                  );
  357. 04812
  358. 04813 /* keyboard.c */
  359. 04814 _PROTOTYPE( void kb_init, (struct tty *tp)                              );
  360. 04815 _PROTOTYPE( int kbd_loadmap, (phys_bytes user_phys)                     );
  361. 04816 _PROTOTYPE( void wreboot, (int how)                                     );
  362. 04817
  363. 04818 /* klib*.s */
  364. 04819 _PROTOTYPE( void bios13, (void)                                         );
  365. 04820 _PROTOTYPE( phys_bytes check_mem, (phys_bytes base, phys_bytes size)    );
  366. 04821 _PROTOTYPE( void cp_mess, (int src,phys_clicks src_clicks,vir_bytes src_offset,
  367. 04822                 phys_clicks dst_clicks, vir_bytes dst_offset)           );
  368. 04823 _PROTOTYPE( int in_byte, (port_t port)                                  );
  369. 04824 _PROTOTYPE( int in_word, (port_t port)                                  );
  370. 04825 _PROTOTYPE( void lock, (void)                                           );
  371. 04826 _PROTOTYPE( void unlock, (void)                                         );
  372. 04827 _PROTOTYPE( void enable_irq, (unsigned irq)                             );
  373. 04828 _PROTOTYPE( int disable_irq, (unsigned irq)                             );
  374. 04829 _PROTOTYPE( u16_t mem_rdw, (segm_t segm, vir_bytes offset)              );
  375. 04830 _PROTOTYPE( void out_byte, (port_t port, int value)                     );
  376. 04831 _PROTOTYPE( void out_word, (port_t port, int value)                     );
  377. 04832 _PROTOTYPE( void phys_copy, (phys_bytes source, phys_bytes dest,
  378. 04833                 phys_bytes count)                                       );
  379. 04834 _PROTOTYPE( void port_read, (unsigned port, phys_bytes destination,
  380. 04835                 unsigned bytcount)                                      );
  381. 04836 _PROTOTYPE( void port_read_byte, (unsigned port, phys_bytes destination,
  382. 04837                 unsigned bytcount)                                      );
  383. 04838 _PROTOTYPE( void port_write, (unsigned port, phys_bytes source,
  384. 04839                 unsigned bytcount)                                      );
  385. 04840 _PROTOTYPE( void port_write_byte, (unsigned port, phys_bytes source,
  386. 04841                 unsigned bytcount)                                      );
  387. 04842 _PROTOTYPE( void reset, (void)                                          );
  388. 04843 _PROTOTYPE( void vid_vid_copy, (unsigned src, unsigned dst, unsigned count));
  389. 04844 _PROTOTYPE( void mem_vid_copy, (u16_t *src, unsigned dst, unsigned count));
  390. 04845 _PROTOTYPE( void level0, (void (*func)(void))                           );
  391. 04846 _PROTOTYPE( void monitor, (void)                                        );
  392. 04847
  393. 04848 /* misc.c */
  394. 04849 _PROTOTYPE( void mem_init, (void)                                       );
  395. 04850
  396. 04851 /* mpx*.s */
  397. 04852 _PROTOTYPE( void idle_task, (void)                                      );
  398. 04853 _PROTOTYPE( void restart, (void)                                        );
  399. 04854
  400. 04855 /* The following are never called from C (pure asm procs). */
  401. 04856
  402. 04857 /* Exception handlers (real or protected mode), in numerical order. */
  403. 04858 void _PROTOTYPE( int00, (void) ), _PROTOTYPE( divide_error, (void) );
  404. 04859 void _PROTOTYPE( int01, (void) ), _PROTOTYPE( single_step_exception, (void) );
  405. 04860 void _PROTOTYPE( int02, (void) ), _PROTOTYPE( nmi, (void) );
  406. 04861 void _PROTOTYPE( int03, (void) ), _PROTOTYPE( breakpoint_exception, (void) );
  407. 04862 void _PROTOTYPE( int04, (void) ), _PROTOTYPE( overflow, (void) );
  408. 04863 void _PROTOTYPE( int05, (void) ), _PROTOTYPE( bounds_check, (void) );
  409. 04864 void _PROTOTYPE( int06, (void) ), _PROTOTYPE( inval_opcode, (void) );
  410. 04865 void _PROTOTYPE( int07, (void) ), _PROTOTYPE( copr_not_available, (void) );
  411. 04866 void                              _PROTOTYPE( double_fault, (void) );
  412. 04867 void                              _PROTOTYPE( copr_seg_overrun, (void) );
  413. 04868 void                              _PROTOTYPE( inval_tss, (void) );
  414. 04869 void                              _PROTOTYPE( segment_not_present, (void) );
  415. 04870 void                              _PROTOTYPE( stack_exception, (void) );
  416. 04871 void                              _PROTOTYPE( general_protection, (void) );
  417. 04872 void                              _PROTOTYPE( page_fault, (void) );
  418. 04873 void                              _PROTOTYPE( copr_error, (void) );
  419. 04874
  420. 04875 /* Hardware interrupt handlers. */
  421. 04876 _PROTOTYPE( void hwint00, (void) );
  422. 04877 _PROTOTYPE( void hwint01, (void) );
  423. 04878 _PROTOTYPE( void hwint02, (void) );
  424. 04879 _PROTOTYPE( void hwint03, (void) );
  425. 04880 _PROTOTYPE( void hwint04, (void) );
  426. 04881 _PROTOTYPE( void hwint05, (void) );
  427. 04882 _PROTOTYPE( void hwint06, (void) );
  428. 04883 _PROTOTYPE( void hwint07, (void) );
  429. 04884 _PROTOTYPE( void hwint08, (void) );
  430. 04885 _PROTOTYPE( void hwint09, (void) );
  431. 04886 _PROTOTYPE( void hwint10, (void) );
  432. 04887 _PROTOTYPE( void hwint11, (void) );
  433. 04888 _PROTOTYPE( void hwint12, (void) );
  434. 04889 _PROTOTYPE( void hwint13, (void) );
  435. 04890 _PROTOTYPE( void hwint14, (void) );
  436. 04891 _PROTOTYPE( void hwint15, (void) );
  437. 04892
  438. 04893 /* Software interrupt handlers, in numerical order. */
  439. 04894 _PROTOTYPE( void trp, (void) );
  440. 04895 _PROTOTYPE( void s_call, (void) ), _PROTOTYPE( p_s_call, (void) );
  441. 04896 _PROTOTYPE( void level0_call, (void) );
  442. 04897
  443. 04898 /* printer.c */
  444. 04899 _PROTOTYPE( void pr_restart, (void)                                     );
  445. 04900
  446. 04901 /* protect.c */
  447. 04902 _PROTOTYPE( void prot_init, (void)                                      );
  448. 04903 _PROTOTYPE( void init_codeseg, (struct segdesc_s *segdp, phys_bytes base,
  449. 04904                 phys_bytes size, int privilege)                         );
  450. 04905 _PROTOTYPE( void init_dataseg, (struct segdesc_s *segdp, phys_bytes base,
  451. 04906                 phys_bytes size, int privilege)                         );
  452. 04907 _PROTOTYPE( phys_bytes seg2phys, (U16_t seg)                            );
  453. 04908 _PROTOTYPE( void enable_iop, (struct proc *pp)                          );
  454. 04909
  455. 04910 /* pty.c */
  456. 04911 _PROTOTYPE( void do_pty, (struct tty *tp, message *m_ptr)               );
  457. 04912 _PROTOTYPE( void pty_init, (struct tty *tp)                             );
  458. 04913
  459. 04914 /* system.c */
  460. 04915 _PROTOTYPE( void alloc_segments, (struct proc *rp)                      );
  461. 04916
  462. 04917 #endif /* (CHIP == INTEL) */
  463. 04918
  464. 04919 #endif /* PROTO_H */
  465. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  466. src/kernel/glo.h    
  467. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  468. 05000 /* Global variables used in the kernel. */
  469. 05001
  470. 05002 /* EXTERN is defined as extern except in table.c. */
  471. 05003 #ifdef _TABLE
  472. 05004 #undef EXTERN
  473. 05005 #define EXTERN
  474. 05006 #endif
  475. 05007
  476. 05008 /* Kernel memory. */
  477. 05009 EXTERN phys_bytes code_base;    /* base of kernel code */
  478. 05010 EXTERN phys_bytes data_base;    /* base of kernel data */
  479. 05011
  480. 05012 /* Low level interrupt communications. */
  481. 05013 EXTERN struct proc *held_head;  /* head of queue of held-up interrupts */
  482. 05014 EXTERN struct proc *held_tail;  /* tail of queue of held-up interrupts */
  483. 05015 EXTERN unsigned char k_reenter; /* kernel reentry count (entry count less 1)*/
  484. 05016
  485. 05017 /* Process table.  Here to stop too many things having to include proc.h. */
  486. 05018 EXTERN struct proc *proc_ptr;   /* pointer to currently running process */
  487. 05019
  488. 05020 /* Signals. */
  489. 05021 EXTERN int sig_procs;           /* number of procs with p_pending != 0 */
  490. 05022
  491. 05023 /* Memory sizes. */
  492. 05024 EXTERN struct memory mem[NR_MEMS];      /* base and size of chunks of memory */
  493. 05025 EXTERN phys_clicks tot_mem_size;        /* total system memory size */
  494. 05026
  495. 05027 /* Miscellaneous. */
  496. 05028 extern u16_t sizes[];           /* table filled in by boot monitor */
  497. 05029 extern struct tasktab tasktab[];/* initialized in table.c, so extern here */
  498. 05030 extern char *t_stack[];         /* initialized in table.c, so extern here */
  499. 05031 EXTERN unsigned lost_ticks;     /* clock ticks counted outside the clock task */
  500. 05032 EXTERN clock_t tty_timeout;     /* time to wake up the TTY task */
  501. 05033 EXTERN int current;             /* currently visible console */
  502. 05034
  503. 05035 #if (CHIP == INTEL)
  504. 05036
  505. 05037 /* Machine type. */
  506. 05038 EXTERN int pc_at;               /* PC-AT compatible hardware interface */
  507. 05039 EXTERN int ps_mca;              /* PS/2 with Micro Channel */
  508. 05040 EXTERN unsigned int processor;  /* 86, 186, 286, 386, ... */
  509. 05041 #if _WORD_SIZE == 2
  510. 05042 EXTERN int protected_mode;      /* nonzero if running in Intel protected mode*/
  511. 05043 #else
  512. 05044 #define protected_mode  1       /* 386 mode implies protected mode */
  513. 05045 #endif
  514. 05046
  515. 05047 /* Video card types. */
  516. 05048 EXTERN int ega;                 /* nonzero if console is EGA or VGA */
  517. 05049 EXTERN int vga;                 /* nonzero if console is VGA */
  518. 05050
  519. 05051 /* Memory sizes. */
  520. 05052 EXTERN unsigned ext_memsize;    /* initialized by assembler startup code */
  521. 05053 EXTERN unsigned low_memsize;
  522. 05054
  523. 05055 /* Miscellaneous. */
  524. 05056 EXTERN irq_handler_t irq_table[NR_IRQ_VECTORS];
  525. 05057 EXTERN int irq_use;             /* bit map of all in-use irq's */
  526. 05058 EXTERN reg_t mon_ss, mon_sp;    /* monitor stack */
  527. 05059 EXTERN int mon_return;          /* true if return to the monitor possible */
  528. 05060 EXTERN phys_bytes reboot_code;  /* program for the boot monitor */
  529. 05061
  530. 05062 /* Variables that are initialized elsewhere are just extern here. */
  531. 05063 extern struct segdesc_s gdt[];  /* global descriptor table for protected mode*/
  532. 05064
  533. 05065 EXTERN _PROTOTYPE( void (*level0_func), (void) );
  534. 05066 #endif /* (CHIP == INTEL) */
  535. 05067
  536. 05068 #if (CHIP == M68000)
  537. 05069 /* Variables that are initialized elsewhere are just extern here. */
  538. 05070 extern int keypad;              /* Flag for keypad mode */
  539. 05071 extern int app_mode;            /* Flag for arrow key application mode */
  540. 05072 extern int STdebKey;            /* nonzero if ctl-alt-Fx detected */
  541. 05073 extern struct tty *cur_cons;    /* virtual cons currently displayed */
  542. 05074 extern unsigned char font8[];   /* 8 pixel wide font table (initialized) */
  543. 05075 extern unsigned char font12[];  /* 12 pixel wide font table (initialized) */
  544. 05076 extern unsigned char font16[];  /* 16 pixel wide font table (initialized) */
  545. 05077 extern unsigned short resolution; /* screen res; ST_RES_LOW..TT_RES_HIGH */
  546. 05078 #endif
  547. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  548. src/kernel/proc.h    
  549. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  550. 05100 #ifndef PROC_H
  551. 05101 #define PROC_H
  552. 05102
  553. 05103 /* Here is the declaration of the process table.  It contains the process'
  554. 05104  * registers, memory map, accounting, and message send/receive information.
  555. 05105  * Many assembly code routines reference fields in it.  The offsets to these
  556. 05106  * fields are defined in the assembler include file sconst.h.  When changing
  557. 05107  * 'proc', be sure to change sconst.h to match.
  558. 05108  */
  559. 05109
  560. 05110 struct proc {
  561. 05111   struct stackframe_s p_reg;    /* process' registers saved in stack frame */
  562. 05112
  563. 05113 #if (CHIP == INTEL)
  564. 05114   reg_t p_ldt_sel;              /* selector in gdt giving ldt base and limit*/
  565. 05115   struct segdesc_s p_ldt[2];    /* local descriptors for code and data */
  566. 05116                                 /* 2 is LDT_SIZE - avoid include protect.h */
  567. 05117 #endif /* (CHIP == INTEL) */
  568. 05118
  569. 05119   reg_t *p_stguard;             /* stack guard word */
  570. 05120
  571. 05121   int p_nr;                     /* number of this process (for fast access) */
  572. 05122
  573. 05123   int p_int_blocked;            /* nonzero if int msg blocked by busy task */
  574. 05124   int p_int_held;               /* nonzero if int msg held by busy syscall */
  575. 05125   struct proc *p_nextheld;      /* next in chain of held-up int processes */
  576. 05126
  577. 05127   int p_flags;                  /* P_SLOT_FREE, SENDING, RECEIVING, etc. */
  578. 05128   struct mem_map p_map[NR_SEGS];/* memory map */
  579. 05129   pid_t p_pid;                  /* process id passed in from MM */
  580. 05130
  581. 05131   clock_t user_time;            /* user time in ticks */
  582. 05132   clock_t sys_time;             /* sys time in ticks */
  583. 05133   clock_t child_utime;          /* cumulative user time of children */
  584. 05134   clock_t child_stime;          /* cumulative sys time of children */
  585. 05135   clock_t p_alarm;              /* time of next alarm in ticks, or 0 */
  586. 05136
  587. 05137   struct proc *p_callerq;       /* head of list of procs wishing to send */
  588. 05138   struct proc *p_sendlink;      /* link to next proc wishing to send */
  589. 05139   message *p_messbuf;           /* pointer to message buffer */
  590. 05140   int p_getfrom;                /* from whom does process want to receive? */
  591. 05141   int p_sendto;
  592. 05142
  593. 05143   struct proc *p_nextready;     /* pointer to next ready process */
  594. 05144   sigset_t p_pending;           /* bit map for pending signals */
  595. 05145   unsigned p_pendcount;         /* count of pending and unfinished signals */
  596. 05146
  597. 05147   char p_name[16];              /* name of the process */
  598. 05148 };
  599. 05149
  600. 05150 /* Guard word for task stacks. */
  601. 05151 #define STACK_GUARD     ((reg_t) (sizeof(reg_t) == 2 ? 0xBEEF : 0xDEADBEEF))
  602. 05152
  603. 05153 /* Bits for p_flags in proc[].  A process is runnable iff p_flags == 0. */
  604. 05154 #define P_SLOT_FREE      001    /* set when slot is not in use */
  605. 05155 #define NO_MAP           002    /* keeps unmapped forked child from running */
  606. 05156 #define SENDING          004    /* set when process blocked trying to send */
  607. 05157 #define RECEIVING        010    /* set when process blocked trying to recv */
  608. 05158 #define PENDING          020    /* set when inform() of signal pending */
  609. 05159 #define SIG_PENDING      040    /* keeps to-be-signalled proc from running */
  610. 05160 #define P_STOP          0100    /* set when process is being traced */
  611. 05161
  612. 05162 /* Magic process table addresses. */
  613. 05163 #define BEG_PROC_ADDR (&proc[0])
  614. 05164 #define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS])
  615. 05165 #define END_TASK_ADDR (&proc[NR_TASKS])
  616. 05166 #define BEG_SERV_ADDR (&proc[NR_TASKS])
  617. 05167 #define BEG_USER_ADDR (&proc[NR_TASKS + LOW_USER])
  618. 05168
  619. 05169 #define NIL_PROC          ((struct proc *) 0)
  620. 05170 #define isidlehardware(n) ((n) == IDLE || (n) == HARDWARE)
  621. 05171 #define isokprocn(n)      ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS)
  622. 05172 #define isoksrc_dest(n)   (isokprocn(n) || (n) == ANY)
  623. 05173 #define isoksusern(n)     ((unsigned) (n) < NR_PROCS)
  624. 05174 #define isokusern(n)      ((unsigned) ((n) - LOW_USER) < NR_PROCS - LOW_USER)
  625. 05175 #define isrxhardware(n)   ((n) == ANY || (n) == HARDWARE)
  626. 05176 #define issysentn(n)      ((n) == FS_PROC_NR || (n) == MM_PROC_NR)
  627. 05177 #define istaskp(p)        ((p) < END_TASK_ADDR && (p) != proc_addr(IDLE))
  628. 05178 #define isuserp(p)        ((p) >= BEG_USER_ADDR)
  629. 05179 #define proc_addr(n)      (pproc_addr + NR_TASKS)[(n)]
  630. 05180 #define cproc_addr(n)     (&(proc + NR_TASKS)[(n)])
  631. 05181 #define proc_number(p)    ((p)->p_nr)
  632. 05182 #define proc_vir2phys(p, vir) 
  633. 05183                           (((phys_bytes)(p)->p_map[D].mem_phys << CLICK_SHIFT) 
  634. 05184                                                         + (vir_bytes) (vir))
  635. 05185
  636. 05186 EXTERN struct proc proc[NR_TASKS + NR_PROCS];   /* process table */
  637. 05187 EXTERN struct proc *pproc_addr[NR_TASKS + NR_PROCS];
  638. 05188 /* ptrs to process table slots; fast because now a process entry can be found
  639. 05189    by indexing the pproc_addr array, while accessing an element i requires
  640. 05190    a multiplication with sizeof(struct proc) to determine the address */
  641. 05191 EXTERN struct proc *bill_ptr;   /* ptr to process to bill for clock ticks */
  642. 05192 EXTERN struct proc *rdy_head[NQ];       /* pointers to ready list headers */
  643. 05193 EXTERN struct proc *rdy_tail[NQ];       /* pointers to ready list tails */
  644. 05194
  645. 05195 #endif /* PROC_H */
  646. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  647. src/kernel/protect.h    
  648. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  649. 05200 /* Constants for protected mode. */
  650. 05201
  651. 05202 /* Table sizes. */
  652. 05203 #define GDT_SIZE (FIRST_LDT_INDEX + NR_TASKS + NR_PROCS) /* spec. and LDT's */
  653. 05204 #define IDT_SIZE (IRQ8_VECTOR + 8)      /* only up to the highest vector */
  654. 05205 #define LDT_SIZE         2      /* contains CS and DS only */
  655. 05206
  656. 05207 /* Fixed global descriptors.  1 to 7 are prescribed by the BIOS. */
  657. 05208 #define GDT_INDEX        1      /* GDT descriptor */
  658. 05209 #define IDT_INDEX        2      /* IDT descriptor */
  659. 05210 #define DS_INDEX         3      /* kernel DS */
  660. 05211 #define ES_INDEX         4      /* kernel ES (386: flag 4 Gb at startup) */
  661. 05212 #define SS_INDEX         5      /* kernel SS (386: monitor SS at startup) */
  662. 05213 #define CS_INDEX         6      /* kernel CS */
  663. 05214 #define MON_CS_INDEX     7      /* temp for BIOS (386: monitor CS at startup) */
  664. 05215 #define TSS_INDEX        8      /* kernel TSS */
  665. 05216 #define DS_286_INDEX     9      /* scratch 16-bit source segment */
  666. 05217 #define ES_286_INDEX    10      /* scratch 16-bit destination segment */
  667. 05218 #define VIDEO_INDEX     11      /* video memory segment */
  668. 05219 #define DP_ETH0_INDEX   12      /* Western Digital Etherplus buffer */
  669. 05220 #define DP_ETH1_INDEX   13      /* Western Digital Etherplus buffer */
  670. 05221 #define FIRST_LDT_INDEX 14      /* rest of descriptors are LDT's */
  671. 05222
  672. 05223 #define GDT_SELECTOR      0x08  /* (GDT_INDEX * DESC_SIZE) bad for asld */
  673. 05224 #define IDT_SELECTOR      0x10  /* (IDT_INDEX * DESC_SIZE) */
  674. 05225 #define DS_SELECTOR       0x18  /* (DS_INDEX * DESC_SIZE) */
  675. 05226 #define ES_SELECTOR       0x20  /* (ES_INDEX * DESC_SIZE) */
  676. 05227 #define FLAT_DS_SELECTOR  0x21  /* less privileged ES */
  677. 05228 #define SS_SELECTOR       0x28  /* (SS_INDEX * DESC_SIZE) */
  678. 05229 #define CS_SELECTOR       0x30  /* (CS_INDEX * DESC_SIZE) */
  679. 05230 #define MON_CS_SELECTOR   0x38  /* (MON_CS_INDEX * DESC_SIZE) */
  680. 05231 #define TSS_SELECTOR      0x40  /* (TSS_INDEX * DESC_SIZE) */
  681. 05232 #define DS_286_SELECTOR   0x49  /* (DS_286_INDEX * DESC_SIZE + 1) */
  682. 05233 #define ES_286_SELECTOR   0x51  /* (ES_286_INDEX * DESC_SIZE + 1) */
  683. 05234 #define VIDEO_SELECTOR    0x59  /* (VIDEO_INDEX * DESC_SIZE + 1) */
  684. 05235 #define DP_ETH0_SELECTOR  0x61  /* (DP_ETH0_INDEX * DESC_SIZE) */
  685. 05236 #define DP_ETH1_SELECTOR  0x69  /* (DP_ETH1_INDEX * DESC_SIZE) */
  686. 05237
  687. 05238 /* Fixed local descriptors. */
  688. 05239 #define CS_LDT_INDEX     0      /* process CS */
  689. 05240 #define DS_LDT_INDEX     1      /* process DS=ES=FS=GS=SS */
  690. 05241
  691. 05242 /* Privileges. */
  692. 05243 #define INTR_PRIVILEGE   0      /* kernel and interrupt handlers */
  693. 05244 #define TASK_PRIVILEGE   1
  694. 05245 #define USER_PRIVILEGE   3
  695. 05246
  696. 05247 /* 286 hardware constants. */
  697. 05248
  698. 05249 /* Exception vector numbers. */
  699. 05250 #define BOUNDS_VECTOR       5   /* bounds check failed */
  700. 05251 #define INVAL_OP_VECTOR     6   /* invalid opcode */
  701. 05252 #define COPROC_NOT_VECTOR   7   /* coprocessor not available */
  702. 05253 #define DOUBLE_FAULT_VECTOR 8
  703. 05254 #define COPROC_SEG_VECTOR   9   /* coprocessor segment overrun */
  704. 05255 #define INVAL_TSS_VECTOR   10   /* invalid TSS */
  705. 05256 #define SEG_NOT_VECTOR     11   /* segment not present */
  706. 05257 #define STACK_FAULT_VECTOR 12   /* stack exception */
  707. 05258 #define PROTECTION_VECTOR  13   /* general protection */
  708. 05259
  709. 05260 /* Selector bits. */
  710. 05261 #define TI            0x04      /* table indicator */
  711. 05262 #define RPL           0x03      /* requester privilege level */
  712. 05263
  713. 05264 /* Descriptor structure offsets. */
  714. 05265 #define DESC_BASE        2      /* to base_low */
  715. 05266 #define DESC_BASE_MIDDLE 4      /* to base_middle */
  716. 05267 #define DESC_ACCESS      5      /* to access byte */
  717. 05268 #define DESC_SIZE        8      /* sizeof (struct segdesc_s) */
  718. 05269
  719. 05270 /* Segment sizes. */
  720. 05271 #define MAX_286_SEG_SIZE 0x10000L
  721. 05272
  722. 05273 /* Base and limit sizes and shifts. */
  723. 05274 #define BASE_MIDDLE_SHIFT   16  /* shift for base --> base_middle */
  724. 05275
  725. 05276 /* Access-byte and type-byte bits. */
  726. 05277 #define PRESENT       0x80      /* set for descriptor present */
  727. 05278 #define DPL           0x60      /* descriptor privilege level mask */
  728. 05279 #define DPL_SHIFT        5
  729. 05280 #define SEGMENT       0x10      /* set for segment-type descriptors */
  730. 05281
  731. 05282 /* Access-byte bits. */
  732. 05283 #define EXECUTABLE    0x08      /* set for executable segment */
  733. 05284 #define CONFORMING    0x04      /* set for conforming segment if executable */
  734. 05285 #define EXPAND_DOWN   0x04      /* set for expand-down segment if !executable*/
  735. 05286 #define READABLE      0x02      /* set for readable segment if executable */
  736. 05287 #define WRITEABLE     0x02      /* set for writeable segment if !executable */
  737. 05288 #define TSS_BUSY      0x02      /* set if TSS descriptor is busy */
  738. 05289 #define ACCESSED      0x01      /* set if segment accessed */
  739. 05290
  740. 05291 /* Special descriptor types. */
  741. 05292 #define AVL_286_TSS      1      /* available 286 TSS */
  742. 05293 #define LDT              2      /* local descriptor table */
  743. 05294 #define BUSY_286_TSS     3      /* set transparently to the software */
  744. 05295 #define CALL_286_GATE    4      /* not used */
  745. 05296 #define TASK_GATE        5      /* only used by debugger */
  746. 05297 #define INT_286_GATE     6      /* interrupt gate, used for all vectors */
  747. 05298 #define TRAP_286_GATE    7      /* not used */
  748. 05299
  749. 05300 /* Extra 386 hardware constants. */
  750. 05301
  751. 05302 /* Exception vector numbers. */
  752. 05303 #define PAGE_FAULT_VECTOR   14
  753. 05304 #define COPROC_ERR_VECTOR   16  /* coprocessor error */
  754. 05305
  755. 05306 /* Descriptor structure offsets. */
  756. 05307 #define DESC_GRANULARITY     6  /* to granularity byte */
  757. 05308 #define DESC_BASE_HIGH       7  /* to base_high */
  758. 05309
  759. 05310 /* Base and limit sizes and shifts. */
  760. 05311 #define BASE_HIGH_SHIFT     24  /* shift for base --> base_high */
  761. 05312 #define BYTE_GRAN_MAX   0xFFFFFL   /* maximum size for byte granular segment */
  762. 05313 #define GRANULARITY_SHIFT   16  /* shift for limit --> granularity */
  763. 05314 #define OFFSET_HIGH_SHIFT   16  /* shift for (gate) offset --> offset_high */
  764. 05315 #define PAGE_GRAN_SHIFT     12  /* extra shift for page granular limits */
  765. 05316
  766. 05317 /* Type-byte bits. */
  767. 05318 #define DESC_386_BIT      0x08  /* 386 types are obtained by ORing with this */
  768. 05319                                 /* LDT's and TASK_GATE's don't need it */
  769. 05320
  770. 05321 /* Granularity byte. */
  771. 05322 #define GRANULAR          0x80  /* set for 4K granularilty */
  772. 05323 #define DEFAULT           0x40  /* set for 32-bit defaults (executable seg) */
  773. 05324 #define BIG               0x40  /* set for "BIG" (expand-down seg) */
  774. 05325 #define AVL               0x10  /* 0 for available */
  775. 05326 #define LIMIT_HIGH        0x0F  /* mask for high bits of limit */
  776. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  777. src/kernel/sconst.h    
  778. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  779. 05400 ! Miscellaneous constants used in assembler code.
  780. 05401 W               =       _WORD_SIZE      ! Machine word size.
  781. 05402
  782. 05403 ! Offsets in struct proc. They MUST match proc.h.
  783. 05404 P_STACKBASE     =       0
  784. 05405 #if _WORD_SIZE == 2
  785. 05406 ESREG           =       P_STACKBASE
  786. 05407 #else
  787. 05408 GSREG           =       P_STACKBASE
  788. 05409 FSREG           =       GSREG + 2       ! 386 introduces FS and GS segments
  789. 05410 ESREG           =       FSREG + 2
  790. 05411 #endif
  791. 05412 DSREG           =       ESREG + 2
  792. 05413 DIREG           =       DSREG + 2
  793. 05414 SIREG           =       DIREG + W
  794. 05415 BPREG           =       SIREG + W
  795. 05416 STREG           =       BPREG + W       ! hole for another SP
  796. 05417 BXREG           =       STREG + W
  797. 05418 DXREG           =       BXREG + W
  798. 05419 CXREG           =       DXREG + W
  799. 05420 AXREG           =       CXREG + W
  800. 05421 RETADR          =       AXREG + W       ! return address for save() call
  801. 05422 PCREG           =       RETADR + W
  802. 05423 CSREG           =       PCREG + W
  803. 05424 PSWREG          =       CSREG + W
  804. 05425 SPREG           =       PSWREG + W
  805. 05426 SSREG           =       SPREG + W
  806. 05427 P_STACKTOP      =       SSREG + W
  807. 05428 P_LDT_SEL       =       P_STACKTOP
  808. 05429 P_LDT           =       P_LDT_SEL + W
  809. 05430
  810. 05431 #if _WORD_SIZE == 2
  811. 05432 Msize           =       12              ! size of a message in 16-bit words
  812. 05433 #else
  813. 05434 Msize           =       9               ! size of a message in 32-bit words
  814. 05435 #endif
  815. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  816. src/kernel/assert.h    
  817. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  818. 05500 /*
  819. 05501 assert.h
  820. 05502 */
  821. 05503 #ifndef ASSERT_H
  822. 05504 #define ASSERT_H
  823. 05505
  824. 05506 #if DEBUG
  825. 05507
  826. 05508 #define INIT_ASSERT     static char *assert_file= __FILE__;
  827. 05509
  828. 05510 void bad_assertion(char *file, int line, char *what);
  829. 05511 void bad_compare(char *file, int line, int lhs, char *what, int rhs);
  830. 05512
  831. 05513 #define assert(x)       (!(x) ? bad_assertion(assert_file, __LINE__, #x) 
  832. 05514                                                                 : (void) 0)
  833. 05515 #define compare(a,t,b)  (!((a) t (b)) ? bad_compare(assert_file, __LINE__, 
  834. 05516                                 (a), #a " " #t " " #b, (b)) : (void) 0)
  835. 05517 #else /* !DEBUG */
  836. 05518
  837. 05519 #define INIT_ASSERT     /* nothing */
  838. 05520
  839. 05521 #define assert(x)       (void)0
  840. 05522 #define compare(a,t,b)  (void)0
  841. 05523
  842. 05524 #endif /* !DEBUG */
  843. 05525
  844. 05526 #endif /* ASSERT_H */
  845. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  846. src/kernel/table.c    
  847. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  848. 05600 /* The object file of "table.c" contains all the data.  In the *.h files, 
  849. 05601  * declared variables appear with EXTERN in front of them, as in
  850. 05602  *
  851. 05603  *    EXTERN int x;
  852. 05604  *
  853. 05605  * Normally EXTERN is defined as extern, so when they are included in another
  854. 05606  * file, no storage is allocated.  If the EXTERN were not present, but just
  855. 05607  * say,
  856. 05608  *
  857. 05609  *    int x;
  858. 05610  *
  859. 05611  * then including this file in several source files would cause 'x' to be
  860. 05612  * declared several times.  While some linkers accept this, others do not,
  861. 05613  * so they are declared extern when included normally.  However, it must
  862. 05614  * be declared for real somewhere.  That is done here, by redefining
  863. 05615  * EXTERN as the null string, so the inclusion of all the *.h files in
  864. 05616  * table.c actually generates storage for them.  All the initialized
  865. 05617  * variables are also declared here, since
  866. 05618  *
  867. 05619  * extern int x = 4;
  868. 05620  *
  869. 05621  * is not allowed.  If such variables are shared, they must also be declared
  870. 05622  * in one of the *.h files without the initialization.
  871. 05623  */
  872. 05624
  873. 05625 #define _TABLE
  874. 05626
  875. 05627 #include "kernel.h"
  876. 05628 #include <termios.h>
  877. 05629 #include <minix/com.h>
  878. 05630 #include "proc.h"
  879. 05631 #include "tty.h"
  880. 05632
  881. 05633 /* The startup routine of each task is given below, from -NR_TASKS upwards.
  882. 05634  * The order of the names here MUST agree with the numerical values assigned to
  883. 05635  * the tasks in <minix/com.h>.
  884. 05636  */
  885. 05637 #define SMALL_STACK     (128 * sizeof(char *))
  886. 05638
  887. 05639 #define TTY_STACK       (3 * SMALL_STACK)
  888. 05640 #define SYN_ALRM_STACK  SMALL_STACK
  889. 05641
  890. 05642 #define DP8390_STACK    (SMALL_STACK * ENABLE_NETWORKING)
  891. 05643
  892. 05644 #if (CHIP == INTEL)
  893. 05645 #define IDLE_STACK      ((3+3+4) * sizeof(char *))  /* 3 intr, 3 temps, 4 db */
  894. 05646 #else
  895. 05647 #define IDLE_STACK      SMALL_STACK
  896. 05648 #endif
  897. 05649
  898. 05650 #define PRINTER_STACK   SMALL_STACK
  899. 05651
  900. 05652 #if (CHIP == INTEL)
  901. 05653 #define WINCH_STACK     (2 * SMALL_STACK * ENABLE_WINI)
  902. 05654 #else
  903. 05655 #define WINCH_STACK     (3 * SMALL_STACK * ENABLE_WINI)
  904. 05656 #endif
  905. 05657
  906. 05658 #if (MACHINE == ATARI)
  907. 05659 #define SCSI_STACK      (3 * SMALL_STACK)
  908. 05660 #endif
  909. 05661
  910. 05662 #if (MACHINE == IBM_PC)
  911. 05663 #define SCSI_STACK      (2 * SMALL_STACK * ENABLE_SCSI)
  912. 05664 #endif
  913. 05665
  914. 05666 #define CDROM_STACK     (4 * SMALL_STACK * ENABLE_CDROM)
  915. 05667 #define AUDIO_STACK     (4 * SMALL_STACK * ENABLE_AUDIO)
  916. 05668 #define MIXER_STACK     (4 * SMALL_STACK * ENABLE_AUDIO)
  917. 05669
  918. 05670 #define FLOP_STACK      (3 * SMALL_STACK)
  919. 05671 #define MEM_STACK       SMALL_STACK
  920. 05672 #define CLOCK_STACK     SMALL_STACK
  921. 05673 #define SYS_STACK       SMALL_STACK
  922. 05674 #define HARDWARE_STACK  0               /* dummy task, uses kernel stack */
  923. 05675
  924. 05676
  925. 05677 #define TOT_STACK_SPACE         (TTY_STACK + DP8390_STACK + SCSI_STACK + 
  926. 05678         SYN_ALRM_STACK + IDLE_STACK + HARDWARE_STACK + PRINTER_STACK + 
  927. 05679         WINCH_STACK + FLOP_STACK + MEM_STACK + CLOCK_STACK + SYS_STACK + 
  928. 05680         CDROM_STACK + AUDIO_STACK + MIXER_STACK)
  929. 05681
  930. 05682
  931. 05683 /* SCSI, CDROM and AUDIO may in the future have different choices like
  932. 05684  * WINCHESTER, but for now the choice is fixed.
  933. 05685  */
  934. 05686 #define scsi_task       aha_scsi_task
  935. 05687 #define cdrom_task      mcd_task
  936. 05688 #define audio_task      dsp_task
  937. 05689
  938. 05690
  939. 05691 /*
  940. 05692  * Some notes about the following table:
  941. 05693  *  1) The tty_task should always be first so that other tasks can use printf
  942. 05694  *     if their initialisation has problems.
  943. 05695  *  2) If you add a new kernel task, add it before the printer task.
  944. 05696  *  3) The task name is used for the process name (p_name).
  945. 05697  */
  946. 05698
  947. 05699 PUBLIC struct tasktab tasktab[] = {
  948. 05700         { tty_task,             TTY_STACK,      "TTY"           },
  949. 05701 #if ENABLE_NETWORKING
  950. 05702         { dp8390_task,          DP8390_STACK,   "DP8390"        },
  951. 05703 #endif
  952. 05704 #if ENABLE_CDROM
  953. 05705         { cdrom_task,           CDROM_STACK,    "CDROM"         },
  954. 05706 #endif
  955. 05707 #if ENABLE_AUDIO
  956. 05708         { audio_task,           AUDIO_STACK,    "AUDIO"         },
  957. 05709         { mixer_task,           MIXER_STACK,    "MIXER"         },
  958. 05710 #endif
  959. 05711 #if ENABLE_SCSI
  960. 05712         { scsi_task,            SCSI_STACK,     "SCSI"          },
  961. 05713 #endif
  962. 05714 #if ENABLE_WINI
  963. 05715         { winchester_task,      WINCH_STACK,    "WINCH"         },
  964. 05716 #endif
  965. 05717         { syn_alrm_task,        SYN_ALRM_STACK, "SYN_AL"        },
  966. 05718         { idle_task,            IDLE_STACK,     "IDLE"          },
  967. 05719         { printer_task,         PRINTER_STACK,  "PRINTER"       },
  968. 05720         { floppy_task,          FLOP_STACK,     "FLOPPY"        },
  969. 05721         { mem_task,             MEM_STACK,      "MEMORY"        },
  970. 05722         { clock_task,           CLOCK_STACK,    "CLOCK"         },
  971. 05723         { sys_task,             SYS_STACK,      "SYS"           },
  972. 05724         { 0,                    HARDWARE_STACK, "HARDWAR"       },
  973. 05725         { 0,                    0,              "MM"            },
  974. 05726         { 0,                    0,              "FS"            },
  975. 05727 #if ENABLE_NETWORKING
  976. 05728         { 0,                    0,              "INET"          },
  977. 05729 #endif
  978. 05730         { 0,                    0,              "INIT"          },
  979. 05731 };
  980. 05732
  981. 05733 /* Stack space for all the task stacks.  (Declared as (char *) to align it.) */
  982. 05734 PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
  983. 05735
  984. 05736 /*
  985. 05737  * The number of kernel tasks must be the same as NR_TASKS.
  986. 05738  * If NR_TASKS is not correct then you will get the compile error:
  987. 05739  *   "array size is negative"
  988. 05740  */
  989. 05741
  990. 05742 #define NKT (sizeof tasktab / sizeof (struct tasktab) - (INIT_PROC_NR + 1))
  991. 05743
  992. 05744 extern int dummy_tasktab_check[NR_TASKS == NKT ? 1 : -1];
  993. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  994. src/kernel/mpx.s    
  995. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  996. 05800 #
  997. 05801 ! Chooses between the 8086 and 386 versions of the Minix startup code.
  998. 05802
  999. 05803 #include <minix/config.h>
  1000. 05804 #if _WORD_SIZE == 2
  1001. 05805 #include "mpx88.s"
  1002. 05806 #else
  1003. 05807 #include "mpx386.s"
  1004. 05808 #endif
  1005. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1006. src/kernel/mpx386.s    
  1007. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1008. 05900 #
  1009. 05901 ! This file contains the assembler startup code for Minix and the 32-bit
  1010. 05902 ! interrupt handlers.  It cooperates with start.c to set up a good
  1011. 05903 ! environment for main().
  1012. 05904
  1013. 05905 ! This file is part of the lowest layer of the MINIX kernel.  The other part
  1014. 05906 ! is "proc.c".  The lowest layer does process switching and message handling.
  1015. 05907
  1016. 05908 ! Every transition to the kernel goes through this file.  Transitions are
  1017. 05909 ! caused by sending/receiving messages and by most interrupts.  (RS232
  1018. 05910 ! interrupts may be handled in the file "rs2.s" and then they rarely enter
  1019. 05911 ! the kernel.)
  1020. 05912
  1021. 05913 ! Transitions to the kernel may be nested.  The initial entry may be with a
  1022. 05914 ! system call, exception or hardware interrupt; reentries may only be made
  1023. 05915 ! by hardware interrupts.  The count of reentries is kept in "k_reenter".
  1024. 05916 ! It is important for deciding whether to switch to the kernel stack and
  1025. 05917 ! for protecting the message passing code in "proc.c".
  1026. 05918
  1027. 05919 ! For the message passing trap, most of the machine state is saved in the
  1028. 05920 ! proc table.  (Some of the registers need not be saved.)  Then the stack is
  1029. 05921 ! switched to "k_stack", and interrupts are reenabled.  Finally, the system
  1030. 05922 ! call handler (in C) is called.  When it returns, interrupts are disabled
  1031. 05923 ! again and the code falls into the restart routine, to finish off held-up
  1032. 05924 ! interrupts and run the process or task whose pointer is in "proc_ptr".
  1033. 05925
  1034. 05926 ! Hardware interrupt handlers do the same, except  (1) The entire state must
  1035. 05927 ! be saved.  (2) There are too many handlers to do this inline, so the save
  1036. 05928 ! routine is called.  A few cycles are saved by pushing the address of the
  1037. 05929 ! appropiate restart routine for a return later.  (3) A stack switch is
  1038. 05930 ! avoided when the stack is already switched.  (4) The (master) 8259 interrupt
  1039. 05931 ! controller is reenabled centrally in save().  (5) Each interrupt handler
  1040. 05932 ! masks its interrupt line using the 8259 before enabling (other unmasked)
  1041. 05933 ! interrupts, and unmasks it after servicing the interrupt.  This limits the
  1042. 05934 ! nest level to the number of lines and protects the handler from itself.
  1043. 05935
  1044. 05936 ! For communication with the boot monitor at startup time some constant
  1045. 05937 ! data are compiled into the beginning of the text segment. This facilitates 
  1046. 05938 ! reading the data at the start of the boot process, since only the first
  1047. 05939 ! sector of the file needs to be read.
  1048. 05940
  1049. 05941 ! Some data storage is also allocated at the end of this file. This data 
  1050. 05942 ! will be at the start of the data segment of the kernel and will be read
  1051. 05943 ! and modified by the boot monitor before the kernel starts.
  1052. 05944
  1053. 05945 ! sections
  1054. 05946
  1055. 05947 .sect .text
  1056. 05948 begtext:
  1057. 05949 .sect .rom
  1058. 05950 begrom:
  1059. 05951 .sect .data
  1060. 05952 begdata:
  1061. 05953 .sect .bss
  1062. 05954 begbss:
  1063. 05955
  1064. 05956 #include <minix/config.h>
  1065. 05957 #include <minix/const.h>
  1066. 05958 #include <minix/com.h>
  1067. 05959 #include "const.h"
  1068. 05960 #include "protect.h"
  1069. 05961 #include "sconst.h"
  1070. 05962
  1071. 05963 /* Selected 386 tss offsets. */
  1072. 05964 #define TSS3_S_SP0      4
  1073. 05965
  1074. 05966 ! Exported functions
  1075. 05967 ! Note: in assembly language the .define statement applied to a function name 
  1076. 05968 ! is loosely equivalent to a prototype in C code -- it makes it possible to
  1077. 05969 ! link to an entity declared in the assembly code but does not create
  1078. 05970 ! the entity.
  1079. 05971
  1080. 05972 .define _idle_task
  1081. 05973 .define _restart
  1082. 05974 .define save
  1083. 05975
  1084. 05976 .define _divide_error
  1085. 05977 .define _single_step_exception
  1086. 05978 .define _nmi
  1087. 05979 .define _breakpoint_exception
  1088. 05980 .define _overflow
  1089. 05981 .define _bounds_check
  1090. 05982 .define _inval_opcode
  1091. 05983 .define _copr_not_available
  1092. 05984 .define _double_fault
  1093. 05985 .define _copr_seg_overrun
  1094. 05986 .define _inval_tss
  1095. 05987 .define _segment_not_present
  1096. 05988 .define _stack_exception
  1097. 05989 .define _general_protection
  1098. 05990 .define _page_fault
  1099. 05991 .define _copr_error
  1100. 05992
  1101. 05993 .define _hwint00        ! handlers for hardware interrupts
  1102. 05994 .define _hwint01
  1103. 05995 .define _hwint02
  1104. 05996 .define _hwint03
  1105. 05997 .define _hwint04
  1106. 05998 .define _hwint05
  1107. 05999 .define _hwint06
  1108. 06000 .define _hwint07
  1109. 06001 .define _hwint08
  1110. 06002 .define _hwint09
  1111. 06003 .define _hwint10
  1112. 06004 .define _hwint11
  1113. 06005 .define _hwint12
  1114. 06006 .define _hwint13
  1115. 06007 .define _hwint14
  1116. 06008 .define _hwint15
  1117. 06009
  1118. 06010 .define _s_call
  1119. 06011 .define _p_s_call
  1120. 06012 .define _level0_call
  1121. 06013
  1122. 06014 ! Imported functions.
  1123. 06015
  1124. 06016 .extern _cstart
  1125. 06017 .extern _main
  1126. 06018 .extern _exception
  1127. 06019 .extern _interrupt
  1128. 06020 .extern _sys_call
  1129. 06021 .extern _unhold
  1130. 06022
  1131. 06023 ! Exported variables.
  1132. 06024 ! Note: when used with a variable the .define does not reserve storage,
  1133. 06025 ! it makes the name externally visible so it may be linked to. 
  1134. 06026
  1135. 06027 .define begbss
  1136. 06028 .define begdata
  1137. 06029 .define _sizes
  1138. 06030
  1139. 06031 ! Imported variables.
  1140. 06032
  1141. 06033 .extern _gdt
  1142. 06034 .extern _code_base
  1143. 06035 .extern _data_base
  1144. 06036 .extern _held_head
  1145. 06037 .extern _k_reenter
  1146. 06038 .extern _pc_at
  1147. 06039 .extern _proc_ptr
  1148. 06040 .extern _ps_mca
  1149. 06041 .extern _tss
  1150. 06042 .extern _level0_func
  1151. 06043 .extern _mon_sp
  1152. 06044 .extern _mon_return
  1153. 06045 .extern _reboot_code
  1154. 06046
  1155. 06047 .sect .text
  1156. 06048 !*===========================================================================*
  1157. 06049 !*                              MINIX                                        *
  1158. 06050 !*===========================================================================*
  1159. 06051 MINIX:                          ! this is the entry point for the MINIX kernel
  1160. 06052         jmp     over_flags      ! skip over the next few bytes
  1161. 06053         .data2  CLICK_SHIFT     ! for the monitor: memory granularity
  1162. 06054 flags:
  1163. 06055         .data2  0x002D          ! boot monitor flags:
  1164. 06056                                 !       call in 386 mode, make stack,
  1165. 06057                                 !       load high, will return
  1166. 06058         nop                     ! extra byte to sync up disassembler
  1167. 06059 over_flags:
  1168. 06060
  1169. 06061 ! Set up a C stack frame on the monitor stack.  (The monitor sets cs and ds
  1170. 06062 ! right.  The ss descriptor still references the monitor data segment.)
  1171. 06063         movzx   esp, sp         ! monitor stack is a 16 bit stack
  1172. 06064         push    ebp
  1173. 06065         mov     ebp, esp
  1174. 06066         push    esi
  1175. 06067         push    edi
  1176. 06068         cmp     4(ebp), 0       ! nonzero if return possible
  1177. 06069         jz      noret
  1178. 06070         inc     (_mon_return)
  1179. 06071 noret:  mov     (_mon_sp), esp  ! save stack pointer for later return
  1180. 06072
  1181. 06073 ! Copy the monitor global descriptor table to the address space of kernel and
  1182. 06074 ! switch over to it.  Prot_init() can then update it with immediate effect.
  1183. 06075
  1184. 06076         sgdt    (_gdt+GDT_SELECTOR)             ! get the monitor gdtr
  1185. 06077         mov     esi, (_gdt+GDT_SELECTOR+2)      ! absolute address of GDT
  1186. 06078         mov     ebx, _gdt                       ! address of kernel GDT
  1187. 06079         mov     ecx, 8*8                        ! copying eight descriptors
  1188. 06080 copygdt:
  1189. 06081  eseg   movb    al, (esi)
  1190. 06082         movb    (ebx), al
  1191. 06083         inc     esi
  1192. 06084         inc     ebx
  1193. 06085         loop    copygdt
  1194. 06086         mov     eax, (_gdt+DS_SELECTOR+2)       ! base of kernel data
  1195. 06087         and     eax, 0x00FFFFFF                 ! only 24 bits
  1196. 06088         add     eax, _gdt                       ! eax = vir2phys(gdt)
  1197. 06089         mov     (_gdt+GDT_SELECTOR+2), eax      ! set base of GDT
  1198. 06090         lgdt    (_gdt+GDT_SELECTOR)             ! switch over to kernel GDT
  1199. 06091
  1200. 06092 ! Locate boot parameters, set up kernel segment registers and stack.
  1201. 06093         mov     ebx, 8(ebp)     ! boot parameters offset
  1202. 06094         mov     edx, 12(ebp)    ! boot parameters length
  1203. 06095         mov     ax, ds          ! kernel data
  1204. 06096         mov     es, ax
  1205. 06097         mov     fs, ax
  1206. 06098         mov     gs, ax
  1207. 06099         mov     ss, ax
  1208. 06100         mov     esp, k_stktop   ! set sp to point to the top of kernel stack
  1209. 06101
  1210. 06102 ! Call C startup code to set up a proper environment to run main().
  1211. 06103         push    edx
  1212. 06104         push    ebx
  1213. 06105         push    SS_SELECTOR
  1214. 06106         push    MON_CS_SELECTOR
  1215. 06107         push    DS_SELECTOR
  1216. 06108         push    CS_SELECTOR
  1217. 06109         call    _cstart         ! cstart(cs, ds, mcs, mds, parmoff, parmlen)
  1218. 06110         add     esp, 6*4
  1219. 06111
  1220. 06112 ! Reload gdtr, idtr and the segment registers to global descriptor table set
  1221. 06113 ! up by prot_init().
  1222. 06114
  1223. 06115         lgdt    (_gdt+GDT_SELECTOR)
  1224. 06116         lidt    (_gdt+IDT_SELECTOR)
  1225. 06117
  1226. 06118         jmpf    CS_SELECTOR:csinit
  1227. 06119 csinit:
  1228. 06120     o16 mov     ax, DS_SELECTOR
  1229. 06121         mov     ds, ax
  1230. 06122         mov     es, ax
  1231. 06123         mov     fs, ax
  1232. 06124         mov     gs, ax
  1233. 06125         mov     ss, ax
  1234. 06126     o16 mov     ax, TSS_SELECTOR        ! no other TSS is used
  1235. 06127         ltr     ax
  1236. 06128         push    0                       ! set flags to known good state
  1237. 06129         popf                            ! esp, clear nested task and int enable
  1238. 06130
  1239. 06131         jmp     _main                   ! main()
  1240. 06132
  1241. 06133
  1242. 06134 !*===========================================================================*
  1243. 06135 !*                              interrupt handlers                           *
  1244. 06136 !*              interrupt handlers for 386 32-bit protected mode             *
  1245. 06137 !*===========================================================================*
  1246. 06138
  1247. 06139 !*===========================================================================*
  1248. 06140 !*                              hwint00 - 07                                 *
  1249. 06141 !*===========================================================================*
  1250. 06142 ! Note this is a macro, it looks like a subroutine.
  1251. 06143 #define hwint_master(irq)       
  1252. 06144         call    save                    /* save interrupted process state */;
  1253. 06145         inb     INT_CTLMASK                                                 ;
  1254. 06146         orb     al, [1<<irq]                                                ;
  1255. 06147         outb    INT_CTLMASK             /* disable the irq                */;
  1256. 06148         movb    al, ENABLE                                                  ;
  1257. 06149         outb    INT_CTL                 /* reenable master 8259           */;
  1258. 06150         sti                             /* enable interrupts              */;
  1259. 06151         push    irq                     /* irq                            */;
  1260. 06152         call    (_irq_table + 4*irq)    /* eax = (*irq_table[irq])(irq)   */;
  1261. 06153         pop     ecx                                                         ;
  1262. 06154         cli                             /* disable interrupts             */;
  1263. 06155         test    eax, eax                /* need to reenable irq?          */;
  1264. 06156         jz      0f                                                          ;
  1265. 06157         inb     INT_CTLMASK                                                 ;
  1266. 06158         andb    al, ~[1<<irq]                                               ;
  1267. 06159         outb    INT_CTLMASK             /* enable the irq                 */;
  1268. 06160 0:      ret                             /* restart (another) process      */
  1269. 06161
  1270. 06162 ! Each of these entry points is an expansion of the hwint_master macro
  1271. 06163         .align  16
  1272. 06164 _hwint00:               ! Interrupt routine for irq 0 (the clock).
  1273. 06165         hwint_master(0)
  1274. 06166
  1275. 06167         .align  16
  1276. 06168 _hwint01:               ! Interrupt routine for irq 1 (keyboard)
  1277. 06169         hwint_master(1)
  1278. 06170
  1279. 06171         .align  16
  1280. 06172 _hwint02:               ! Interrupt routine for irq 2 (cascade!)
  1281. 06173         hwint_master(2)
  1282. 06174
  1283. 06175         .align  16
  1284. 06176 _hwint03:               ! Interrupt routine for irq 3 (second serial)
  1285. 06177         hwint_master(3)
  1286. 06178
  1287. 06179         .align  16
  1288. 06180 _hwint04:               ! Interrupt routine for irq 4 (first serial)
  1289. 06181         hwint_master(4)
  1290. 06182
  1291. 06183         .align  16
  1292. 06184 _hwint05:               ! Interrupt routine for irq 5 (XT winchester)
  1293. 06185         hwint_master(5)
  1294. 06186
  1295. 06187         .align  16
  1296. 06188 _hwint06:               ! Interrupt routine for irq 6 (floppy)
  1297. 06189         hwint_master(6)
  1298. 06190
  1299. 06191         .align  16
  1300. 06192 _hwint07:               ! Interrupt routine for irq 7 (printer)
  1301. 06193         hwint_master(7)
  1302. 06194
  1303. 06195 !*===========================================================================*
  1304. 06196 !*                              hwint08 - 15                                 *
  1305. 06197 !*===========================================================================*
  1306. 06198 ! Note this is a macro, it looks like a subroutine.
  1307. 06199 #define hwint_slave(irq)        
  1308. 06200         call    save                    /* save interrupted process state */;
  1309. 06201         inb     INT2_CTLMASK                                                ;
  1310. 06202         orb     al, [1<<[irq-8]]                                            ;
  1311. 06203         outb    INT2_CTLMASK            /* disable the irq                */;
  1312. 06204         movb    al, ENABLE                                                  ;
  1313. 06205         outb    INT_CTL                 /* reenable master 8259           */;
  1314. 06206         jmp     .+2                     /* delay                          */;
  1315. 06207         outb    INT2_CTL                /* reenable slave 8259            */;
  1316. 06208         sti                             /* enable interrupts              */;
  1317. 06209         push    irq                     /* irq                            */;
  1318. 06210         call    (_irq_table + 4*irq)    /* eax = (*irq_table[irq])(irq)   */;
  1319. 06211         pop     ecx                                                         ;
  1320. 06212         cli                             /* disable interrupts             */;
  1321. 06213         test    eax, eax                /* need to reenable irq?          */;
  1322. 06214         jz      0f                                                          ;
  1323. 06215         inb     INT2_CTLMASK                                                ;
  1324. 06216         andb    al, ~[1<<[irq-8]]                                           ;
  1325. 06217         outb    INT2_CTLMASK            /* enable the irq                 */;
  1326. 06218 0:      ret                             /* restart (another) process      */
  1327. 06219
  1328. 06220 ! Each of these entry points is an expansion of the hwint_slave macro
  1329. 06221         .align  16
  1330. 06222 _hwint08:               ! Interrupt routine for irq 8 (realtime clock)
  1331. 06223         hwint_slave(8)
  1332. 06224
  1333. 06225         .align  16
  1334. 06226 _hwint09:               ! Interrupt routine for irq 9 (irq 2 redirected)
  1335. 06227         hwint_slave(9)
  1336. 06228
  1337. 06229         .align  16
  1338. 06230 _hwint10:               ! Interrupt routine for irq 10
  1339. 06231         hwint_slave(10)
  1340. 06232
  1341. 06233         .align  16
  1342. 06234 _hwint11:               ! Interrupt routine for irq 11
  1343. 06235         hwint_slave(11)
  1344. 06236
  1345. 06237         .align  16
  1346. 06238 _hwint12:               ! Interrupt routine for irq 12
  1347. 06239         hwint_slave(12)
  1348. 06240
  1349. 06241         .align  16
  1350. 06242 _hwint13:               ! Interrupt routine for irq 13 (FPU exception)
  1351. 06243         hwint_slave(13)
  1352. 06244
  1353. 06245         .align  16
  1354. 06246 _hwint14:               ! Interrupt routine for irq 14 (AT winchester)
  1355. 06247         hwint_slave(14)
  1356. 06248
  1357. 06249         .align  16
  1358. 06250 _hwint15:               ! Interrupt routine for irq 15
  1359. 06251         hwint_slave(15)
  1360. 06252
  1361. 06253 !*===========================================================================*
  1362. 06254 !*                              save                                         *
  1363. 06255 !*===========================================================================*
  1364. 06256 ! Save for protected mode.
  1365. 06257 ! This is much simpler than for 8086 mode, because the stack already points
  1366. 06258 ! into the process table, or has already been switched to the kernel stack.
  1367. 06259
  1368. 06260         .align  16
  1369. 06261 save:
  1370. 06262         cld                     ! set direction flag to a known value
  1371. 06263         pushad                  ! save "general" registers
  1372. 06264     o16 push    ds              ! save ds
  1373. 06265     o16 push    es              ! save es
  1374. 06266     o16 push    fs              ! save fs
  1375. 06267     o16 push    gs              ! save gs
  1376. 06268         mov     dx, ss          ! ss is kernel data segment
  1377. 06269         mov     ds, dx          ! load rest of kernel segments
  1378. 06270         mov     es, dx          ! kernel does not use fs, gs
  1379. 06271         mov     eax, esp        ! prepare to return
  1380. 06272         incb    (_k_reenter)    ! from -1 if not reentering
  1381. 06273         jnz     set_restart1    ! stack is already kernel stack
  1382. 06274         mov     esp, k_stktop
  1383. 06275         push    _restart        ! build return address for int handler
  1384. 06276         xor     ebp, ebp        ! for stacktrace
  1385. 06277         jmp     RETADR-P_STACKBASE(eax)
  1386. 06278
  1387. 06279         .align  4
  1388. 06280 set_restart1:
  1389. 06281         push    restart1
  1390. 06282         jmp     RETADR-P_STACKBASE(eax)
  1391. 06283
  1392. 06284 !*===========================================================================*
  1393. 06285 !*                              _s_call                                      *
  1394. 06286 !*===========================================================================*
  1395. 06287         .align  16
  1396. 06288 _s_call:
  1397. 06289 _p_s_call:
  1398. 06290         cld                     ! set direction flag to a known value
  1399. 06291         sub     esp, 6*4        ! skip RETADR, eax, ecx, edx, ebx, est
  1400. 06292         push    ebp             ! stack already points into proc table
  1401. 06293         push    esi
  1402. 06294         push    edi
  1403. 06295     o16 push    ds
  1404. 06296     o16 push    es
  1405. 06297     o16 push    fs
  1406. 06298     o16 push    gs
  1407. 06299         mov     dx, ss
  1408. 06300         mov     ds, dx
  1409. 06301         mov     es, dx
  1410. 06302         incb    (_k_reenter)
  1411. 06303         mov     esi, esp        ! assumes P_STACKBASE == 0
  1412. 06304         mov     esp, k_stktop
  1413. 06305         xor     ebp, ebp        ! for stacktrace
  1414. 06306                                 ! end of inline save
  1415. 06307         sti                     ! allow SWITCHER to be interrupted
  1416. 06308                                 ! now set up parameters for sys_call()
  1417. 06309         push    ebx             ! pointer to user message
  1418. 06310         push    eax             ! src/dest
  1419. 06311         push    ecx             ! SEND/RECEIVE/BOTH
  1420. 06312         call    _sys_call       ! sys_call(function, src_dest, m_ptr)
  1421. 06313                                 ! caller is now explicitly in proc_ptr
  1422. 06314         mov     AXREG(esi), eax ! sys_call MUST PRESERVE si
  1423. 06315         cli                     ! disable interrupts 
  1424. 06316
  1425. 06317 ! Fall into code to restart proc/task running.
  1426. 06318
  1427. 06319 !*===========================================================================*
  1428. 06320 !*                              restart                                      *
  1429. 06321 !*===========================================================================*
  1430. 06322 _restart:
  1431. 06323
  1432. 06324 ! Flush any held-up interrupts.
  1433. 06325 ! This reenables interrupts, so the current interrupt handler may reenter.
  1434. 06326 ! This does not matter, because the current handler is about to exit and no
  1435. 06327 ! other handlers can reenter since flushing is only done when k_reenter == 0.
  1436. 06328
  1437. 06329         cmp     (_held_head), 0 ! do fast test to usually avoid function call
  1438. 06330         jz      over_call_unhold
  1439. 06331         call    _unhold         ! this is rare so overhead acceptable
  1440. 06332 over_call_unhold:
  1441. 06333         mov     esp, (_proc_ptr)        ! will assume P_STACKBASE == 0
  1442. 06334         lldt    P_LDT_SEL(esp)          ! enable segment descriptors for task
  1443. 06335         lea     eax, P_STACKTOP(esp)    ! arrange for next interrupt
  1444. 06336         mov     (_tss+TSS3_S_SP0), eax  ! to save state in process table
  1445. 06337 restart1:
  1446. 06338         decb    (_k_reenter)
  1447. 06339     o16 pop     gs
  1448. 06340     o16 pop     fs
  1449. 06341     o16 pop     es
  1450. 06342     o16 pop     ds
  1451. 06343         popad
  1452. 06344         add     esp, 4          ! skip return adr
  1453. 06345         iretd                   ! continue process
  1454. 06346
  1455. 06347 !*===========================================================================*
  1456. 06348 !*                              exception handlers                           *
  1457. 06349 !*===========================================================================*
  1458. 06350 _divide_error:
  1459. 06351         push    DIVIDE_VECTOR
  1460. 06352         jmp     exception
  1461. 06353
  1462. 06354 _single_step_exception:
  1463. 06355         push    DEBUG_VECTOR
  1464. 06356         jmp     exception
  1465. 06357
  1466. 06358 _nmi:
  1467. 06359         push    NMI_VECTOR
  1468. 06360         jmp     exception
  1469. 06361
  1470. 06362 _breakpoint_exception:
  1471. 06363         push    BREAKPOINT_VECTOR
  1472. 06364         jmp     exception
  1473. 06365
  1474. 06366 _overflow:
  1475. 06367         push    OVERFLOW_VECTOR
  1476. 06368         jmp     exception
  1477. 06369
  1478. 06370 _bounds_check:
  1479. 06371         push    BOUNDS_VECTOR
  1480. 06372         jmp     exception
  1481. 06373
  1482. 06374 _inval_opcode:
  1483. 06375         push    INVAL_OP_VECTOR
  1484. 06376         jmp     exception
  1485. 06377
  1486. 06378 _copr_not_available:
  1487. 06379         push    COPROC_NOT_VECTOR
  1488. 06380         jmp     exception
  1489. 06381
  1490. 06382 _double_fault:
  1491. 06383         push    DOUBLE_FAULT_VECTOR
  1492. 06384         jmp     errexception
  1493. 06385
  1494. 06386 _copr_seg_overrun:
  1495. 06387         push    COPROC_SEG_VECTOR
  1496. 06388         jmp     exception
  1497. 06389
  1498. 06390 _inval_tss:
  1499. 06391         push    INVAL_TSS_VECTOR
  1500. 06392         jmp     errexception
  1501. 06393
  1502. 06394 _segment_not_present:
  1503. 06395         push    SEG_NOT_VECTOR
  1504. 06396         jmp     errexception
  1505. 06397
  1506. 06398 _stack_exception:
  1507. 06399         push    STACK_FAULT_VECTOR
  1508. 06400         jmp     errexception
  1509. 06401
  1510. 06402 _general_protection:
  1511. 06403         push    PROTECTION_VECTOR
  1512. 06404         jmp     errexception
  1513. 06405
  1514. 06406 _page_fault:
  1515. 06407         push    PAGE_FAULT_VECTOR
  1516. 06408         jmp     errexception
  1517. 06409
  1518. 06410 _copr_error:
  1519. 06411         push    COPROC_ERR_VECTOR
  1520. 06412         jmp     exception
  1521. 06413
  1522. 06414 !*===========================================================================*
  1523. 06415 !*                              exception                                    *
  1524. 06416 !*===========================================================================*
  1525. 06417 ! This is called for all exceptions which do not push an error code.
  1526. 06418
  1527. 06419         .align  16
  1528. 06420 exception:
  1529. 06421  sseg   mov     (trap_errno), 0         ! clear trap_errno
  1530. 06422  sseg   pop     (ex_number)
  1531. 06423         jmp     exception1
  1532. 06424
  1533. 06425 !*===========================================================================*
  1534. 06426 !*                              errexception                                 *
  1535. 06427 !*===========================================================================*
  1536. 06428 ! This is called for all exceptions which push an error code.
  1537. 06429
  1538. 06430         .align  16
  1539. 06431 errexception:
  1540. 06432  sseg   pop     (ex_number)
  1541. 06433  sseg   pop     (trap_errno)
  1542. 06434 exception1:                             ! Common for all exceptions.
  1543. 06435         push    eax                     ! eax is scratch register
  1544. 06436         mov     eax, 0+4(esp)           ! old eip
  1545. 06437  sseg   mov     (old_eip), eax
  1546. 06438         movzx   eax, 4+4(esp)           ! old cs
  1547. 06439  sseg   mov     (old_cs), eax
  1548. 06440         mov     eax, 8+4(esp)           ! old eflags
  1549. 06441  sseg   mov     (old_eflags), eax
  1550. 06442         pop     eax
  1551. 06443         call    save
  1552. 06444         push    (old_eflags)
  1553. 06445         push    (old_cs)
  1554. 06446         push    (old_eip)
  1555. 06447         push    (trap_errno)
  1556. 06448         push    (ex_number)
  1557. 06449         call    _exception              ! (ex_number, trap_errno, old_eip,
  1558. 06450                                         !       old_cs, old_eflags)
  1559. 06451         add     esp, 5*4
  1560. 06452         cli
  1561. 06453         ret
  1562. 06454
  1563. 06455 !*===========================================================================*
  1564. 06456 !*                              level0_call                                  *
  1565. 06457 !*===========================================================================*
  1566. 06458 _level0_call:
  1567. 06459         call    save
  1568. 06460         jmp     (_level0_func)
  1569. 06461
  1570. 06462 !*===========================================================================*
  1571. 06463 !*                              idle_task                                    *
  1572. 06464 !*===========================================================================*
  1573. 06465 _idle_task:                     ! executed when there is no work
  1574. 06466         jmp     _idle_task      ! a "hlt" before this fails in protected mode
  1575. 06467
  1576. 06468 !*===========================================================================*
  1577. 06469 !*                              data                                         *
  1578. 06470 !*===========================================================================*
  1579. 06471 ! These declarations assure that storage will be allocated at the very 
  1580. 06472 ! beginning of the kernel data section, so the boot monitor can be easily 
  1581. 06473 ! told how to patch these locations. Note that the magic number is put
  1582. 06474 ! here by the compiler, but will be read by, and then overwritten by,
  1583. 06475 ! the boot monitor. When the kernel starts the sizes array will be
  1584. 06476 ! found here, as if it had been initialized by the compiler.
  1585. 06477
  1586. 06478 .sect .rom      ! Before the string table please
  1587. 06479 _sizes:                         ! sizes of kernel, mm, fs filled in by boot
  1588. 06480         .data2  0x526F          ! this must be the first data entry (magic #)
  1589. 06481         .space  16*2*2-2        ! monitor uses previous word and this space
  1590. 06482                                 ! extra space allows for additional servers
  1591. 06483 .sect .bss
  1592. 06484 k_stack:
  1593. 06485         .space  K_STACK_BYTES   ! kernel stack
  1594. 06486 k_stktop:                       ! top of kernel stack
  1595. 06487         .comm   ex_number, 4
  1596. 06488         .comm   trap_errno, 4
  1597. 06489         .comm   old_eip, 4
  1598. 06490         .comm   old_cs, 4
  1599. 06491         .comm   old_eflags, 4
  1600. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1601. src/kernel/start.c    
  1602. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1603. 06500 /* This file contains the C startup code for Minix on Intel processors.
  1604. 06501  * It cooperates with mpx.s to set up a good environment for main().
  1605. 06502  *
  1606. 06503  * This code runs in real mode for a 16 bit kernel and may have to switch
  1607. 06504  * to protected mode for a 286.
  1608. 06505  *
  1609. 06506  * For a 32 bit kernel this already runs in protected mode, but the selectors
  1610. 06507  * are still those given by the BIOS with interrupts disabled, so the
  1611. 06508  * descriptors need to be reloaded and interrupt descriptors made.
  1612. 06509  */
  1613. 06510
  1614. 06511 #include "kernel.h"
  1615. 06512 #include <stdlib.h>
  1616. 06513 #include <minix/boot.h>
  1617. 06514 #include "protect.h"
  1618. 06515
  1619. 06516 PRIVATE char k_environ[256];    /* environment strings passed by loader */
  1620. 06517
  1621. 06518 FORWARD _PROTOTYPE( int k_atoi, (char *s) );
  1622. 06519
  1623. 06520
  1624. 06521 /*==========================================================================*
  1625. 06522  *                              cstart                                      *
  1626. 06523  *==========================================================================*/
  1627. 06524 PUBLIC void cstart(cs, ds, mcs, mds, parmoff, parmsize)
  1628. 06525 U16_t cs, ds;                   /* Kernel code and data segment */
  1629. 06526 U16_t mcs, mds;                 /* Monitor code and data segment */
  1630. 06527 U16_t parmoff, parmsize;        /* boot parameters offset and length */
  1631. 06528 {
  1632. 06529 /* Perform system initializations prior to calling main(). */
  1633. 06530
  1634. 06531   register char *envp;
  1635. 06532   phys_bytes mcode_base, mdata_base;
  1636. 06533   unsigned mon_start;
  1637. 06534
  1638. 06535   /* Record where the kernel and the monitor are. */
  1639. 06536   code_base = seg2phys(cs);
  1640. 06537   data_base = seg2phys(ds);
  1641. 06538   mcode_base = seg2phys(mcs);
  1642. 06539   mdata_base = seg2phys(mds);
  1643. 06540
  1644. 06541   /* Initialize protected mode descriptors. */
  1645. 06542   prot_init();
  1646. 06543
  1647. 06544   /* Copy the boot parameters to kernel memory. */
  1648. 06545   if (parmsize > sizeof k_environ - 2) parmsize = sizeof k_environ - 2;
  1649. 06546   phys_copy(mdata_base + parmoff, vir2phys(k_environ), (phys_bytes) parmsize);
  1650. 06547
  1651. 06548   /* Convert important boot environment variables. */
  1652. 06549   boot_parameters.bp_rootdev = k_atoi(k_getenv("rootdev"));
  1653. 06550   boot_parameters.bp_ramimagedev = k_atoi(k_getenv("ramimagedev"));
  1654. 06551   boot_parameters.bp_ramsize = k_atoi(k_getenv("ramsize"));
  1655. 06552   boot_parameters.bp_processor = k_atoi(k_getenv("processor"));
  1656. 06553
  1657. 06554   /* Type of VDU: */
  1658. 06555   envp = k_getenv("video");
  1659. 06556   if (strcmp(envp, "ega") == 0) ega = TRUE;
  1660. 06557   if (strcmp(envp, "vga") == 0) vga = ega = TRUE;
  1661. 06558
  1662. 06559   /* Memory sizes: */
  1663. 06560   low_memsize = k_atoi(k_getenv("memsize"));
  1664. 06561   ext_memsize = k_atoi(k_getenv("emssize"));
  1665. 06562
  1666. 06563   /* Processor? */
  1667. 06564   processor = boot_parameters.bp_processor;     /* 86, 186, 286, 386, ... */
  1668. 06565
  1669. 06566   /* XT, AT or MCA bus? */
  1670. 06567   envp = k_getenv("bus");
  1671. 06568   if (envp == NIL_PTR || strcmp(envp, "at") == 0) {
  1672. 06569         pc_at = TRUE;
  1673. 06570   } else
  1674. 06571   if (strcmp(envp, "mca") == 0) {
  1675. 06572         pc_at = ps_mca = TRUE;
  1676. 06573   }
  1677. 06574
  1678. 06575   /* Decide if mode is protected. */
  1679. 06576 #if _WORD_SIZE == 2
  1680. 06577   protected_mode = processor >= 286;
  1681. 06578 #endif
  1682. 06579
  1683. 06580   /* Is there a monitor to return to?  If so then keep it safe. */
  1684. 06581   if (!protected_mode) mon_return = 0;
  1685. 06582   mon_start = mcode_base / 1024;
  1686. 06583   if (mon_return && low_memsize > mon_start) low_memsize = mon_start;
  1687. 06584
  1688. 06585   /* Return to assembler code to switch to protected mode (if 286), reload
  1689. 06586    * selectors and call main().
  1690. 06587    */
  1691. 06588 }
  1692. 06591 /*==========================================================================*
  1693. 06592  *                              k_atoi                                      *
  1694. 06593  *==========================================================================*/
  1695. 06594 PRIVATE int k_atoi(s)
  1696. 06595 register char *s;
  1697. 06596 {
  1698. 06597 /* Convert string to integer. */
  1699. 06598
  1700. 06599   return strtol(s, (char **) NULL, 10);
  1701. 06600 }
  1702. 06603 /*==========================================================================*
  1703. 06604  *                              k_getenv                                    *
  1704. 06605  *==========================================================================*/
  1705. 06606 PUBLIC char *k_getenv(name)
  1706. 06607 char *name;
  1707. 06608 {
  1708. 06609 /* Get environment value - kernel version of getenv to avoid setting up the
  1709. 06610  * usual environment array.
  1710. 06611  */
  1711. 06612
  1712. 06613   register char *namep;
  1713. 06614   register char *envp;
  1714. 06615
  1715. 06616   for (envp = k_environ; *envp != 0;) {
  1716. 06617         for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++)
  1717. 06618                 ;
  1718. 06619         if (*namep == '' && *envp == '=') return(envp + 1);
  1719. 06620         while (*envp++ != 0)
  1720. 06621                 ;
  1721. 06622   }
  1722. 06623   return(NIL_PTR);
  1723. 06624 }
  1724. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1725. src/kernel/main.c    
  1726. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1727. 06700 /* This file contains the main program of MINIX.  The routine main()
  1728. 06701  * initializes the system and starts the ball rolling by setting up the proc
  1729. 06702  * table, interrupt vectors, and scheduling each task to run to initialize
  1730. 06703  * itself.
  1731. 06704  *
  1732. 06705  * The entries into this file are:
  1733. 06706  *   main:              MINIX main program
  1734. 06707  *   panic:             abort MINIX due to a fatal error
  1735. 06708  */
  1736. 06709
  1737. 06710 #include "kernel.h"
  1738. 06711 #include <signal.h>
  1739. 06712 #include <unistd.h>
  1740. 06713 #include <minix/callnr.h>
  1741. 06714 #include <minix/com.h>
  1742. 06715 #include "proc.h"
  1743. 06716
  1744. 06717
  1745. 06718 /*===========================================================================*
  1746. 06719  *                                   main                                    *
  1747. 06720  *===========================================================================*/
  1748. 06721 PUBLIC void main()
  1749. 06722 {
  1750. 06723 /* Start the ball rolling. */
  1751. 06724
  1752. 06725   register struct proc *rp;
  1753. 06726   register int t;
  1754. 06727   int sizeindex;
  1755. 06728   phys_clicks text_base;
  1756. 06729   vir_clicks text_clicks;
  1757. 06730   vir_clicks data_clicks;
  1758. 06731   phys_bytes phys_b;
  1759. 06732   reg_t ktsb;                   /* kernel task stack base */
  1760. 06733   struct memory *memp;
  1761. 06734   struct tasktab *ttp;
  1762. 06735
  1763. 06736   /* Initialize the interrupt controller. */
  1764. 06737   intr_init(1);
  1765. 06738
  1766. 06739   /* Interpret memory sizes. */
  1767. 06740   mem_init();
  1768. 06741
  1769. 06742   /* Clear the process table.
  1770. 06743    * Set up mappings for proc_addr() and proc_number() macros.
  1771. 06744    */
  1772. 06745   for (rp = BEG_PROC_ADDR, t = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++t) {
  1773. 06746         rp->p_flags = P_SLOT_FREE;
  1774. 06747         rp->p_nr = t;           /* proc number from ptr */
  1775. 06748         (pproc_addr + NR_TASKS)[t] = rp;        /* proc ptr from number */
  1776. 06749   }
  1777. 06750
  1778. 06751   /* Set up proc table entries for tasks and servers.  The stacks of the
  1779. 06752    * kernel tasks are initialized to an array in data space.  The stacks
  1780. 06753    * of the servers have been added to the data segment by the monitor, so
  1781. 06754    * the stack pointer is set to the end of the data segment.  All the
  1782. 06755    * processes are in low memory on the 8086.  On the 386 only the kernel
  1783. 06756    * is in low memory, the rest if loaded in extended memory.
  1784. 06757    */
  1785. 06758
  1786. 06759   /* Task stacks. */
  1787. 06760   ktsb = (reg_t) t_stack;
  1788. 06761
  1789. 06762   for (t = -NR_TASKS; t <= LOW_USER; ++t) {
  1790. 06763         rp = proc_addr(t);                      /* t's process slot */
  1791. 06764         ttp = &tasktab[t + NR_TASKS];           /* t's task attributes */
  1792. 06765         strcpy(rp->p_name, ttp->name);
  1793. 06766         if (t < 0) {
  1794. 06767                 if (ttp->stksize > 0) {
  1795. 06768                         rp->p_stguard = (reg_t *) ktsb;
  1796. 06769                         *rp->p_stguard = STACK_GUARD;
  1797. 06770                 }
  1798. 06771                 ktsb += ttp->stksize;
  1799. 06772                 rp->p_reg.sp = ktsb;
  1800. 06773                 text_base = code_base >> CLICK_SHIFT;
  1801. 06774                                         /* tasks are all in the kernel */
  1802. 06775                 sizeindex = 0;          /* and use the full kernel sizes */
  1803. 06776                 memp = &mem[0];         /* remove from this memory chunk */
  1804. 06777         } else {
  1805. 06778                 sizeindex = 2 * t + 2;  /* MM, FS, INIT have their own sizes */
  1806. 06779         }
  1807. 06780         rp->p_reg.pc = (reg_t) ttp->initial_pc;
  1808. 06781         rp->p_reg.psw = istaskp(rp) ? INIT_TASK_PSW : INIT_PSW;
  1809. 06782
  1810. 06783         text_clicks = sizes[sizeindex];
  1811. 06784         data_clicks = sizes[sizeindex + 1];
  1812. 06785         rp->p_map[T].mem_phys = text_base;
  1813. 06786         rp->p_map[T].mem_len  = text_clicks;
  1814. 06787         rp->p_map[D].mem_phys = text_base + text_clicks;
  1815. 06788         rp->p_map[D].mem_len  = data_clicks;
  1816. 06789         rp->p_map[S].mem_phys = text_base + text_clicks + data_clicks;
  1817. 06790         rp->p_map[S].mem_vir  = data_clicks;    /* empty - stack is in data */
  1818. 06791         text_base += text_clicks + data_clicks; /* ready for next, if server */
  1819. 06792         memp->size -= (text_base - memp->base);
  1820. 06793         memp->base = text_base;                 /* memory no longer free */
  1821. 06794
  1822. 06795         if (t >= 0) {
  1823. 06796                 /* Initialize the server stack pointer.  Take it down one word
  1824. 06797                  * to give crtso.s something to use as "argc".
  1825. 06798                  */
  1826. 06799                 rp->p_reg.sp = (rp->p_map[S].mem_vir +
  1827. 06800                                 rp->p_map[S].mem_len) << CLICK_SHIFT;
  1828. 06801                 rp->p_reg.sp -= sizeof(reg_t);
  1829. 06802         }
  1830. 06803
  1831. 06804 #if _WORD_SIZE == 4
  1832. 06805         /* Servers are loaded in extended memory if in 386 mode. */
  1833. 06806         if (t < 0) {
  1834. 06807                 memp = &mem[1];
  1835. 06808                 text_base = 0x100000 >> CLICK_SHIFT;
  1836. 06809         }
  1837. 06810 #endif
  1838. 06811         if (!isidlehardware(t)) lock_ready(rp); /* IDLE, HARDWARE neveready */
  1839. 06812         rp->p_flags = 0;
  1840. 06813
  1841. 06814         alloc_segments(rp);
  1842. 06815   }
  1843. 06816
  1844. 06817   proc[NR_TASKS+INIT_PROC_NR].p_pid = 1;/* INIT of course has pid 1 */
  1845. 06818   bill_ptr = proc_addr(IDLE);           /* it has to point somewhere */
  1846. 06819   lock_pick_proc();
  1847. 06820
  1848. 06821   /* Now go to the assembly code to start running the current process. */
  1849. 06822   restart();
  1850. 06823 }
  1851. 06826 /*===========================================================================*
  1852. 06827  *                                   panic                                   *
  1853. 06828  *===========================================================================*/
  1854. 06829 PUBLIC void panic(s,n)
  1855. 06830 _CONST char *s;
  1856. 06831 int n;
  1857. 06832 {
  1858. 06833 /* The system has run aground of a fatal error.  Terminate execution.
  1859. 06834  * If the panic originated in MM or FS, the string will be empty and the
  1860. 06835  * file system already syncked.  If the panic originates in the kernel, we are
  1861. 06836  * kind of stuck.
  1862. 06837  */
  1863. 06838
  1864. 06839   if (*s != 0) {
  1865. 06840         printf("nKernel panic: %s",s);
  1866. 06841         if (n != NO_NUM) printf(" %d", n);
  1867. 06842         printf("n");
  1868. 06843   }
  1869. 06844   wreboot(RBT_PANIC);
  1870. 06845 }
  1871. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1872. src/kernel/proc.c    
  1873. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1874. 06900 /* This file contains essentially all of the process and message handling.
  1875. 06901  * It has two main entry points from the outside:
  1876. 06902  *
  1877. 06903  *   sys_call:   called when a process or task does SEND, RECEIVE or SENDREC
  1878. 06904  *   interrupt: called by interrupt routines to send a message to task
  1879. 06905  *
  1880. 06906  * It also has several minor entry points:
  1881. 06907  *
  1882. 06908  *   lock_ready:      put a process on one of the ready queues so it can be run
  1883. 06909  *   lock_unready:    remove a process from the ready queues
  1884. 06910  *   lock_sched:      a process has run too long; schedule another one
  1885. 06911  *   lock_mini_send:  send a message (used by interrupt signals, etc.)
  1886. 06912  *   lock_pick_proc:  pick a process to run (used by system initialization)
  1887. 06913  *   unhold:          repeat all held-up interrupts
  1888. 06914  */
  1889. 06915
  1890. 06916 #include "kernel.h"
  1891. 06917 #include <minix/callnr.h>
  1892. 06918 #include <minix/com.h>
  1893. 06919 #include "proc.h"
  1894. 06920
  1895. 06921 PRIVATE unsigned char switching;        /* nonzero to inhibit interrupt() */
  1896. 06922
  1897. 06923 FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dest,
  1898. 06924                 message *m_ptr) );
  1899. 06925 FORWARD _PROTOTYPE( int mini_rec, (struct proc *caller_ptr, int src,
  1900. 06926                 message *m_ptr) );
  1901. 06927 FORWARD _PROTOTYPE( void ready, (struct proc *rp) );
  1902. 06928 FORWARD _PROTOTYPE( void sched, (void) );
  1903. 06929 FORWARD _PROTOTYPE( void unready, (struct proc *rp) );
  1904. 06930 FORWARD _PROTOTYPE( void pick_proc, (void) );
  1905. 06931
  1906. 06932 #define CopyMess(s,sp,sm,dp,dm) 
  1907. 06933         cp_mess(s, (sp)->p_map[D].mem_phys, (vir_bytes)sm, (dp)->p_map[D].mem_phys, (vir_bytes)dm)
  1908. 06934
  1909. 06935 /*===========================================================================*
  1910. 06936  *                              interrupt                                    * 
  1911. 06937  *===========================================================================*/
  1912. 06938 PUBLIC void interrupt(task)
  1913. 06939 int task;                       /* number of task to be started */
  1914. 06940 {
  1915. 06941 /* An interrupt has occurred.  Schedule the task that handles it. */
  1916. 06942
  1917. 06943   register struct proc *rp;     /* pointer to task's proc entry */
  1918. 06944
  1919. 06945   rp = proc_addr(task);
  1920. 06946
  1921. 06947   /* If this call would compete with other process-switching functions, put
  1922. 06948    * it on the 'held' queue to be flushed at the next non-competing restart().
  1923. 06949    * The competing conditions are:
  1924. 06950    * (1) k_reenter == (typeof k_reenter) -1:
  1925. 06951    *     Call from the task level, typically from an output interrupt
  1926. 06952    *     routine.  An interrupt handler might reenter interrupt().  Rare,
  1927. 06953    *     so not worth special treatment.
  1928. 06954    * (2) k_reenter > 0:
  1929. 06955    *     Call from a nested interrupt handler.  A previous interrupt handler
  1930. 06956    *     might be inside interrupt() or sys_call().
  1931. 06957    * (3) switching != 0:
  1932. 06958    *     Some process-switching function other than interrupt() is being
  1933. 06959    *     called from the task level, typically sched() from CLOCK.  An
  1934. 06960    *     interrupt handler might call interrupt and pass the k_reenter test.
  1935. 06961    */
  1936. 06962   if (k_reenter != 0 || switching) {
  1937. 06963         lock();
  1938. 06964         if (!rp->p_int_held) {
  1939. 06965                 rp->p_int_held = TRUE;
  1940. 06966                 if (held_head != NIL_PROC)
  1941. 06967                         held_tail->p_nextheld = rp;
  1942. 06968                 else
  1943. 06969                         held_head = rp;
  1944. 06970                 held_tail = rp;
  1945. 06971                 rp->p_nextheld = NIL_PROC;
  1946. 06972         }
  1947. 06973         unlock();
  1948. 06974         return;
  1949. 06975   }
  1950. 06976
  1951. 06977   /* If task is not waiting for an interrupt, record the blockage. */
  1952. 06978   if ( (rp->p_flags & (RECEIVING | SENDING)) != RECEIVING ||
  1953. 06979       !isrxhardware(rp->p_getfrom)) {
  1954. 06980         rp->p_int_blocked = TRUE;
  1955. 06981         return;
  1956. 06982   }
  1957. 06983
  1958. 06984   /* Destination is waiting for an interrupt.
  1959. 06985    * Send it a message with source HARDWARE and type HARD_INT.
  1960. 06986    * No more information can be reliably provided since interrupt messages
  1961. 06987    * are not queued.
  1962. 06988    */
  1963. 06989   rp->p_messbuf->m_source = HARDWARE;
  1964. 06990   rp->p_messbuf->m_type = HARD_INT;
  1965. 06991   rp->p_flags &= ~RECEIVING;
  1966. 06992   rp->p_int_blocked = FALSE;
  1967. 06993
  1968. 06994    /* Make rp ready and run it unless a task is already running.  This is
  1969. 06995     * ready(rp) in-line for speed.
  1970. 06996     */
  1971. 06997   if (rdy_head[TASK_Q] != NIL_PROC)
  1972. 06998         rdy_tail[TASK_Q]->p_nextready = rp;
  1973. 06999   else
  1974. 07000         proc_ptr = rdy_head[TASK_Q] = rp;
  1975. 07001   rdy_tail[TASK_Q] = rp;
  1976. 07002   rp->p_nextready = NIL_PROC;
  1977. 07003 }
  1978. 07005 /*===========================================================================*
  1979. 07006  *                              sys_call                                     * 
  1980. 07007  *===========================================================================*/
  1981. 07008 PUBLIC int sys_call(function, src_dest, m_ptr)
  1982. 07009 int function;                   /* SEND, RECEIVE, or BOTH */
  1983. 07010 int src_dest;                   /* source to receive from or dest to send to */
  1984. 07011 message *m_ptr;                 /* pointer to message */
  1985. 07012 {
  1986. 07013 /* The only system calls that exist in MINIX are sending and receiving
  1987. 07014  * messages.  These are done by trapping to the kernel with an INT instruction.
  1988. 07015  * The trap is caught and sys_call() is called to send or receive a message
  1989. 07016  * (or both). The caller is always given by proc_ptr.
  1990. 07017  */
  1991. 07018
  1992. 07019   register struct proc *rp;
  1993. 07020   int n;
  1994. 07021
  1995. 07022   /* Check for bad system call parameters. */
  1996. 07023   if (!isoksrc_dest(src_dest)) return(E_BAD_SRC);
  1997. 07024   rp = proc_ptr;
  1998. 07025
  1999. 07026   if (isuserp(rp) && function != BOTH) return(E_NO_PERM);
  2000. 07027   
  2001. 07028   /* The parameters are ok. Do the call. */
  2002. 07029   if (function & SEND) {
  2003. 07030         /* Function = SEND or BOTH. */
  2004. 07031         n = mini_send(rp, src_dest, m_ptr);
  2005. 07032         if (function == SEND || n != OK)
  2006. 07033                 return(n);      /* done, or SEND failed */
  2007. 07034   }
  2008. 07035
  2009. 07036   /* Function = RECEIVE or BOTH.
  2010. 07037    * We have checked user calls are BOTH, and trust 'function' otherwise.
  2011. 07038    */
  2012. 07039   return(mini_rec(rp, src_dest, m_ptr));
  2013. 07040 }
  2014. 07042 /*===========================================================================*
  2015. 07043  *                              mini_send                                    * 
  2016. 07044  *===========================================================================*/
  2017. 07045 PRIVATE int mini_send(caller_ptr, dest, m_ptr)
  2018. 07046 register struct proc *caller_ptr;       /* who is trying to send a message? */
  2019. 07047 int dest;                       /* to whom is message being sent? */
  2020. 07048 message *m_ptr;                 /* pointer to message buffer */
  2021. 07049 {
  2022. 07050 /* Send a message from 'caller_ptr' to 'dest'. If 'dest' is blocked waiting
  2023. 07051  * for this message, copy the message to it and unblock 'dest'. If 'dest' is
  2024. 07052  * not waiting at all, or is waiting for another source, queue 'caller_ptr'.
  2025. 07053  */
  2026. 07054
  2027. 07055   register struct proc *dest_ptr, *next_ptr;
  2028. 07056   vir_bytes vb;                 /* message buffer pointer as vir_bytes */
  2029. 07057   vir_clicks vlo, vhi;          /* virtual clicks containing message to send */
  2030. 07058
  2031. 07059   /* User processes are only allowed to send to FS and MM.  Check for this. */
  2032. 07060   if (isuserp(caller_ptr) && !issysentn(dest)) return(E_BAD_DEST);
  2033. 07061   dest_ptr = proc_addr(dest);   /* pointer to destination's proc entry */
  2034. 07062   if (dest_ptr->p_flags & P_SLOT_FREE) return(E_BAD_DEST);      /* dead dest */
  2035. 07063
  2036. 07064   /* This check allows a message to be anywhere in data or stack or gap. 
  2037. 07065    * It will have to be made more elaborate later for machines which
  2038. 07066    * don't have the gap mapped.
  2039. 07067    */
  2040. 07068   vb = (vir_bytes) m_ptr;
  2041. 07069   vlo = vb >> CLICK_SHIFT;      /* vir click for bottom of message */
  2042. 07070   vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT;    /* vir click for top of msg */
  2043. 07071   if (vlo < caller_ptr->p_map[D].mem_vir || vlo > vhi ||
  2044. 07072       vhi >= caller_ptr->p_map[S].mem_vir + caller_ptr->p_map[S].mem_len)
  2045. 07073         return(EFAULT); 
  2046. 07074
  2047. 07075   /* Check for deadlock by 'caller_ptr' and 'dest' sending to each other. */
  2048. 07076   if (dest_ptr->p_flags & SENDING) {
  2049. 07077         next_ptr = proc_addr(dest_ptr->p_sendto);
  2050. 07078         while (TRUE) {
  2051. 07079                 if (next_ptr == caller_ptr) return(ELOCKED);
  2052. 07080                 if (next_ptr->p_flags & SENDING)
  2053. 07081                         next_ptr = proc_addr(next_ptr->p_sendto);
  2054. 07082                 else
  2055. 07083                         break;
  2056. 07084         }
  2057. 07085   }
  2058. 07086
  2059. 07087   /* Check to see if 'dest' is blocked waiting for this message. */
  2060. 07088   if ( (dest_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING &&
  2061. 07089        (dest_ptr->p_getfrom == ANY ||
  2062. 07090         dest_ptr->p_getfrom == proc_number(caller_ptr))) {
  2063. 07091         /* Destination is indeed waiting for this message. */
  2064. 07092         CopyMess(proc_number(caller_ptr), caller_ptr, m_ptr, dest_ptr,
  2065. 07093                  dest_ptr->p_messbuf);
  2066. 07094         dest_ptr->p_flags &= ~RECEIVING;        /* deblock destination */
  2067. 07095         if (dest_ptr->p_flags == 0) ready(dest_ptr);
  2068. 07096   } else {
  2069. 07097         /* Destination is not waiting.  Block and queue caller. */
  2070. 07098         caller_ptr->p_messbuf = m_ptr;
  2071. 07099         if (caller_ptr->p_flags == 0) unready(caller_ptr);
  2072. 07100         caller_ptr->p_flags |= SENDING;
  2073. 07101         caller_ptr->p_sendto= dest;
  2074. 07102
  2075. 07103         /* Process is now blocked.  Put in on the destination's queue. */
  2076. 07104         if ( (next_ptr = dest_ptr->p_callerq) == NIL_PROC)
  2077. 07105                 dest_ptr->p_callerq = caller_ptr;
  2078. 07106         else {
  2079. 07107                 while (next_ptr->p_sendlink != NIL_PROC)
  2080. 07108                         next_ptr = next_ptr->p_sendlink;
  2081. 07109                 next_ptr->p_sendlink = caller_ptr;
  2082. 07110         }
  2083. 07111         caller_ptr->p_sendlink = NIL_PROC;
  2084. 07112   }
  2085. 07113   return(OK);
  2086. 07114 }
  2087. 07116 /*===========================================================================*
  2088. 07117  *                              mini_rec                                     * 
  2089. 07118  *===========================================================================*/
  2090. 07119 PRIVATE int mini_rec(caller_ptr, src, m_ptr)
  2091. 07120 register struct proc *caller_ptr;       /* process trying to get message */
  2092. 07121 int src;                        /* which message source is wanted (or ANY) */
  2093. 07122 message *m_ptr;                 /* pointer to message buffer */
  2094. 07123 {
  2095. 07124 /* A process or task wants to get a message.  If one is already queued,
  2096. 07125  * acquire it and deblock the sender.  If no message from the desired source
  2097. 07126  * is available, block the caller.  No need to check parameters for validity.
  2098. 07127  * Users calls are always sendrec(), and mini_send() has checked already.  
  2099. 07128  * Calls from the tasks, MM, and FS are trusted.
  2100. 07129  */
  2101. 07130
  2102. 07131   register struct proc *sender_ptr;
  2103. 07132   register struct proc *previous_ptr;
  2104. 07133
  2105. 07134   /* Check to see if a message from desired source is already available. */
  2106. 07135   if (!(caller_ptr->p_flags & SENDING)) {
  2107. 07136         /* Check caller queue. */
  2108. 07137     for (sender_ptr = caller_ptr->p_callerq; sender_ptr != NIL_PROC;
  2109. 07138          previous_ptr = sender_ptr, sender_ptr = sender_ptr->p_sendlink) {
  2110. 07139         if (src == ANY || src == proc_number(sender_ptr)) {
  2111. 07140                 /* An acceptable message has been found. */
  2112. 07141                 CopyMess(proc_number(sender_ptr), sender_ptr,
  2113. 07142                          sender_ptr->p_messbuf, caller_ptr, m_ptr);
  2114. 07143                 if (sender_ptr == caller_ptr->p_callerq)
  2115. 07144                         caller_ptr->p_callerq = sender_ptr->p_sendlink;
  2116. 07145                 else
  2117. 07146                         previous_ptr->p_sendlink = sender_ptr->p_sendlink;
  2118. 07147                 if ((sender_ptr->p_flags &= ~SENDING) == 0)
  2119. 07148                         ready(sender_ptr);      /* deblock sender */
  2120. 07149                 return(OK);
  2121. 07150         }
  2122. 07151     }
  2123. 07152
  2124. 07153     /* Check for blocked interrupt. */
  2125. 07154     if (caller_ptr->p_int_blocked && isrxhardware(src)) {
  2126. 07155         m_ptr->m_source = HARDWARE;
  2127. 07156         m_ptr->m_type = HARD_INT;
  2128. 07157         caller_ptr->p_int_blocked = FALSE;
  2129. 07158         return(OK);
  2130. 07159     }
  2131. 07160   }
  2132. 07161
  2133. 07162   /* No suitable message is available.  Block the process trying to receive. */
  2134. 07163   caller_ptr->p_getfrom = src;
  2135. 07164   caller_ptr->p_messbuf = m_ptr;
  2136. 07165   if (caller_ptr->p_flags == 0) unready(caller_ptr);
  2137. 07166   caller_ptr->p_flags |= RECEIVING;
  2138. 07167
  2139. 07168   /* If MM has just blocked and there are kernel signals pending, now is the
  2140. 07169    * time to tell MM about them, since it will be able to accept the message.
  2141. 07170    */
  2142. 07171   if (sig_procs > 0 && proc_number(caller_ptr) == MM_PROC_NR && src == ANY)
  2143. 07172         inform();
  2144. 07173   return(OK);
  2145. 07174 }
  2146. 07176 /*===========================================================================*
  2147. 07177  *                              pick_proc                                    * 
  2148. 07178  *===========================================================================*/
  2149. 07179 PRIVATE void pick_proc()
  2150. 07180 {
  2151. 07181 /* Decide who to run now.  A new process is selected by setting 'proc_ptr'.
  2152. 07182  * When a fresh user (or idle) process is selected, record it in 'bill_ptr',
  2153. 07183  * so the clock task can tell who to bill for system time.
  2154. 07184  */
  2155. 07185
  2156. 07186   register struct proc *rp;     /* process to run */
  2157. 07187
  2158. 07188   if ( (rp = rdy_head[TASK_Q]) != NIL_PROC) {
  2159. 07189         proc_ptr = rp;
  2160. 07190         return;
  2161. 07191   }
  2162. 07192   if ( (rp = rdy_head[SERVER_Q]) != NIL_PROC) {
  2163. 07193         proc_ptr = rp;
  2164. 07194         return;
  2165. 07195   }
  2166. 07196   if ( (rp = rdy_head[USER_Q]) != NIL_PROC) {
  2167. 07197         proc_ptr = rp;
  2168. 07198         bill_ptr = rp;
  2169. 07199         return;
  2170. 07200   }
  2171. 07201   /* No one is ready.  Run the idle task.  The idle task might be made an
  2172. 07202    * always-ready user task to avoid this special case.
  2173. 07203    */
  2174. 07204   bill_ptr = proc_ptr = proc_addr(IDLE);
  2175. 07205 }
  2176. 07207 /*===========================================================================*
  2177. 07208  *                              ready                                        * 
  2178. 07209  *===========================================================================*/
  2179. 07210 PRIVATE void ready(rp)
  2180. 07211 register struct proc *rp;       /* this process is now runnable */
  2181. 07212 {
  2182. 07213 /* Add 'rp' to the end of one of the queues of runnable processes. Three
  2183. 07214  * queues are maintained:
  2184. 07215  *   TASK_Q   - (highest priority) for runnable tasks
  2185. 07216  *   SERVER_Q - (middle priority) for MM and FS only
  2186. 07217  *   USER_Q   - (lowest priority) for user processes
  2187. 07218  */
  2188. 07219
  2189. 07220   if (istaskp(rp)) {
  2190. 07221         if (rdy_head[TASK_Q] != NIL_PROC)
  2191. 07222                 /* Add to tail of nonempty queue. */
  2192. 07223                 rdy_tail[TASK_Q]->p_nextready = rp;
  2193. 07224         else {
  2194. 07225                 proc_ptr =              /* run fresh task next */
  2195. 07226                 rdy_head[TASK_Q] = rp;  /* add to empty queue */
  2196. 07227         }
  2197. 07228         rdy_tail[TASK_Q] = rp;
  2198. 07229         rp->p_nextready = NIL_PROC;     /* new entry has no successor */
  2199. 07230         return;
  2200. 07231   }
  2201. 07232   if (!isuserp(rp)) {           /* others are similar */
  2202. 07233         if (rdy_head[SERVER_Q] != NIL_PROC)
  2203. 07234                 rdy_tail[SERVER_Q]->p_nextready = rp;
  2204. 07235         else
  2205. 07236                 rdy_head[SERVER_Q] = rp;
  2206. 07237         rdy_tail[SERVER_Q] = rp;
  2207. 07238         rp->p_nextready = NIL_PROC;
  2208. 07239         return;
  2209. 07240   }
  2210. 07241   if (rdy_head[USER_Q] == NIL_PROC)
  2211. 07242         rdy_tail[USER_Q] = rp;
  2212. 07243   rp->p_nextready = rdy_head[USER_Q];
  2213. 07244   rdy_head[USER_Q] = rp;
  2214. 07245 /*
  2215. 07246   if (rdy_head[USER_Q] != NIL_PROC)
  2216. 07247         rdy_tail[USER_Q]->p_nextready = rp;
  2217. 07248   else
  2218. 07249         rdy_head[USER_Q] = rp;
  2219. 07250   rdy_tail[USER_Q] = rp;
  2220. 07251   rp->p_nextready = NIL_PROC;
  2221. 07252 */
  2222. 07253 }
  2223. 07255 /*===========================================================================*
  2224. 07256  *                              unready                                      * 
  2225. 07257  *===========================================================================*/
  2226. 07258 PRIVATE void unready(rp)
  2227. 07259 register struct proc *rp;       /* this process is no longer runnable */
  2228. 07260 {
  2229. 07261 /* A process has blocked. */
  2230. 07262
  2231. 07263   register struct proc *xp;
  2232. 07264   register struct proc **qtail;  /* TASK_Q, SERVER_Q, or USER_Q rdy_tail */
  2233. 07265
  2234. 07266   if (istaskp(rp)) {
  2235. 07267         /* task stack still ok? */
  2236. 07268         if (*rp->p_stguard != STACK_GUARD)
  2237. 07269                 panic("stack overrun by task", proc_number(rp));
  2238. 07270
  2239. 07271         if ( (xp = rdy_head[TASK_Q]) == NIL_PROC) return;
  2240. 07272         if (xp == rp) {
  2241. 07273                 /* Remove head of queue */
  2242. 07274                 rdy_head[TASK_Q] = xp->p_nextready;
  2243. 07275                 if (rp == proc_ptr) pick_proc();
  2244. 07276                 return;
  2245. 07277         }
  2246. 07278         qtail = &rdy_tail[TASK_Q];
  2247. 07279   }
  2248. 07280   else if (!isuserp(rp)) {
  2249. 07281         if ( (xp = rdy_head[SERVER_Q]) == NIL_PROC) return;
  2250. 07282         if (xp == rp) {
  2251. 07283                 rdy_head[SERVER_Q] = xp->p_nextready;
  2252. 07284                 pick_proc();
  2253. 07285                 return;
  2254. 07286         }
  2255. 07287         qtail = &rdy_tail[SERVER_Q];
  2256. 07288   } else
  2257. 07289   {
  2258. 07290         if ( (xp = rdy_head[USER_Q]) == NIL_PROC) return;
  2259. 07291         if (xp == rp) {
  2260. 07292                 rdy_head[USER_Q] = xp->p_nextready;
  2261. 07293                 pick_proc();
  2262. 07294                 return;
  2263. 07295         }
  2264. 07296         qtail = &rdy_tail[USER_Q];
  2265. 07297   }
  2266. 07298
  2267. 07299   /* Search body of queue.  A process can be made unready even if it is
  2268. 07300    * not running by being sent a signal that kills it.
  2269. 07301    */
  2270. 07302   while (xp->p_nextready != rp)
  2271. 07303         if ( (xp = xp->p_nextready) == NIL_PROC) return;
  2272. 07304   xp->p_nextready = xp->p_nextready->p_nextready;
  2273. 07305   if (*qtail == rp) *qtail = xp;
  2274. 07306 }
  2275. 07308 /*===========================================================================*
  2276. 07309  *                              sched                                        * 
  2277. 07310  *===========================================================================*/
  2278. 07311 PRIVATE void sched()
  2279. 07312 {
  2280. 07313 /* The current process has run too long.  If another low priority (user)
  2281. 07314  * process is runnable, put the current process on the end of the user queue,
  2282. 07315  * possibly promoting another user to head of the queue.
  2283. 07316  */
  2284. 07317
  2285. 07318   if (rdy_head[USER_Q] == NIL_PROC) return;
  2286. 07319
  2287. 07320   /* One or more user processes queued. */
  2288. 07321   rdy_tail[USER_Q]->p_nextready = rdy_head[USER_Q];
  2289. 07322   rdy_tail[USER_Q] = rdy_head[USER_Q];
  2290. 07323   rdy_head[USER_Q] = rdy_head[USER_Q]->p_nextready;
  2291. 07324   rdy_tail[USER_Q]->p_nextready = NIL_PROC;
  2292. 07325   pick_proc();
  2293. 07326 }
  2294. 07328 /*==========================================================================*
  2295. 07329  *                              lock_mini_send                              *
  2296. 07330  *==========================================================================*/
  2297. 07331 PUBLIC int lock_mini_send(caller_ptr, dest, m_ptr)
  2298. 07332 struct proc *caller_ptr;        /* who is trying to send a message? */
  2299. 07333 int dest;                       /* to whom is message being sent? */
  2300. 07334 message *m_ptr;                 /* pointer to message buffer */
  2301. 07335 {
  2302. 07336 /* Safe gateway to mini_send() for tasks. */
  2303. 07337
  2304. 07338   int result;
  2305. 07339
  2306. 07340   switching = TRUE;
  2307. 07341   result = mini_send(caller_ptr, dest, m_ptr);
  2308. 07342   switching = FALSE;
  2309. 07343   return(result);
  2310. 07344 }
  2311. 07346 /*==========================================================================*
  2312. 07347  *                              lock_pick_proc                              *
  2313. 07348  *==========================================================================*/
  2314. 07349 PUBLIC void lock_pick_proc()
  2315. 07350 {
  2316. 07351 /* Safe gateway to pick_proc() for tasks. */
  2317. 07352
  2318. 07353   switching = TRUE;
  2319. 07354   pick_proc();
  2320. 07355   switching = FALSE;
  2321. 07356 }
  2322. 07358 /*==========================================================================*
  2323. 07359  *                              lock_ready                                  *
  2324. 07360  *==========================================================================*/
  2325. 07361 PUBLIC void lock_ready(rp)
  2326. 07362 struct proc *rp;                /* this process is now runnable */
  2327. 07363 {
  2328. 07364 /* Safe gateway to ready() for tasks. */
  2329. 07365
  2330. 07366   switching = TRUE;
  2331. 07367   ready(rp);
  2332. 07368   switching = FALSE;
  2333. 07369 }
  2334. 07372 /*==========================================================================*
  2335. 07373  *                              lock_unready                                *
  2336. 07374  *==========================================================================*/
  2337. 07375 PUBLIC void lock_unready(rp)
  2338. 07376 struct proc *rp;                /* this process is no longer runnable */
  2339. 07377 {
  2340. 07378 /* Safe gateway to unready() for tasks. */
  2341. 07379
  2342. 07380   switching = TRUE;
  2343. 07381   unready(rp);
  2344. 07382   switching = FALSE;
  2345. 07383 }
  2346. 07385 /*==========================================================================*
  2347. 07386  *                              lock_sched                                  *
  2348. 07387  *==========================================================================*/
  2349. 07388 PUBLIC void lock_sched()
  2350. 07389 {
  2351. 07390 /* Safe gateway to sched() for tasks. */
  2352. 07391
  2353. 07392   switching = TRUE;
  2354. 07393   sched();
  2355. 07394   switching = FALSE;
  2356. 07395 }
  2357. 07397 /*==========================================================================*
  2358. 07398  *                              unhold                                      *
  2359. 07399  *==========================================================================*/
  2360. 07400 PUBLIC void unhold()
  2361. 07401 {
  2362. 07402 /* Flush any held-up interrupts.  k_reenter must be 0.  held_head must not
  2363. 07403  * be NIL_PROC.  Interrupts must be disabled.  They will be enabled but will
  2364. 07404  * be disabled when this returns.
  2365. 07405  */
  2366. 07406
  2367. 07407   register struct proc *rp;     /* current head of held queue */
  2368. 07408
  2369. 07409   if (switching) return;
  2370. 07410   rp = held_head;
  2371. 07411   do {
  2372. 07412         if ( (held_head = rp->p_nextheld) == NIL_PROC) held_tail = NIL_PROC;
  2373. 07413         rp->p_int_held = FALSE;
  2374. 07414         unlock();               /* reduce latency; held queue may change! */
  2375. 07415         interrupt(proc_number(rp));
  2376. 07416         lock();                 /* protect the held queue again */
  2377. 07417   }
  2378. 07418   while ( (rp = held_head) != NIL_PROC);
  2379. 07419 }
  2380. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2381. src/kernel/exception.c    
  2382. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2383. 07500 /* This file contains a simple exception handler.  Exceptions in user
  2384. 07501  * processes are converted to signals.  Exceptions in the kernel, MM and
  2385. 07502  * FS cause a panic.
  2386. 07503  */
  2387. 07504
  2388. 07505 #include "kernel.h"
  2389. 07506 #include <signal.h>
  2390. 07507 #include "proc.h"
  2391. 07508
  2392. 07509 /*==========================================================================*
  2393. 07510  *                              exception                                   *
  2394. 07511  *==========================================================================*/
  2395. 07512 PUBLIC void exception(vec_nr)
  2396. 07513 unsigned vec_nr;
  2397. 07514 {
  2398. 07515 /* An exception or unexpected interrupt has occurred. */
  2399. 07516
  2400. 07517   struct ex_s {
  2401. 07518         char *msg;
  2402. 07519         int signum;
  2403. 07520         int minprocessor;
  2404. 07521   };
  2405. 07522   static struct ex_s ex_data[] = {
  2406. 07523         "Divide error", SIGFPE, 86,
  2407. 07524         "Debug exception", SIGTRAP, 86,
  2408. 07525         "Nonmaskable interrupt", SIGBUS, 86,
  2409. 07526         "Breakpoint", SIGEMT, 86,
  2410. 07527         "Overflow", SIGFPE, 86,
  2411. 07528         "Bounds check", SIGFPE, 186,
  2412. 07529         "Invalid opcode", SIGILL, 186,
  2413. 07530         "Coprocessor not available", SIGFPE, 186,
  2414. 07531         "Double fault", SIGBUS, 286,
  2415. 07532         "Copressor segment overrun", SIGSEGV, 286,
  2416. 07533         "Invalid TSS", SIGSEGV, 286,
  2417. 07534         "Segment not present", SIGSEGV, 286,
  2418. 07535         "Stack exception", SIGSEGV, 286,        /* STACK_FAULT already used */
  2419. 07536         "General protection", SIGSEGV, 286,
  2420. 07537         "Page fault", SIGSEGV, 386,             /* not close */
  2421. 07538         NIL_PTR, SIGILL, 0,                     /* probably software trap */
  2422. 07539         "Coprocessor error", SIGFPE, 386,
  2423. 07540   };
  2424. 07541   register struct ex_s *ep;
  2425. 07542   struct proc *saved_proc;
  2426. 07543
  2427. 07544   saved_proc= proc_ptr; /* Save proc_ptr, because it may be changed by debug 
  2428. 07545                          * statements.
  2429. 07546                          */
  2430. 07547
  2431. 07548   ep = &ex_data[vec_nr];
  2432. 07549
  2433. 07550   if (vec_nr == 2) {            /* spurious NMI on some machines */
  2434. 07551         printf("got spurious NMIn");
  2435. 07552         return;
  2436. 07553   }
  2437. 07554
  2438. 07555   if (k_reenter == 0 && isuserp(saved_proc)) {
  2439. 07556         unlock();               /* this is protected like sys_call() */
  2440. 07557         cause_sig(proc_number(saved_proc), ep->signum);
  2441. 07558         return;
  2442. 07559   }
  2443. 07560
  2444. 07561   /* This is not supposed to happen. */
  2445. 07562   if (ep->msg == NIL_PTR || processor < ep->minprocessor)
  2446. 07563         printf("nIntel-reserved exception %dn", vec_nr);
  2447. 07564   else
  2448. 07565         printf("n%sn", ep->msg);
  2449. 07566   printf("process number %d, pc = 0x%04x:0x%08xn",
  2450. 07567         proc_number(saved_proc),
  2451. 07568         (unsigned) saved_proc->p_reg.cs,
  2452. 07569         (unsigned) saved_proc->p_reg.pc);
  2453. 07570   panic("exception in system code", NO_NUM);
  2454. 07571 }
  2455. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2456. src/kernel/i8259.c    
  2457. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2458. 07600 /* This file contains routines for initializing the 8259 interrupt controller:
  2459. 07601  *      get_irq_handler: address of handler for a given interrupt
  2460. 07602  *      put_irq_handler: register an interrupt handler
  2461. 07603  *      intr_init:      initialize the interrupt controller(s)
  2462. 07604  */
  2463. 07605
  2464. 07606 #include "kernel.h"
  2465. 07607
  2466. 07608 #define ICW1_AT         0x11    /* edge triggered, cascade, need ICW4 */
  2467. 07609 #define ICW1_PC         0x13    /* edge triggered, no cascade, need ICW4 */
  2468. 07610 #define ICW1_PS         0x19    /* level triggered, cascade, need ICW4 */
  2469. 07611 #define ICW4_AT         0x01    /* not SFNM, not buffered, normal EOI, 8086 */
  2470. 07612 #define ICW4_PC         0x09    /* not SFNM, buffered, normal EOI, 8086 */
  2471. 07613
  2472. 07614 FORWARD _PROTOTYPE( int spurious_irq, (int irq) );
  2473. 07615
  2474. 07616 #define set_vec(nr, addr)       ((void)0) /* kluge for protected mode */
  2475. 07617
  2476. 07618 /*==========================================================================*
  2477. 07619  *                              intr_init                                   *
  2478. 07620  *==========================================================================*/
  2479. 07621 PUBLIC void intr_init(mine)
  2480. 07622 int mine;
  2481. 07623 {
  2482. 07624 /* Initialize the 8259s, finishing with all interrupts disabled.  This is
  2483. 07625  * only done in protected mode, in real mode we don't touch the 8259s, but
  2484. 07626  * use the BIOS locations instead.  The flag "mine" is set if the 8259s are
  2485. 07627  * to be programmed for Minix, or to be reset to what the BIOS expects.
  2486. 07628  */
  2487. 07629
  2488. 07630   int i;
  2489. 07631
  2490. 07632   lock();
  2491. 07633   /* The AT and newer PS/2 have two interrupt controllers, one master,
  2492. 07634    * one slaved at IRQ 2.  (We don't have to deal with the PC that
  2493. 07635    * has just one controller, because it must run in real mode.)
  2494. 07636    */
  2495. 07637   out_byte(INT_CTL, ps_mca ? ICW1_PS : ICW1_AT);
  2496. 07638   out_byte(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
  2497. 07639                                                 /* ICW2 for master */
  2498. 07640   out_byte(INT_CTLMASK, (1 << CASCADE_IRQ));    /* ICW3 tells slaves */
  2499. 07641   out_byte(INT_CTLMASK, ICW4_AT);
  2500. 07642   out_byte(INT_CTLMASK, ~(1 << CASCADE_IRQ));   /* IRQ 0-7 mask */
  2501. 07643   out_byte(INT2_CTL, ps_mca ? ICW1_PS : ICW1_AT);
  2502. 07644   out_byte(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
  2503. 07645                                                 /* ICW2 for slave */
  2504. 07646   out_byte(INT2_CTLMASK, CASCADE_IRQ);          /* ICW3 is slave nr */
  2505. 07647   out_byte(INT2_CTLMASK, ICW4_AT);
  2506. 07648   out_byte(INT2_CTLMASK, ~0);                   /* IRQ 8-15 mask */
  2507. 07649
  2508. 07650   /* Initialize the table of interrupt handlers. */
  2509. 07651   for (i = 0; i < NR_IRQ_VECTORS; i++) irq_table[i] = spurious_irq;
  2510. 07652 }
  2511. 07654 /*=========================================================================*
  2512. 07655  *                              spurious_irq                               *
  2513. 07656  *=========================================================================*/
  2514. 07657 PRIVATE int spurious_irq(irq)
  2515. 07658 int irq;
  2516. 07659 {
  2517. 07660 /* Default interrupt handler.  It complains a lot. */
  2518. 07661
  2519. 07662   if (irq < 0 || irq >= NR_IRQ_VECTORS)
  2520. 07663         panic("invalid call to spurious_irq", irq);
  2521. 07664
  2522. 07665   printf("spurious irq %dn", irq);
  2523. 07666
  2524. 07667   return 1;     /* Reenable interrupt */
  2525. 07668 }
  2526. 07670 /*=========================================================================*
  2527. 07671  *                              put_irq_handler                            *
  2528. 07672  *=========================================================================*/
  2529. 07673 PUBLIC void put_irq_handler(irq, handler)
  2530. 07674 int irq;
  2531. 07675 irq_handler_t handler;
  2532. 07676 {
  2533. 07677 /* Register an interrupt handler. */
  2534. 07678
  2535. 07679   if (irq < 0 || irq >= NR_IRQ_VECTORS)
  2536. 07680         panic("invalid call to put_irq_handler", irq);
  2537. 07681
  2538. 07682   if (irq_table[irq] == handler)
  2539. 07683         return;         /* extra initialization */
  2540. 07684
  2541. 07685   if (irq_table[irq] != spurious_irq)
  2542. 07686         panic("attempt to register second irq handler for irq", irq);
  2543. 07687
  2544. 07688   disable_irq(irq);
  2545. 07689   if (!protected_mode) set_vec(BIOS_VECTOR(irq), irq_vec[irq]);
  2546. 07690   irq_table[irq]= handler;
  2547. 07691   irq_use |= 1 << irq;
  2548. 07692 }
  2549. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2550. src/kernel/protect.c    
  2551. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2552. 07700 /* This file contains code for initialization of protected mode, to initialize
  2553. 07701  * code and data segment descriptors, and to initialize global descriptors
  2554. 07702  * for local descriptors in the process table.
  2555. 07703  */
  2556. 07704
  2557. 07705 #include "kernel.h"
  2558. 07706 #include "proc.h"
  2559. 07707 #include "protect.h"
  2560. 07708
  2561. 07709 #define INT_GATE_TYPE   (INT_286_GATE | DESC_386_BIT)
  2562. 07710 #define TSS_TYPE        (AVL_286_TSS  | DESC_386_BIT)
  2563. 07711
  2564. 07712 struct desctableptr_s {
  2565. 07713   char limit[sizeof(u16_t)];
  2566. 07714   char base[sizeof(u32_t)];             /* really u24_t + pad for 286 */
  2567. 07715 };
  2568. 07716
  2569. 07717 struct gatedesc_s {
  2570. 07718   u16_t offset_low;
  2571. 07719   u16_t selector;
  2572. 07720   u8_t pad;                     /* |000|XXXXX| ig & trpg, |XXXXXXXX| task g */
  2573. 07721   u8_t p_dpl_type;              /* |P|DL|0|TYPE| */
  2574. 07722   u16_t offset_high;
  2575. 07723 };
  2576. 07724
  2577. 07725 struct tss_s {
  2578. 07726   reg_t backlink;
  2579. 07727   reg_t sp0;                    /* stack pointer to use during interrupt */
  2580. 07728   reg_t ss0;                    /*   "   segment  "  "    "        "     */
  2581. 07729   reg_t sp1;
  2582. 07730   reg_t ss1;
  2583. 07731   reg_t sp2;
  2584. 07732   reg_t ss2;
  2585. 07733   reg_t cr3;
  2586. 07734   reg_t ip;
  2587. 07735   reg_t flags;
  2588. 07736   reg_t ax;
  2589. 07737   reg_t cx;
  2590. 07738   reg_t dx;
  2591. 07739   reg_t bx;
  2592. 07740   reg_t sp;
  2593. 07741   reg_t bp;
  2594. 07742   reg_t si;
  2595. 07743   reg_t di;
  2596. 07744   reg_t es;
  2597. 07745   reg_t cs;
  2598. 07746   reg_t ss;
  2599. 07747   reg_t ds;
  2600. 07748   reg_t fs;
  2601. 07749   reg_t gs;
  2602. 07750   reg_t ldt;
  2603. 07751   u16_t trap;
  2604. 07752   u16_t iobase;
  2605. 07753 };
  2606. 07754
  2607. 07755 PUBLIC struct segdesc_s gdt[GDT_SIZE];
  2608. 07756 PRIVATE struct gatedesc_s idt[IDT_SIZE];        /* zero-init so none present */
  2609. 07757 PUBLIC struct tss_s tss;        /* zero init */
  2610. 07758
  2611. 07759 FORWARD _PROTOTYPE( void int_gate, (unsigned vec_nr, phys_bytes base,
  2612. 07760                 unsigned dpl_type) );
  2613. 07761 FORWARD _PROTOTYPE( void sdesc, (struct segdesc_s *segdp, phys_bytes base,
  2614. 07762                 phys_bytes size) );
  2615. 07763
  2616. 07764 /*=========================================================================*
  2617. 07765  *                              prot_init                                  *
  2618. 07766  *=========================================================================*/
  2619. 07767 PUBLIC void prot_init()
  2620. 07768 {
  2621. 07769 /* Set up tables for protected mode.
  2622. 07770  * All GDT slots are allocated at compile time.
  2623. 07771  */
  2624. 07772
  2625. 07773   phys_bytes code_bytes;
  2626. 07774   phys_bytes data_bytes;
  2627. 07775   struct gate_table_s *gtp;
  2628. 07776   struct desctableptr_s *dtp;
  2629. 07777   unsigned ldt_selector;
  2630. 07778   register struct proc *rp;
  2631. 07779
  2632. 07780   static struct gate_table_s {
  2633. 07781         _PROTOTYPE( void (*gate), (void) );
  2634. 07782         unsigned char vec_nr;
  2635. 07783         unsigned char privilege;
  2636. 07784   }
  2637. 07785   gate_table[] = {
  2638. 07786         divide_error, DIVIDE_VECTOR, INTR_PRIVILEGE,
  2639. 07787         single_step_exception, DEBUG_VECTOR, INTR_PRIVILEGE,
  2640. 07788         nmi, NMI_VECTOR, INTR_PRIVILEGE,
  2641. 07789         breakpoint_exception, BREAKPOINT_VECTOR, USER_PRIVILEGE,
  2642. 07790         overflow, OVERFLOW_VECTOR, USER_PRIVILEGE,
  2643. 07791         bounds_check, BOUNDS_VECTOR, INTR_PRIVILEGE,
  2644. 07792         inval_opcode, INVAL_OP_VECTOR, INTR_PRIVILEGE,
  2645. 07793         copr_not_available, COPROC_NOT_VECTOR, INTR_PRIVILEGE,
  2646. 07794         double_fault, DOUBLE_FAULT_VECTOR, INTR_PRIVILEGE,
  2647. 07795         copr_seg_overrun, COPROC_SEG_VECTOR, INTR_PRIVILEGE,
  2648. 07796         inval_tss, INVAL_TSS_VECTOR, INTR_PRIVILEGE,
  2649. 07797         segment_not_present, SEG_NOT_VECTOR, INTR_PRIVILEGE,
  2650. 07798         stack_exception, STACK_FAULT_VECTOR, INTR_PRIVILEGE,
  2651. 07799         general_protection, PROTECTION_VECTOR, INTR_PRIVILEGE,
  2652. 07800         page_fault, PAGE_FAULT_VECTOR, INTR_PRIVILEGE,
  2653. 07801         copr_error, COPROC_ERR_VECTOR, INTR_PRIVILEGE,
  2654. 07802         { hwint00, VECTOR( 0), INTR_PRIVILEGE },
  2655. 07803         { hwint01, VECTOR( 1), INTR_PRIVILEGE },
  2656. 07804         { hwint02, VECTOR( 2), INTR_PRIVILEGE },
  2657. 07805         { hwint03, VECTOR( 3), INTR_PRIVILEGE },
  2658. 07806         { hwint04, VECTOR( 4), INTR_PRIVILEGE },
  2659. 07807         { hwint05, VECTOR( 5), INTR_PRIVILEGE },
  2660. 07808         { hwint06, VECTOR( 6), INTR_PRIVILEGE },
  2661. 07809         { hwint07, VECTOR( 7), INTR_PRIVILEGE },
  2662. 07810         { hwint08, VECTOR( 8), INTR_PRIVILEGE },
  2663. 07811         { hwint09, VECTOR( 9), INTR_PRIVILEGE },
  2664. 07812         { hwint10, VECTOR(10), INTR_PRIVILEGE },
  2665. 07813         { hwint11, VECTOR(11), INTR_PRIVILEGE },
  2666. 07814         { hwint12, VECTOR(12), INTR_PRIVILEGE },
  2667. 07815         { hwint13, VECTOR(13), INTR_PRIVILEGE },
  2668. 07816         { hwint14, VECTOR(14), INTR_PRIVILEGE },
  2669. 07817         { hwint15, VECTOR(15), INTR_PRIVILEGE },
  2670. 07818   };
  2671. 07819
  2672. 07820   /* This is called early and can't use tables set up by main(). */
  2673. 07821   data_bytes = (phys_bytes) sizes[1] << CLICK_SHIFT;
  2674. 07822   if (sizes[0] == 0)
  2675. 07823         code_bytes = data_bytes;        /* common I&D */
  2676. 07824   else
  2677. 07825         code_bytes = (phys_bytes) sizes[0] << CLICK_SHIFT;
  2678. 07826
  2679. 07827   /* Build gdt and idt pointers in GDT where the BIOS expects them. */
  2680. 07828   dtp= (struct desctableptr_s *) &gdt[GDT_INDEX];
  2681. 07829   * (u16_t *) dtp->limit = (sizeof gdt) - 1;
  2682. 07830   * (u32_t *) dtp->base = vir2phys(gdt);
  2683. 07831
  2684. 07832   dtp= (struct desctableptr_s *) &gdt[IDT_INDEX];
  2685. 07833   * (u16_t *) dtp->limit = (sizeof idt) - 1;
  2686. 07834   * (u32_t *) dtp->base = vir2phys(idt);
  2687. 07835
  2688. 07836   /* Build segment descriptors for tasks and interrupt handlers. */
  2689. 07837   init_codeseg(&gdt[CS_INDEX], code_base, code_bytes, INTR_PRIVILEGE);
  2690. 07838   init_dataseg(&gdt[DS_INDEX], data_base, data_bytes, INTR_PRIVILEGE);
  2691. 07839   init_dataseg(&gdt[ES_INDEX], 0L, 0L, TASK_PRIVILEGE);
  2692. 07840
  2693. 07841   /* Build scratch descriptors for functions in klib88. */
  2694. 07842   init_dataseg(&gdt[DS_286_INDEX], (phys_bytes) 0,
  2695. 07843                (phys_bytes) MAX_286_SEG_SIZE, TASK_PRIVILEGE);
  2696. 07844   init_dataseg(&gdt[ES_286_INDEX], (phys_bytes) 0,
  2697. 07845                (phys_bytes) MAX_286_SEG_SIZE, TASK_PRIVILEGE);
  2698. 07846
  2699. 07847   /* Build local descriptors in GDT for LDT's in process table.
  2700. 07848    * The LDT's are allocated at compile time in the process table, and
  2701. 07849    * initialized whenever a process' map is initialized or changed.
  2702. 07850    */
  2703. 07851   for (rp = BEG_PROC_ADDR, ldt_selector = FIRST_LDT_INDEX * DESC_SIZE;
  2704. 07852        rp < END_PROC_ADDR; ++rp, ldt_selector += DESC_SIZE) {
  2705. 07853         init_dataseg(&gdt[ldt_selector / DESC_SIZE], vir2phys(rp->p_ldt),
  2706. 07854                      (phys_bytes) sizeof rp->p_ldt, INTR_PRIVILEGE);
  2707. 07855         gdt[ldt_selector / DESC_SIZE].access = PRESENT | LDT;
  2708. 07856         rp->p_ldt_sel = ldt_selector;
  2709. 07857   }
  2710. 07858
  2711. 07859   /* Build main TSS.
  2712. 07860    * This is used only to record the stack pointer to be used after an
  2713. 07861    * interrupt.
  2714. 07862    * The pointer is set up so that an interrupt automatically saves the
  2715. 07863    * current process's registers ip:cs:f:sp:ss in the correct slots in the
  2716. 07864    * process table.
  2717. 07865    */
  2718. 07866   tss.ss0 = DS_SELECTOR;
  2719. 07867   init_dataseg(&gdt[TSS_INDEX], vir2phys(&tss), (phys_bytes) sizeof tss,
  2720. 07868                                                         INTR_PRIVILEGE);
  2721. 07869   gdt[TSS_INDEX].access = PRESENT | (INTR_PRIVILEGE << DPL_SHIFT) | TSS_TYPE;
  2722. 07870   tss.iobase = sizeof tss;      /* empty i/o permissions map */
  2723. 07871
  2724. 07872   /* Build descriptors for interrupt gates in IDT. */
  2725. 07873   for (gtp = &gate_table[0];
  2726. 07874        gtp < &gate_table[sizeof gate_table / sizeof gate_table[0]]; ++gtp) {
  2727. 07875         int_gate(gtp->vec_nr, (phys_bytes) (vir_bytes) gtp->gate,
  2728. 07876                  PRESENT | INT_GATE_TYPE | (gtp->privilege << DPL_SHIFT));
  2729. 07877   }
  2730. 07878   int_gate(SYS_VECTOR, (phys_bytes) (vir_bytes) p_s_call,
  2731. 07879            PRESENT | (USER_PRIVILEGE << DPL_SHIFT) | INT_GATE_TYPE);
  2732. 07880   int_gate(LEVEL0_VECTOR, (phys_bytes) (vir_bytes) level0_call,
  2733. 07881            PRESENT | (TASK_PRIVILEGE << DPL_SHIFT) | INT_GATE_TYPE);
  2734. 07882   int_gate(SYS386_VECTOR, (phys_bytes) (vir_bytes) s_call,
  2735. 07883            PRESENT | (USER_PRIVILEGE << DPL_SHIFT) | INT_GATE_TYPE);
  2736. 07884 }
  2737. 07886 /*=========================================================================*
  2738. 07887  *                              init_codeseg                               *
  2739. 07888  *=========================================================================*/
  2740. 07889 PUBLIC void init_codeseg(segdp, base, size, privilege)
  2741. 07890 register struct segdesc_s *segdp;
  2742. 07891 phys_bytes base;
  2743. 07892 phys_bytes size;
  2744. 07893 int privilege;
  2745. 07894 {