📄 metaconstructor.c
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* Metaconstructor builds constructors. This is a primordial domain, * and it is one of the places where the recursion stops. * * Metaconstructor is considered a constructor by administrative fiat, * even though it does not run the constructor code. */#include <eros/target.h>#include <eros/Invoke.h>#include <eros/ReturnerKey.h>#include <eros/ProcessKey.h>#include <eros/Key.h>#include <eros/StdKeyType.h>#include <eros/ProcessState.h>#include <eros/NodeKey.h>#include <eros/NumberKey.h>#include <domain/domdbg.h>#include <domain/ConstructorKey.h>#include <domain/ProcessCreatorKey.h>#include <domain/SpaceBankKey.h>#include <domain/PccKey.h>#include <domain/Runtime.h>#include "constituents.h"uint32_t __rt_unkept = 1;#define DEBUG if (0)/* #define DEBUG if (1) *//* #define KR_CON_CONSTIT KR_APP(0) */#define KR_RETURNER KR_APP(1)#define KR_DISCRIM KR_APP(2)#define KR_YIELDCRE KR_APP(3) /* constructor domain creator */#define KR_SCRATCH KR_APP(4) /* constructor domain creator */#define KR_CON_SEG KR_APP(5) /* constructor program segment */#define KR_OSTREAM KR_APP(6) /* our mouth */#define KR_NEWDOM KR_APP(7) /* where new constructor goes */#define KR_YIELDBITS KR_APP(8)#define KR_RO_YIELDBITS KR_APP(9)#define KR_ARG0 KR_ARG(0)#define KR_ARG1 KR_ARG(1)#define KR_ARG2 KR_ARG(2)typedef struct { uint32_t constructor_pc;} MetaConInfo;/* On startup, entrypt of constructor is in KR_ARG0 */voidInitMetaCon(MetaConInfo *mci){ node_copy(KR_CONSTIT, KC_OSTREAM, KR_OSTREAM); DEBUG kdprintf(KR_OSTREAM, "Metacon inits\n"); node_copy(KR_CONSTIT, KC_CON_PC, KR_NEWDOM); number_get_word(KR_NEWDOM, &mci->constructor_pc); node_copy(KR_CONSTIT, KC_DISCRIM, KR_DISCRIM); node_copy(KR_CONSTIT, KC_RETURNER, KR_RETURNER); node_copy(KR_CONSTIT, KC_YIELDCRE, KR_YIELDCRE); node_copy(KR_CONSTIT, KC_CON_SEG, KR_CON_SEG); /* node_copy(KR_CONSTIT, KC_CON_CONSTIT, KR_CON_CONSTIT); */ /* Create a runtime bits node appropriate for our yields: */ spcbank_buy_nodes(KR_BANK, 1, KR_YIELDBITS, KR_VOID, KR_VOID); node_clone(KR_YIELDBITS, KR_RTBITS); node_swap(KR_YIELDBITS, RKT_CREATOR, KR_YIELDCRE, KR_VOID); /* Now make the yieldbits key read-only. */ { uint16_t keyData; node_get_key_data(KR_YIELDBITS, &keyData); node_make_node_key(KR_YIELDBITS, SEGMODE_RO | EROS_PAGE_BLSS, KR_RO_YIELDBITS); }}uint32_tMakeNewProduct(Message *msg, MetaConInfo *mci){ uint32_t result; struct Registers regs; msg->snd_key0 = KR_VOID; msg->snd_key1 = KR_VOID; msg->snd_key2 = KR_VOID; msg->snd_key3 = KR_VOID; msg->snd_code = 0; /* ordinary restart */ msg->snd_w1 = 0; msg->snd_w2 = 0; msg->snd_w3 = 0; msg->snd_len = 0; result = proccre_create_process(KR_YIELDCRE, KR_ARG0, KR_NEWDOM); if (result != RC_OK) return result; /* NOTE that if proccre_create_process succeeded, we know it's a good space bank. */ /* Install the schedule. KR_ARG1 can be reused after this. */ (void) process_swap(KR_NEWDOM, ProcSched, KR_ARG1, KR_VOID); (void) process_swap_keyreg(KR_NEWDOM, 5, KR_ARG1, KR_VOID);#define KR_ALTSCRATCH KR_ARG1 /* Build a constiuents node: */ result = spcbank_buy_nodes(KR_ARG0, 1, KR_ALTSCRATCH, KR_VOID, KR_VOID); if (result != RC_OK) goto destroy_product; /* The new constructor constituents are the same as ours, so just duplicate that: */ node_clone(KR_ALTSCRATCH, KR_CONSTIT); (void) process_swap_keyreg(KR_NEWDOM, 1, KR_ALTSCRATCH, KR_VOID);#undef KR_ALTSCRATCH /* runtime bits to product KR 2 */ (void) process_swap_keyreg(KR_NEWDOM, KR_RTBITS, KR_RO_YIELDBITS, KR_VOID); /* Install the address space of the new constructor */ (void) process_swap(KR_NEWDOM, ProcAddrSpace, KR_CON_SEG, KR_VOID); /* POPULATE KEY REGISTERS */ /* Place the new domain creator in the appropriate key register of the new constructor domain. */ (void) process_swap_keyreg(KR_NEWDOM, KR_SELF, KR_NEWDOM, KR_VOID); (void) process_swap_keyreg(KR_NEWDOM, KR_BANK, KR_ARG0, KR_VOID); (void) process_swap_keyreg(KR_NEWDOM, KR_RETURN, KR_RETURN, KR_VOID); /* Fetch out the register values, mostly for the benefit of Retrieving the PC -- this prevents us from needing to hard-code the PC, which will inevitably change. */ (void) process_get_regs(KR_NEWDOM, ®s); DEBUG kdprintf(KR_OSTREAM, "Got regs\n"); /* Unless we set them otherwise, the register values are zero. We now need to set the PC and the segment registers. */ regs.CS = DOMAIN_CODE_SEG; regs.SS = DOMAIN_DATA_SEG; regs.DS = DOMAIN_DATA_SEG; regs.ES = DOMAIN_DATA_SEG; regs.FS = DOMAIN_DATA_SEG; regs.GS = DOMAIN_DATA_SEG; regs.pc = mci->constructor_pc; regs.EFLAGS = 0x200; regs.faultCode = 0; regs.faultInfo = 0; regs.domState = RS_Waiting; regs.domFlags = 0; /* Set the new register values. */ (void) process_set_regs(KR_NEWDOM, ®s); DEBUG kdprintf(KR_OSTREAM, "Wrote regs\n"); (void) process_make_fault_key(KR_NEWDOM, KR_SCRATCH); msg->snd_invKey = KR_SCRATCH; return RC_OK;destroy_product: (void) proccre_destroy_process(KR_YIELDCRE, KR_ARG0, KR_NEWDOM); return RC_NoMoreNodes;}intProcessRequest(Message *msg, MetaConInfo* mci){ /*initialize the keys being sent*/ msg->snd_len = 0; msg->snd_key0 = KR_VOID; msg->snd_key1 = KR_VOID; msg->snd_key2 = KR_VOID; msg->snd_key3 = KR_VOID; msg->snd_code = RC_OK; msg->snd_w1 = 0; msg->snd_w2 = 0; msg->snd_w3 = 0; msg->snd_invKey = KR_RETURN; switch (msg->rcv_code) { case OC_Constructor_IsDiscreet: { msg->snd_w1 = 1; /* answer YES */ msg->snd_code = RC_OK; return 1; } case OC_Constructor_Request: { msg->snd_code = MakeNewProduct(msg, mci); return 1; } case OC_Constructor_Seal: { msg->snd_code = 1; /* answer YES */ return 1; } case OC_KeyType: /* check alleged keytype */ { msg->snd_code = RC_OK; msg->snd_w1 = AKT_MetaConstructor; return 1; } default: break; } msg->snd_code = RC_UnknownRequest; return 1;}intmain(){ Message msg; MetaConInfo mci; InitMetaCon(&mci); msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_code = 0; msg.snd_w1 = 0; msg.snd_w2 = 0; msg.snd_w3 = 0; msg.snd_len = 0; msg.snd_data = 0; msg.snd_invKey = KR_VOID; msg.rcv_key0 = KR_ARG0; msg.rcv_key1 = KR_ARG1; msg.rcv_key2 = KR_ARG2; msg.rcv_key3 = KR_RETURN; msg.rcv_data = 0; msg.rcv_len = 0; do { /* no need to re-initialize rcv_len, since always 0 */ RETURN(&msg); } while (ProcessRequest(&msg, &mci)); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -