mirror of
https://github.com/SmallPond/MIT6.828_OS.git
synced 2026-05-03 09:50:32 +08:00
my solution to lab 6
This commit is contained in:
88
lab/lab6.si4project/Backup/e1000(1028).c
Normal file
88
lab/lab6.si4project/Backup/e1000(1028).c
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <kern/e1000.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <kern/pci.h>
|
||||
#include <kern/pcireg.h>
|
||||
#include <inc/string.h>
|
||||
|
||||
|
||||
// LAB 6: Your driver code here
|
||||
#define E1000_LOCATE(offset) (offset >> 2)
|
||||
volatile uint32_t *e1000;
|
||||
|
||||
/* 为描述符列表分配静态内存 */
|
||||
struct E1000TxDesc tx_desc_list[TX_DESC_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
char pbuf[TX_DESC_SIZE][TX_PACKET_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
|
||||
void
|
||||
e1000_transmit_init()
|
||||
{
|
||||
size_t i;
|
||||
memset(tx_desc_list, 0 , sizeof(struct E1000TxDesc) * TX_DESC_SIZE);
|
||||
for (i = 0; i < TX_DESC_SIZE; i++) {
|
||||
tx_desc_list[i].buffer_addr = PADDR(pbuf[i]);
|
||||
tx_desc_list[i].status = E1000_TXD_STAT_DD;
|
||||
tx_desc_list[i].cmd = E1000_TXD_CMD_RS | E1000_TXD_CMD_EOP;
|
||||
|
||||
}
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDBAL)] = PADDR(tx_desc_list);
|
||||
e1000[E1000_LOCATE(E1000_TDBAH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDLEN)] = sizeof(struct E1000TxDesc) * TX_DESC_SIZE;
|
||||
// ensure that TDH and TDT are 0 index not offset
|
||||
e1000[E1000_LOCATE(E1000_TDH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = 0;
|
||||
|
||||
// Initialize the Transmit Control Register (TCTL)
|
||||
e1000[E1000_LOCATE(E1000_TCTL)] = E1000_TCTL_EN |
|
||||
E1000_TCTL_PSP |
|
||||
(E1000_TCTL_CT & (0x10 << 4)) |
|
||||
(E1000_TCTL_COLD & (0x40 << 12));
|
||||
|
||||
// 10 8 6
|
||||
// 10 8 12
|
||||
e1000[E1000_LOCATE(E1000_TIPG)] = 10 | (8 << 10) | (12 << 20);
|
||||
}
|
||||
|
||||
int
|
||||
e1000_transmit(void *addr, size_t len)
|
||||
{
|
||||
|
||||
size_t tdt = e1000[E1000_LOCATE(E1000_TDT)];
|
||||
struct E1000TxDesc *tail_desc = &tx_desc_list[tdt];
|
||||
|
||||
|
||||
if ( !(tail_desc->status & E1000_TXD_STAT_DD )) {
|
||||
// Status is not DD
|
||||
return -1;
|
||||
}
|
||||
memmove(pbuf[tdt], addr, len);
|
||||
|
||||
tail_desc->length = (uint16_t )len;
|
||||
// clear DD
|
||||
tail_desc->status &= (~E1000_TXD_STAT_DD);
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = (tdt+1) % TX_DESC_SIZE;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
pci_e1000_attach(struct pci_func * pcif)
|
||||
{
|
||||
int r;
|
||||
// 使能E1000,分配 MMIO等
|
||||
pci_func_enable(pcif);
|
||||
// 映射,并保存其虚拟地址,方便访问。
|
||||
e1000 = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]);
|
||||
e1000_transmit_init();
|
||||
|
||||
cprintf("device status:[%08x]\n", e1000[E1000_LOCATE(E1000_DEVICE_STATUS)]);
|
||||
/*
|
||||
char mes[40] = "e1000 transmit :HELLO";
|
||||
for (size_t i = 0; i < 10 ; i++) {
|
||||
e1000_transmit(mes, strlen(mes));
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
86
lab/lab6.si4project/Backup/e1000(1108).h
Normal file
86
lab/lab6.si4project/Backup/e1000(1108).h
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef JOS_KERN_E1000_H
|
||||
#define JOS_KERN_E1000_H
|
||||
|
||||
#include <inc/types.h>
|
||||
|
||||
#define PCI_E1000_VENDOR_ID 0x8086
|
||||
#define PCI_E1000_DEVICE_ID 0x100E
|
||||
|
||||
/* 循环队列的长度*/
|
||||
#define TX_DESC_SIZE 32
|
||||
#define TX_PACKET_SIZE 2048
|
||||
/* Register Set
|
||||
*
|
||||
* RW - register is both readable and writable
|
||||
*
|
||||
*/
|
||||
|
||||
#define E1000_DEVICE_STATUS 0x00008 /* Device Status - RO */
|
||||
|
||||
#define E1000_RCTL 0x00100 /* RX Control - RW */
|
||||
#define E1000_TCTL 0x00400 /* TX Control - RW */
|
||||
|
||||
|
||||
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
|
||||
#define E1000_TDBAH 0X03804 /* TX Descriptor Base Address High - RW */
|
||||
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
|
||||
|
||||
#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
|
||||
#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
|
||||
|
||||
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
|
||||
|
||||
/* Transmit Control */
|
||||
#define E1000_TCTL_RST 0x00000001 /* Reserved */
|
||||
#define E1000_TCTL_EN 0x00000002 /* enable tx */
|
||||
#define E1000_TCTL_BCE 0x00000004 /* Reserved */
|
||||
#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
|
||||
#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
|
||||
#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
|
||||
#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
|
||||
#define E1000_TCTL_PBE 0x00800000 /* Reserved */
|
||||
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
|
||||
#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
|
||||
#define E1000_TCTL_MULR 0x10000000 /* Reserved */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Transmit Descriptor */
|
||||
struct E1000TxDesc {
|
||||
uint64_t buffer_addr; /* Address of the descriptor's data buffer */
|
||||
|
||||
uint16_t length; /* Data buffer length */
|
||||
uint8_t cso; /* Checksum offset */
|
||||
uint8_t cmd; /* Descriptor control */
|
||||
|
||||
uint8_t status; /* Descriptor status */
|
||||
uint8_t css; /* Checksum start */
|
||||
uint16_t special;
|
||||
|
||||
}__attribute__((packed));
|
||||
|
||||
|
||||
/* Transmit Descriptor bit definitions */
|
||||
#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
|
||||
#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
|
||||
|
||||
|
||||
#define E1000_TXD_CMD_EOP 0x01 /* End of Packet */
|
||||
#define E1000_TXD_CMD_RS 0x08 /* Report Status */
|
||||
|
||||
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
|
||||
#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
|
||||
#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
|
||||
#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
|
||||
#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
|
||||
|
||||
|
||||
|
||||
int e1000_transmit(void *addr, size_t len);
|
||||
|
||||
|
||||
#endif // SOL >= 6
|
||||
|
||||
|
||||
88
lab/lab6.si4project/Backup/e1000(18).c
Normal file
88
lab/lab6.si4project/Backup/e1000(18).c
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <kern/e1000.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <kern/pci.h>
|
||||
#include <kern/pcireg.h>
|
||||
#include <inc/string.h>
|
||||
|
||||
|
||||
// LAB 6: Your driver code here
|
||||
#define E1000_LOCATE(offset) (offset >> 2)
|
||||
volatile uint32_t *e1000;
|
||||
|
||||
/* 为描述符列表分配静态内存 */
|
||||
struct E1000TxDesc tx_desc_list[TX_DESC_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
char pbuf[TX_DESC_SIZE][TX_PACKET_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
|
||||
void
|
||||
e1000_transmit_init()
|
||||
{
|
||||
size_t i;
|
||||
memset(tx_desc_list, 0 , sizeof(struct E1000TxDesc) * TX_DESC_SIZE);
|
||||
for (i = 0; i < TX_DESC_SIZE; i++) {
|
||||
tx_desc_list[i].buffer_addr = PADDR(pbuf[i]);
|
||||
tx_desc_list[i].status = E1000_TXD_STAT_DD;
|
||||
tx_desc_list[i].cmd = E1000_TXD_CMD_RS | E1000_TXD_CMD_EOP;
|
||||
|
||||
}
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDBAL)] = PADDR(tx_desc_list);
|
||||
e1000[E1000_LOCATE(E1000_TDBAH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDLEN)] = sizeof(struct E1000TxDesc) * TX_DESC_SIZE;
|
||||
// ensure that TDH and TDT are 0 index not offset
|
||||
e1000[E1000_LOCATE(E1000_TDH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = 0;
|
||||
|
||||
// Initialize the Transmit Control Register (TCTL)
|
||||
e1000[E1000_LOCATE(E1000_TCTL)] = E1000_TCTL_EN |
|
||||
E1000_TCTL_PSP |
|
||||
(E1000_TCTL_CT & (0x10 << 4)) |
|
||||
(E1000_TCTL_COLD & (0x40 << 12));
|
||||
|
||||
// 10 8 6
|
||||
// 10 8 12
|
||||
e1000[E1000_LOCATE(E1000_TIPG)] = 10 | (8 << 10) | (12 << 20);
|
||||
}
|
||||
|
||||
int
|
||||
e1000_transmit(void *addr, size_t len)
|
||||
{
|
||||
|
||||
size_t tdt = e1000[E1000_LOCATE(E1000_TDT)];
|
||||
struct E1000TxDesc *tail_desc = &tx_desc_list[tdt];
|
||||
|
||||
|
||||
if ( !(tail_desc->status & E1000_TXD_STAT_DD )) {
|
||||
// Status is not DD
|
||||
return -1;
|
||||
}
|
||||
memmove(pbuf[tdt], addr, len);
|
||||
|
||||
tail_desc->length = (uint16_t )len;
|
||||
// clear DD
|
||||
tail_desc->status &= (~E1000_TXD_STAT_DD);
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = (tdt+1) % TX_DESC_SIZE;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
pci_e1000_attach(struct pci_func * pcif)
|
||||
{
|
||||
int r;
|
||||
// 使能E1000,分配 MMIO等
|
||||
pci_func_enable(pcif);
|
||||
// 映射,并保存其虚拟地址,方便访问。
|
||||
e1000 = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]);
|
||||
e1000_transmit_init();
|
||||
|
||||
cprintf("device status:[%08x]\n", e1000[E1000_LOCATE(E1000_DEVICE_STATUS)]);
|
||||
/*
|
||||
char mes[40] = "e1000 transmit :HELLO";
|
||||
for (size_t i = 0; i < 10 ; i++) {
|
||||
e1000_transmit(mes, strlen(mes));
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
59
lab/lab6.si4project/Backup/e1000(2502).c
Normal file
59
lab/lab6.si4project/Backup/e1000(2502).c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <kern/e1000.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <kern/pci.h>
|
||||
#include <kern/pcireg.h>
|
||||
#include <inc/string.h>
|
||||
|
||||
|
||||
// LAB 6: Your driver code here
|
||||
#define E1000_LOCATE(offset) (offset >> 2)
|
||||
volatile uint32_t *e1000;
|
||||
|
||||
/* 为描述符列表分配静态内存 */
|
||||
struct E1000TxDesc tx_desc_list[TX_DESC_SIZE];
|
||||
struct Packet pack_buf[TX_DESC_SIZE];
|
||||
|
||||
|
||||
void
|
||||
e1000_transmit_init()
|
||||
{
|
||||
size_t i;
|
||||
memset(tx_desc_list, 0 , sizeof(struct E1000TxDesc) * TX_DESC_SIZE);
|
||||
for (i = 0; i < TX_DESC_SIZE; i++) {
|
||||
tx_desc_list[i].buffer_addr = PADDR(&pack_buf[i]);
|
||||
tx_desc_list[i].status |= E1000_TXD_STAT_DD;
|
||||
tx_desc_list[i].cmd |= E1000_TXD_CMD_RS;
|
||||
|
||||
}
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDBAL)] = PADDR(tx_desc_list);
|
||||
e1000[E1000_LOCATE(E1000_TDBAH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDLEN)] = sizeof(struct E1000TxDesc) * TX_DESC_SIZE;
|
||||
// ensure that TDH and TDT are 0
|
||||
e1000[E1000_LOCATE(E1000_TDH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = 0;
|
||||
|
||||
// Initialize the Transmit Control Register (TCTL)
|
||||
e1000[E1000_LOCATE(E1000_TCTL)] |= E1000_TCTL_EN;
|
||||
e1000[E1000_LOCATE(E1000_TCTL)] |= E1000_TCTL_PSP;
|
||||
e1000[E1000_LOCATE(E1000_TCTL)] |= (E1000_TCTL_CT & (0x10 << 4));
|
||||
e1000[E1000_LOCATE(E1000_TCTL)] |= (E1000_TCTL_CT & (0x40 << 12));
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TIPG)] = 10 | (8 << 10) | (6 << 20);
|
||||
}
|
||||
|
||||
int
|
||||
pci_e1000_attach(struct pci_func * pcif)
|
||||
{
|
||||
int r;
|
||||
// 使能E1000,分配 MMIO等
|
||||
pci_func_enable(pcif);
|
||||
// 映射,并保存其虚拟地址,方便访问。
|
||||
e1000 = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]);
|
||||
e1000_transmit_init();
|
||||
|
||||
cprintf("device status:[%08x]\n", e1000[E1000_LOCATE(E1000_DEVICE_STATUS)]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
86
lab/lab6.si4project/Backup/e1000(2669).h
Normal file
86
lab/lab6.si4project/Backup/e1000(2669).h
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef JOS_KERN_E1000_H
|
||||
#define JOS_KERN_E1000_H
|
||||
|
||||
#include <inc/types.h>
|
||||
|
||||
#define PCI_E1000_VENDOR_ID 0x8086
|
||||
#define PCI_E1000_DEVICE_ID 0x100E
|
||||
|
||||
/* 循环队列的长度*/
|
||||
#define TX_DESC_SIZE 32
|
||||
#define TX_PACKET_SIZE 2048
|
||||
/* Register Set
|
||||
*
|
||||
* RW - register is both readable and writable
|
||||
*
|
||||
*/
|
||||
|
||||
#define E1000_DEVICE_STATUS 0x00008 /* Device Status - RO */
|
||||
|
||||
#define E1000_RCTL 0x00100 /* RX Control - RW */
|
||||
#define E1000_TCTL 0x00400 /* TX Control - RW */
|
||||
|
||||
|
||||
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
|
||||
#define E1000_TDBAH 0X03804 /* TX Descriptor Base Address High - RW */
|
||||
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
|
||||
|
||||
#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
|
||||
#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
|
||||
|
||||
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
|
||||
|
||||
/* Transmit Control */
|
||||
#define E1000_TCTL_RST 0x00000001 /* Reserved */
|
||||
#define E1000_TCTL_EN 0x00000002 /* enable tx */
|
||||
#define E1000_TCTL_BCE 0x00000004 /* Reserved */
|
||||
#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
|
||||
#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
|
||||
#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
|
||||
#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
|
||||
#define E1000_TCTL_PBE 0x00800000 /* Reserved */
|
||||
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
|
||||
#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
|
||||
#define E1000_TCTL_MULR 0x10000000 /* Reserved */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Transmit Descriptor */
|
||||
struct E1000TxDesc {
|
||||
uint64_t buffer_addr; /* Address of the descriptor's data buffer */
|
||||
|
||||
uint16_t length; /* Data buffer length */
|
||||
uint8_t cso; /* Checksum offset */
|
||||
uint8_t cmd; /* Descriptor control */
|
||||
|
||||
uint8_t status; /* Descriptor status */
|
||||
uint8_t css; /* Checksum start */
|
||||
uint16_t special;
|
||||
|
||||
}__attribute__((packed));
|
||||
|
||||
|
||||
/* Transmit Descriptor bit definitions */
|
||||
#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
|
||||
#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
|
||||
|
||||
|
||||
#define E1000_TXD_CMD_EOP 0x01 /* End of Packet */
|
||||
#define E1000_TXD_CMD_RS 0x08 /* Report Status */
|
||||
|
||||
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
|
||||
#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
|
||||
#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
|
||||
#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
|
||||
#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
|
||||
|
||||
|
||||
|
||||
int e1000_transmit(void *addr, size_t len);
|
||||
|
||||
|
||||
#endif // SOL >= 6
|
||||
|
||||
|
||||
131
lab/lab6.si4project/Backup/e1000(3017).h
Normal file
131
lab/lab6.si4project/Backup/e1000(3017).h
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef JOS_KERN_E1000_H
|
||||
#define JOS_KERN_E1000_H
|
||||
|
||||
#include "kern/pci.h"
|
||||
|
||||
#define E1000_VENDER_ID_82540EM 0x8086
|
||||
#define E1000_DEV_ID_82540EM 0x100E
|
||||
|
||||
#define TXDESCS 32
|
||||
#define TX_PKT_SIZE 1518
|
||||
|
||||
#define E1000_STATUS 0x00008 /* Device Status - RO */
|
||||
#define E1000_TCTL 0x00400 /* TX Control - RW */
|
||||
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
|
||||
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
|
||||
#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
|
||||
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
|
||||
#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
|
||||
#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
|
||||
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
|
||||
#define E1000_TXD_CMD_EOP 0x00000001 /* End of Packet */
|
||||
#define E1000_TXD_CMD_RS 0x00000008 /* Report Status */
|
||||
|
||||
|
||||
#define RXDESCS 128
|
||||
#define RX_PKT_SIZE 1518
|
||||
#define E1000_RCTL 0x00100
|
||||
#define E1000_RCTL_EN 0x00000002 /* enable */
|
||||
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
|
||||
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
|
||||
#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
|
||||
#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
|
||||
#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
|
||||
#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
|
||||
#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
|
||||
#define E1000_RA 0x05400 /* Receive Address - RW Array */
|
||||
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
|
||||
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
|
||||
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
|
||||
|
||||
enum {
|
||||
E_TRANSMIT_RETRY = 1,
|
||||
E_RECEIVE_RETRY,
|
||||
};
|
||||
|
||||
|
||||
/*transmit descriptor related*/
|
||||
struct e1000_tx_desc
|
||||
{
|
||||
uint64_t addr;
|
||||
uint16_t length;
|
||||
uint8_t cso;
|
||||
uint8_t cmd;
|
||||
uint8_t status;
|
||||
uint8_t css;
|
||||
uint16_t special;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct e1000_tctl {
|
||||
uint32_t rsv1: 1;
|
||||
uint32_t en: 1;
|
||||
uint32_t rsv2: 1;
|
||||
uint32_t psp: 1;
|
||||
uint32_t ct: 8;
|
||||
uint32_t cold: 10;
|
||||
uint32_t swxoff: 1;
|
||||
uint32_t rsv3: 1;
|
||||
uint32_t rtlc: 1;
|
||||
uint32_t nrtu: 1;
|
||||
uint32_t rsv4: 6;
|
||||
};
|
||||
|
||||
struct e1000_tipg {
|
||||
uint32_t ipgt: 10;
|
||||
uint32_t ipgr1: 10;
|
||||
uint32_t ipgr2: 10;
|
||||
uint32_t rsv: 2;
|
||||
};
|
||||
|
||||
struct e1000_tdt {
|
||||
uint16_t tdt;
|
||||
uint16_t rsv;
|
||||
};
|
||||
|
||||
struct e1000_tdlen {
|
||||
uint32_t zero: 7;
|
||||
uint32_t len: 13;
|
||||
uint32_t rsv: 12;
|
||||
};
|
||||
|
||||
struct e1000_tdh {
|
||||
uint16_t tdh;
|
||||
uint16_t rsv;
|
||||
};
|
||||
|
||||
|
||||
/*receive descriptor related*/
|
||||
struct e1000_rx_desc {
|
||||
uint64_t addr;
|
||||
uint16_t length;
|
||||
uint16_t chksum;
|
||||
uint8_t status;
|
||||
uint8_t errors;
|
||||
uint16_t special;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct e1000_rdlen {
|
||||
unsigned zero: 7;
|
||||
unsigned len: 13;
|
||||
unsigned rsv: 12;
|
||||
};
|
||||
|
||||
struct e1000_rdh {
|
||||
uint16_t rdh;
|
||||
uint16_t rsv;
|
||||
};
|
||||
|
||||
struct e1000_rdt {
|
||||
uint16_t rdt;
|
||||
uint16_t rsv;
|
||||
};
|
||||
|
||||
|
||||
int e1000_attachfn(struct pci_func *pcif);
|
||||
static void e1000_transmit_init();
|
||||
int e1000_transmit(void *data, size_t len);
|
||||
|
||||
static void e1000_receive_init();
|
||||
int e1000_receive(void *addr, size_t *len);
|
||||
|
||||
#endif // JOS_KERN_E1000_H
|
||||
94
lab/lab6.si4project/Backup/e1000(3240).h
Normal file
94
lab/lab6.si4project/Backup/e1000(3240).h
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef JOS_KERN_E1000_H
|
||||
#define JOS_KERN_E1000_H
|
||||
|
||||
#include <inc/types.h>
|
||||
|
||||
#define PCI_E1000_VENDOR_ID 0x8086
|
||||
#define PCI_E1000_DEVICE_ID 0x100E
|
||||
|
||||
/* 循环队列的长度*/
|
||||
#define TX_DESC_SIZE 32
|
||||
/* Register Set
|
||||
*
|
||||
* RW - register is both readable and writable
|
||||
*
|
||||
*/
|
||||
|
||||
#define E1000_DEVICE_STATUS 0x00008 /* Device Status - RO */
|
||||
|
||||
#define E1000_RCTL 0x00100 /* RX Control - RW */
|
||||
#define E1000_TCTL 0x00400 /* TX Control - RW */
|
||||
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
|
||||
|
||||
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
|
||||
#define E1000_TDBAH 0X03804 /* TX Descriptor Base Address High - RW */
|
||||
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
|
||||
|
||||
#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
|
||||
#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
|
||||
|
||||
|
||||
/* Transmit Control */
|
||||
#define E1000_TCTL_RST 0x00000001 /* Reserved */
|
||||
#define E1000_TCTL_EN 0x00000002 /* enable tx */
|
||||
#define E1000_TCTL_BCE 0x00000004 /* Reserved */
|
||||
#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
|
||||
#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
|
||||
#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
|
||||
#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
|
||||
#define E1000_TCTL_PBE 0x00800000 /* Reserved */
|
||||
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
|
||||
#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
|
||||
#define E1000_TCTL_MULR 0x10000000 /* Reserved */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Transmit Descriptor */
|
||||
struct E1000TxDesc {
|
||||
uint64_t buffer_addr; /* Address of the descriptor's data buffer */
|
||||
|
||||
uint16_t length; /* Data buffer length */
|
||||
uint8_t cso; /* Checksum offset */
|
||||
uint8_t cmd; /* Descriptor control */
|
||||
|
||||
uint8_t status; /* Descriptor status */
|
||||
uint8_t css; /* Checksum start */
|
||||
uint16_t special;
|
||||
|
||||
}__attribute__((packed));
|
||||
|
||||
|
||||
/* Transmit Descriptor bit definitions */
|
||||
#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
|
||||
#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
|
||||
#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
|
||||
#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
|
||||
#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
|
||||
#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
|
||||
#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
|
||||
#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
|
||||
#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
|
||||
#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
|
||||
#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
|
||||
#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
|
||||
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
|
||||
#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
|
||||
#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
|
||||
#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
|
||||
#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
|
||||
#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
|
||||
#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
|
||||
#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
|
||||
|
||||
/* packet buffer*/
|
||||
struct Packet {
|
||||
char body[2048];
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // SOL >= 6
|
||||
|
||||
|
||||
148
lab/lab6.si4project/Backup/e1000(460).c
Normal file
148
lab/lab6.si4project/Backup/e1000(460).c
Normal file
@@ -0,0 +1,148 @@
|
||||
#include <kern/e1000.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <kern/pci.h>
|
||||
#include <kern/pcireg.h>
|
||||
#include <inc/string.h>
|
||||
|
||||
|
||||
// LAB 6: Your driver code here
|
||||
#define E1000_LOCATE(offset) (offset >> 2)
|
||||
volatile uint32_t *e1000;
|
||||
|
||||
uint32_t E1000_MAC[6] = {0x52, 0x54, 0x00, 0x12, 0x34, 0x56};
|
||||
|
||||
/* 为描述符列表分配静态内存 */
|
||||
struct E1000TxDesc tx_desc_list[TX_DESC_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
char tx_pbuf[TX_DESC_SIZE][TX_PACKET_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
|
||||
struct E1000RxDesc rx_desc_list[RX_DESC_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
char rx_pbuf[RX_DESC_SIZE][RX_PACKET_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
|
||||
void
|
||||
e1000_transmit_init()
|
||||
{
|
||||
size_t i;
|
||||
memset(tx_desc_list, 0 , sizeof(struct E1000TxDesc) * TX_DESC_SIZE);
|
||||
for (i = 0; i < TX_DESC_SIZE; i++) {
|
||||
tx_desc_list[i].buffer_addr = PADDR(tx_pbuf[i]);
|
||||
tx_desc_list[i].status = E1000_TXD_STAT_DD;
|
||||
tx_desc_list[i].cmd = E1000_TXD_CMD_RS | E1000_TXD_CMD_EOP;
|
||||
|
||||
}
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDBAL)] = PADDR(tx_desc_list);
|
||||
e1000[E1000_LOCATE(E1000_TDBAH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDLEN)] = sizeof(struct E1000TxDesc) * TX_DESC_SIZE;
|
||||
// ensure that TDH and TDT are 0 index not offset
|
||||
e1000[E1000_LOCATE(E1000_TDH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = 0;
|
||||
|
||||
// Initialize the Transmit Control Register (TCTL)
|
||||
e1000[E1000_LOCATE(E1000_TCTL)] = E1000_TCTL_EN |
|
||||
E1000_TCTL_PSP |
|
||||
(E1000_TCTL_CT & (0x10 << 4)) |
|
||||
(E1000_TCTL_COLD & (0x40 << 12));
|
||||
|
||||
// 10 8 6
|
||||
// 10 8 12
|
||||
e1000[E1000_LOCATE(E1000_TIPG)] = 10 | (8 << 10) | (12 << 20);
|
||||
}
|
||||
|
||||
int
|
||||
e1000_transmit(void *addr, size_t len)
|
||||
{
|
||||
|
||||
size_t tdt = e1000[E1000_LOCATE(E1000_TDT)];
|
||||
struct E1000TxDesc *tail_desc = &tx_desc_list[tdt];
|
||||
|
||||
|
||||
if ( !(tail_desc->status & E1000_TXD_STAT_DD )) {
|
||||
// Status is not DD
|
||||
return -1;
|
||||
}
|
||||
memmove(tx_pbuf[tdt], addr, len);
|
||||
|
||||
tail_desc->length = (uint16_t )len;
|
||||
// clear DD
|
||||
tail_desc->status &= (~E1000_TXD_STAT_DD);
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = (tdt+1) % TX_DESC_SIZE;
|
||||
|
||||
// cprintf("transmit a packet: %s", addr);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
e1000_set_mac_addr(uint32_t mac[])
|
||||
{
|
||||
uint32_t low = 0, high = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
low |= mac[i] << (8 * i);
|
||||
}
|
||||
|
||||
for (i = 4; i < 6; i++) {
|
||||
high |= mac[i] << (8 * i);
|
||||
}
|
||||
|
||||
e1000[E1000_LOCATE(E1000_RA)] = low;
|
||||
e1000[E1000_LOCATE(E1000_RA) + 1] = high | E1000_RAH_AV;
|
||||
}
|
||||
|
||||
void
|
||||
e1000_receive_init()
|
||||
{
|
||||
size_t i;
|
||||
memset(rx_desc_list, 0 , sizeof(struct E1000RxDesc) * RX_DESC_SIZE);
|
||||
for (i = 0; i < RX_DESC_SIZE; i++) {
|
||||
rx_desc_list[i].buffer_addr = PADDR(rx_pbuf[i]);
|
||||
}
|
||||
e1000_set_mac_addr(E1000_MAC);
|
||||
cprintf("mac addr %x:%x", e1000[E1000_LOCATE(E1000_RA)], e1000[E1000_LOCATE(E1000_RA) + 1] );
|
||||
e1000[E1000_LOCATE(E1000_ICS)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_IMS)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_RDBAL)] = PADDR(rx_desc_list);
|
||||
e1000[E1000_LOCATE(E1000_RDBAH)] = 0;
|
||||
|
||||
e1000[E1000_LOCATE(E1000_RDLEN)] = sizeof(struct E1000RxDesc) * RX_DESC_SIZE;
|
||||
e1000[E1000_LOCATE(E1000_RDH)] = RX_DESC_SIZE - 1;
|
||||
e1000[E1000_LOCATE(E1000_RDH)] = 0;
|
||||
|
||||
e1000[E1000_LOCATE(E1000_RCTL)] = E1000_RCTL_EN | E1000_RCTL_SECRC | E1000_RCTL_BAM | E1000_RCTL_SZ_2048;
|
||||
|
||||
}
|
||||
|
||||
int e1000_receive(void *buf, size_t *len)
|
||||
{
|
||||
static size_t next = 0;
|
||||
size_t tail = e1000[E1000_LOCATE(E1000_RDT)];
|
||||
if ( !(rx_desc_list[next].status & E1000_RXD_STAT_DD) ) {
|
||||
// cprintf("no packet\n");
|
||||
return -1;
|
||||
}
|
||||
*len = rx_desc_list[next].length;
|
||||
memcpy(buf, rx_pbuf[next], *len);
|
||||
|
||||
rx_desc_list[next].status &= ~E1000_RXD_STAT_DD;
|
||||
next = (next + 1) % RX_DESC_SIZE;
|
||||
e1000[E1000_LOCATE(E1000_RDT)] = (tail + 1 ) % RX_DESC_SIZE;
|
||||
cprintf("e1000_receive return 0\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pci_e1000_attach(struct pci_func * pcif)
|
||||
{
|
||||
int r;
|
||||
// 使能E1000,分配 MMIO等
|
||||
pci_func_enable(pcif);
|
||||
// 映射,并保存其虚拟地址,方便访问。
|
||||
e1000 = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]);
|
||||
e1000_transmit_init();
|
||||
e1000_receive_init();
|
||||
cprintf("device status:[%08x]\n", e1000[E1000_LOCATE(E1000_DEVICE_STATUS)]);
|
||||
return 0;
|
||||
}
|
||||
120
lab/lab6.si4project/Backup/e1000(5113).h
Normal file
120
lab/lab6.si4project/Backup/e1000(5113).h
Normal file
@@ -0,0 +1,120 @@
|
||||
#ifndef JOS_KERN_E1000_H
|
||||
#define JOS_KERN_E1000_H
|
||||
|
||||
#include <inc/types.h>
|
||||
|
||||
#define PCI_E1000_VENDOR_ID 0x8086
|
||||
#define PCI_E1000_DEVICE_ID 0x100E
|
||||
|
||||
/* 循环队列的长度*/
|
||||
#define TX_DESC_SIZE 32
|
||||
#define TX_PACKET_SIZE 2048
|
||||
|
||||
#define RX_DESC_SIZE 128
|
||||
#define RX_PACKET_SIZE 2048
|
||||
|
||||
/* Register Set
|
||||
*
|
||||
* RW - register is both readable and writable
|
||||
*
|
||||
*/
|
||||
|
||||
#define E1000_DEVICE_STATUS 0x00008 /* Device Status - RO */
|
||||
|
||||
#define E1000_RCTL 0x00100 /* RX Control - RW */
|
||||
#define E1000_TCTL 0x00400 /* TX Control - RW */
|
||||
|
||||
|
||||
|
||||
#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
|
||||
#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
|
||||
#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
|
||||
#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
|
||||
#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
|
||||
#define E1000_RA 0x05400 /* Receive Address - RW Array */
|
||||
|
||||
|
||||
|
||||
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
|
||||
#define E1000_TDBAH 0X03804 /* TX Descriptor Base Address High - RW */
|
||||
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
|
||||
|
||||
#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
|
||||
#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
|
||||
|
||||
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
|
||||
|
||||
/* Transmit Control */
|
||||
#define E1000_TCTL_RST 0x00000001 /* Reserved */
|
||||
#define E1000_TCTL_EN 0x00000002 /* enable tx */
|
||||
#define E1000_TCTL_BCE 0x00000004 /* Reserved */
|
||||
#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
|
||||
#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
|
||||
#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
|
||||
#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
|
||||
#define E1000_TCTL_PBE 0x00800000 /* Reserved */
|
||||
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
|
||||
#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
|
||||
#define E1000_TCTL_MULR 0x10000000 /* Reserved */
|
||||
|
||||
|
||||
#define E1000_RCTL_EN 0x00000002 /* enable */
|
||||
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
|
||||
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
|
||||
|
||||
|
||||
|
||||
/* Transmit Descriptor */
|
||||
struct E1000TxDesc {
|
||||
uint64_t buffer_addr; /* Address of the descriptor's data buffer */
|
||||
|
||||
uint16_t length; /* Data buffer length */
|
||||
uint8_t cso; /* Checksum offset */
|
||||
uint8_t cmd; /* Descriptor control */
|
||||
|
||||
uint8_t status; /* Descriptor status */
|
||||
uint8_t css; /* Checksum start */
|
||||
uint16_t special;
|
||||
|
||||
}__attribute__((packed));
|
||||
|
||||
|
||||
|
||||
/* Transmit Descriptor bit definitions */
|
||||
#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
|
||||
#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
|
||||
|
||||
|
||||
#define E1000_TXD_CMD_EOP 0x01 /* End of Packet */
|
||||
#define E1000_TXD_CMD_RS 0x08 /* Report Status */
|
||||
|
||||
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
|
||||
#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
|
||||
#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
|
||||
#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
|
||||
#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
|
||||
|
||||
|
||||
/* Receive Descriptor */
|
||||
struct E1000RxDesc {
|
||||
uint64_t buffer_addr;
|
||||
uint16_t length; /* Data buffer length */
|
||||
uint16_t chksum; /* Check Sum */
|
||||
uint8_t status;
|
||||
uint8_t err;
|
||||
uint16_t special;
|
||||
};
|
||||
|
||||
/* Transmit Descriptor bit definitions */
|
||||
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
|
||||
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
|
||||
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
|
||||
|
||||
|
||||
|
||||
int e1000_transmit(void *addr, size_t len);
|
||||
|
||||
|
||||
#endif // SOL >= 6
|
||||
|
||||
|
||||
131
lab/lab6.si4project/Backup/e1000(5347).h
Normal file
131
lab/lab6.si4project/Backup/e1000(5347).h
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef JOS_KERN_E1000_H
|
||||
#define JOS_KERN_E1000_H
|
||||
|
||||
#include "kern/pci.h"
|
||||
|
||||
#define E1000_VENDER_ID_82540EM 0x8086
|
||||
#define E1000_DEV_ID_82540EM 0x100E
|
||||
|
||||
#define TXDESCS 32
|
||||
#define TX_PKT_SIZE 1518
|
||||
|
||||
#define E1000_STATUS 0x00008 /* Device Status - RO */
|
||||
#define E1000_TCTL 0x00400 /* TX Control - RW */
|
||||
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
|
||||
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
|
||||
#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
|
||||
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
|
||||
#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
|
||||
#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
|
||||
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
|
||||
#define E1000_TXD_CMD_EOP 0x00000001 /* End of Packet */
|
||||
#define E1000_TXD_CMD_RS 0x00000008 /* Report Status */
|
||||
|
||||
|
||||
#define RXDESCS 128
|
||||
#define RX_PKT_SIZE 1518
|
||||
#define E1000_RCTL 0x00100
|
||||
#define E1000_RCTL_EN 0x00000002 /* enable */
|
||||
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
|
||||
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
|
||||
#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
|
||||
#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
|
||||
#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
|
||||
#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
|
||||
#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
|
||||
#define E1000_RA 0x05400 /* Receive Address - RW Array */
|
||||
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
|
||||
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
|
||||
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
|
||||
|
||||
enum {
|
||||
E_TRANSMIT_RETRY = 1,
|
||||
E_RECEIVE_RETRY,
|
||||
};
|
||||
|
||||
|
||||
/*transmit descriptor related*/
|
||||
struct e1000_tx_desc
|
||||
{
|
||||
uint64_t addr;
|
||||
uint16_t length;
|
||||
uint8_t cso;
|
||||
uint8_t cmd;
|
||||
uint8_t status;
|
||||
uint8_t css;
|
||||
uint16_t special;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct e1000_tctl {
|
||||
uint32_t rsv1: 1;
|
||||
uint32_t en: 1;
|
||||
uint32_t rsv2: 1;
|
||||
uint32_t psp: 1;
|
||||
uint32_t ct: 8;
|
||||
uint32_t cold: 10;
|
||||
uint32_t swxoff: 1;
|
||||
uint32_t rsv3: 1;
|
||||
uint32_t rtlc: 1;
|
||||
uint32_t nrtu: 1;
|
||||
uint32_t rsv4: 6;
|
||||
};
|
||||
|
||||
struct e1000_tipg {
|
||||
uint32_t ipgt: 10;
|
||||
uint32_t ipgr1: 10;
|
||||
uint32_t ipgr2: 10;
|
||||
uint32_t rsv: 2;
|
||||
};
|
||||
|
||||
struct e1000_tdt {
|
||||
uint16_t tdt;
|
||||
uint16_t rsv;
|
||||
};
|
||||
|
||||
struct e1000_tdlen {
|
||||
uint32_t zero: 7;
|
||||
uint32_t len: 13;
|
||||
uint32_t rsv: 12;
|
||||
};
|
||||
|
||||
struct e1000_tdh {
|
||||
uint16_t tdh;
|
||||
uint16_t rsv;
|
||||
};
|
||||
|
||||
|
||||
/*receive descriptor related*/
|
||||
struct e1000_rx_desc {
|
||||
uint64_t addr;
|
||||
uint16_t length;
|
||||
uint16_t chksum;
|
||||
uint8_t status;
|
||||
uint8_t errors;
|
||||
uint16_t special;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct e1000_rdlen {
|
||||
unsigned zero: 7;
|
||||
unsigned len: 13;
|
||||
unsigned rsv: 12;
|
||||
};
|
||||
|
||||
struct e1000_rdh {
|
||||
uint16_t rdh;
|
||||
uint16_t rsv;
|
||||
};
|
||||
|
||||
struct e1000_rdt {
|
||||
uint16_t rdt;
|
||||
uint16_t rsv;
|
||||
};
|
||||
|
||||
|
||||
int e1000_attachfn(struct pci_func *pcif);
|
||||
static void e1000_transmit_init();
|
||||
int e1000_transmit(void *data, size_t len);
|
||||
|
||||
static void e1000_receive_init();
|
||||
int e1000_receive(void *addr, size_t *len);
|
||||
|
||||
#endif // JOS_KERN_E1000_H
|
||||
126
lab/lab6.si4project/Backup/e1000(5657).c
Normal file
126
lab/lab6.si4project/Backup/e1000(5657).c
Normal file
@@ -0,0 +1,126 @@
|
||||
#include <kern/e1000.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <kern/pci.h>
|
||||
#include <kern/pcireg.h>
|
||||
#include <inc/string.h>
|
||||
|
||||
|
||||
// LAB 6: Your driver code here
|
||||
#define E1000_LOCATE(offset) (offset >> 2)
|
||||
volatile uint32_t *e1000;
|
||||
|
||||
uint32_t E1000_MAC[6] = {0x52, 0x54, 0x00, 0x12, 0x34, 0x56};
|
||||
|
||||
/* 为描述符列表分配静态内存 */
|
||||
struct E1000TxDesc tx_desc_list[TX_DESC_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
char tx_pbuf[TX_DESC_SIZE][TX_PACKET_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
|
||||
struct E1000RxDesc rx_desc_list[RX_DESC_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
char rx_pbuf[RX_DESC_SIZE][RX_PACKET_SIZE] __attribute__((aligned (PGSIZE))) ;
|
||||
|
||||
void
|
||||
e1000_transmit_init()
|
||||
{
|
||||
size_t i;
|
||||
memset(tx_desc_list, 0 , sizeof(struct E1000TxDesc) * TX_DESC_SIZE);
|
||||
for (i = 0; i < TX_DESC_SIZE; i++) {
|
||||
tx_desc_list[i].buffer_addr = PADDR(tx_pbuf[i]);
|
||||
tx_desc_list[i].status = E1000_TXD_STAT_DD;
|
||||
tx_desc_list[i].cmd = E1000_TXD_CMD_RS | E1000_TXD_CMD_EOP;
|
||||
|
||||
}
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDBAL)] = PADDR(tx_desc_list);
|
||||
e1000[E1000_LOCATE(E1000_TDBAH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDLEN)] = sizeof(struct E1000TxDesc) * TX_DESC_SIZE;
|
||||
// ensure that TDH and TDT are 0 index not offset
|
||||
e1000[E1000_LOCATE(E1000_TDH)] = 0;
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = 0;
|
||||
|
||||
// Initialize the Transmit Control Register (TCTL)
|
||||
e1000[E1000_LOCATE(E1000_TCTL)] = E1000_TCTL_EN |
|
||||
E1000_TCTL_PSP |
|
||||
(E1000_TCTL_CT & (0x10 << 4)) |
|
||||
(E1000_TCTL_COLD & (0x40 << 12));
|
||||
|
||||
// 10 8 6
|
||||
// 10 8 12
|
||||
e1000[E1000_LOCATE(E1000_TIPG)] = 10 | (8 << 10) | (12 << 20);
|
||||
}
|
||||
|
||||
int
|
||||
e1000_transmit(void *addr, size_t len)
|
||||
{
|
||||
|
||||
size_t tdt = e1000[E1000_LOCATE(E1000_TDT)];
|
||||
struct E1000TxDesc *tail_desc = &tx_desc_list[tdt];
|
||||
|
||||
|
||||
if ( !(tail_desc->status & E1000_TXD_STAT_DD )) {
|
||||
// Status is not DD
|
||||
return -1;
|
||||
}
|
||||
memmove(tx_pbuf[tdt], addr, len);
|
||||
|
||||
tail_desc->length = (uint16_t )len;
|
||||
// clear DD
|
||||
tail_desc->status &= (~E1000_TXD_STAT_DD);
|
||||
|
||||
e1000[E1000_LOCATE(E1000_TDT)] = (tdt+1) % TX_DESC_SIZE;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void e1000_set_mac_addr(uint32_t mac[])
|
||||
{
|
||||
uint32_t low = 0, high = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
low |= mac[i] << (8 * i);
|
||||
}
|
||||
|
||||
for (i = 4; i < 6; i++) {
|
||||
high |= mac[i] << (8 * i);
|
||||
}
|
||||
|
||||
e1000[E1000_LOCATE(E1000_RA)] = low;
|
||||
e1000[E1000_LOCATE(E1000_RA) + 1] = high | E1000_RAH_AV;
|
||||
}
|
||||
|
||||
void e1000_receive_init()
|
||||
{
|
||||
size_t i;
|
||||
memset(rx_desc_list, 0 , sizeof(struct E1000RxDesc) * RX_DESC_SIZE);
|
||||
for (i = 0; i < RX_DESC_SIZE; i++) {
|
||||
rx_desc_list[i].buffer_addr = PADDR(rx_pbuf[i]);
|
||||
}
|
||||
|
||||
e1000[E1000_LOCATE(E1000_RDBAL)] = PADDR(rx_desc_list);
|
||||
e1000[E1000_LOCATE(E1000_RDBAH)] = 0;
|
||||
|
||||
e1000[E1000_LOCATE(E1000_RDLEN)] = sizeof(struct E1000RxDesc) * RX_DESC_SIZE;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
pci_e1000_attach(struct pci_func * pcif)
|
||||
{
|
||||
int r;
|
||||
// 使能E1000,分配 MMIO等
|
||||
pci_func_enable(pcif);
|
||||
// 映射,并保存其虚拟地址,方便访问。
|
||||
e1000 = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]);
|
||||
e1000_transmit_init();
|
||||
|
||||
cprintf("device status:[%08x]\n", e1000[E1000_LOCATE(E1000_DEVICE_STATUS)]);
|
||||
/*
|
||||
char mes[40] = "e1000 transmit :HELLO";
|
||||
for (size_t i = 0; i < 10 ; i++) {
|
||||
e1000_transmit(mes, strlen(mes));
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
162
lab/lab6.si4project/Backup/e1000(5817).c
Normal file
162
lab/lab6.si4project/Backup/e1000(5817).c
Normal file
@@ -0,0 +1,162 @@
|
||||
#include <kern/e1000.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <inc/string.h>
|
||||
|
||||
// LAB 6: Your driver code here
|
||||
volatile void *bar_va;
|
||||
#define E1000REG(offset) (void *)(bar_va + offset)
|
||||
|
||||
struct e1000_tdh *tdh;
|
||||
struct e1000_tdt *tdt;
|
||||
struct e1000_tx_desc tx_desc_array[TXDESCS];
|
||||
char tx_buffer_array[TXDESCS][TX_PKT_SIZE];
|
||||
|
||||
struct e1000_rdh *rdh;
|
||||
struct e1000_rdt *rdt;
|
||||
struct e1000_rx_desc rx_desc_array[RXDESCS];
|
||||
char rx_buffer_array[RXDESCS][RX_PKT_SIZE];
|
||||
|
||||
uint32_t E1000_MAC[6] = {0x52, 0x54, 0x00, 0x12, 0x34, 0x56};
|
||||
int
|
||||
e1000_attachfn(struct pci_func *pcif)
|
||||
{
|
||||
pci_func_enable(pcif);
|
||||
cprintf("reg_base:%x, reg_size:%x\n", pcif->reg_base[0], pcif->reg_size[0]);
|
||||
|
||||
bar_va = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]);
|
||||
|
||||
uint32_t *status_reg = (uint32_t *)E1000REG(E1000_STATUS);
|
||||
assert(*status_reg == 0x80080783);
|
||||
|
||||
e1000_transmit_init();
|
||||
e1000_receive_init();
|
||||
|
||||
/*
|
||||
* transmit test
|
||||
*/
|
||||
// char *data = "transmit test";
|
||||
// e1000_transmit(data, 13);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
e1000_transmit_init()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < TXDESCS; i++) {
|
||||
tx_desc_array[i].addr = PADDR(tx_buffer_array[i]);
|
||||
tx_desc_array[i].cmd = 0;
|
||||
tx_desc_array[i].status |= E1000_TXD_STAT_DD;
|
||||
}
|
||||
|
||||
struct e1000_tdlen *tdlen = (struct e1000_tdlen *)E1000REG(E1000_TDLEN);
|
||||
tdlen->len = TXDESCS;
|
||||
|
||||
uint32_t *tdbal = (uint32_t *)E1000REG(E1000_TDBAL);
|
||||
*tdbal = PADDR(tx_desc_array);
|
||||
|
||||
uint32_t *tdbah = (uint32_t *)E1000REG(E1000_TDBAH);
|
||||
*tdbah = 0;
|
||||
|
||||
tdh = (struct e1000_tdh *)E1000REG(E1000_TDH);
|
||||
tdh->tdh = 0;
|
||||
|
||||
tdt = (struct e1000_tdt *)E1000REG(E1000_TDT);
|
||||
tdt->tdt = 0;
|
||||
|
||||
struct e1000_tctl *tctl = (struct e1000_tctl *)E1000REG(E1000_TCTL);
|
||||
tctl->en = 1;
|
||||
tctl->psp = 1;
|
||||
tctl->ct = 0x10;
|
||||
tctl->cold = 0x40;
|
||||
|
||||
struct e1000_tipg *tipg = (struct e1000_tipg *)E1000REG(E1000_TIPG);
|
||||
tipg->ipgt = 10;
|
||||
tipg->ipgr1 = 4;
|
||||
tipg->ipgr2 = 6;
|
||||
}
|
||||
|
||||
int
|
||||
e1000_transmit(void *data, size_t len)
|
||||
{
|
||||
uint32_t current = tdt->tdt;
|
||||
if(!(tx_desc_array[current].status & E1000_TXD_STAT_DD)) {
|
||||
return -E_TRANSMIT_RETRY;
|
||||
}
|
||||
tx_desc_array[current].length = len;
|
||||
tx_desc_array[current].status &= ~E1000_TXD_STAT_DD;
|
||||
tx_desc_array[current].cmd |= (E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS);
|
||||
memcpy(tx_buffer_array[current], data, len);
|
||||
uint32_t next = (current + 1) % TXDESCS;
|
||||
tdt->tdt = next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
get_ra_address(uint32_t mac[], uint32_t *ral, uint32_t *rah)
|
||||
{
|
||||
uint32_t low = 0, high = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
low |= mac[i] << (8 * i);
|
||||
}
|
||||
|
||||
for (i = 4; i < 6; i++) {
|
||||
high |= mac[i] << (8 * i);
|
||||
}
|
||||
|
||||
*ral = low;
|
||||
*rah = high | E1000_RAH_AV;
|
||||
}
|
||||
|
||||
static void
|
||||
e1000_receive_init()
|
||||
{
|
||||
uint32_t *rdbal = (uint32_t *)E1000REG(E1000_RDBAL);
|
||||
uint32_t *rdbah = (uint32_t *)E1000REG(E1000_RDBAH);
|
||||
*rdbal = PADDR(rx_desc_array);
|
||||
*rdbah = 0;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < RXDESCS; i++) {
|
||||
rx_desc_array[i].addr = PADDR(rx_buffer_array[i]);
|
||||
}
|
||||
|
||||
struct e1000_rdlen *rdlen = (struct e1000_rdlen *)E1000REG(E1000_RDLEN);
|
||||
rdlen->len = RXDESCS;
|
||||
|
||||
rdh = (struct e1000_rdh *)E1000REG(E1000_RDH);
|
||||
rdt = (struct e1000_rdt *)E1000REG(E1000_RDT);
|
||||
rdh->rdh = 0;
|
||||
rdt->rdt = RXDESCS-1;
|
||||
|
||||
uint32_t *rctl = (uint32_t *)E1000REG(E1000_RCTL);
|
||||
*rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SECRC;
|
||||
|
||||
uint32_t *ra = (uint32_t *)E1000REG(E1000_RA);
|
||||
uint32_t ral, rah;
|
||||
get_ra_address(E1000_MAC, &ral, &rah);
|
||||
ra[0] = ral;
|
||||
ra[1] = rah;
|
||||
}
|
||||
|
||||
int
|
||||
e1000_receive(void *addr, size_t *len)
|
||||
{
|
||||
static int32_t next = 0;
|
||||
if(!(rx_desc_array[next].status & E1000_RXD_STAT_DD)) {
|
||||
return -E_RECEIVE_RETRY;
|
||||
}
|
||||
if(rx_desc_array[next].errors) {
|
||||
cprintf("receive errors\n");
|
||||
return -E_RECEIVE_RETRY;
|
||||
}
|
||||
*len = rx_desc_array[next].length;
|
||||
memcpy(addr, rx_buffer_array[next], *len);
|
||||
|
||||
rdt->rdt = (rdt->rdt + 1) % RXDESCS;
|
||||
next = (next + 1) % RXDESCS;
|
||||
return 0;
|
||||
}
|
||||
162
lab/lab6.si4project/Backup/e1000(6672).c
Normal file
162
lab/lab6.si4project/Backup/e1000(6672).c
Normal file
@@ -0,0 +1,162 @@
|
||||
#include <kern/e1000.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <inc/string.h>
|
||||
|
||||
// LAB 6: Your driver code here
|
||||
volatile void *bar_va;
|
||||
#define E1000REG(offset) (void *)(bar_va + offset)
|
||||
|
||||
struct e1000_tdh *tdh;
|
||||
struct e1000_tdt *tdt;
|
||||
struct e1000_tx_desc tx_desc_array[TXDESCS];
|
||||
char tx_buffer_array[TXDESCS][TX_PKT_SIZE];
|
||||
|
||||
struct e1000_rdh *rdh;
|
||||
struct e1000_rdt *rdt;
|
||||
struct e1000_rx_desc rx_desc_array[RXDESCS];
|
||||
char rx_buffer_array[RXDESCS][RX_PKT_SIZE];
|
||||
|
||||
uint32_t E1000_MAC[6] = {0x52, 0x54, 0x00, 0x12, 0x34, 0x56};
|
||||
int
|
||||
e1000_attachfn(struct pci_func *pcif)
|
||||
{
|
||||
pci_func_enable(pcif);
|
||||
cprintf("reg_base:%x, reg_size:%x\n", pcif->reg_base[0], pcif->reg_size[0]);
|
||||
|
||||
bar_va = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]);
|
||||
|
||||
uint32_t *status_reg = (uint32_t *)E1000REG(E1000_STATUS);
|
||||
assert(*status_reg == 0x80080783);
|
||||
|
||||
e1000_transmit_init();
|
||||
e1000_receive_init();
|
||||
|
||||
/*
|
||||
* transmit test
|
||||
*/
|
||||
// char *data = "transmit test";
|
||||
// e1000_transmit(data, 13);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
e1000_transmit_init()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < TXDESCS; i++) {
|
||||
tx_desc_array[i].addr = PADDR(tx_buffer_array[i]);
|
||||
tx_desc_array[i].cmd = 0;
|
||||
tx_desc_array[i].status |= E1000_TXD_STAT_DD;
|
||||
}
|
||||
|
||||
struct e1000_tdlen *tdlen = (struct e1000_tdlen *)E1000REG(E1000_TDLEN);
|
||||
tdlen->len = TXDESCS;
|
||||
|
||||
uint32_t *tdbal = (uint32_t *)E1000REG(E1000_TDBAL);
|
||||
*tdbal = PADDR(tx_desc_array);
|
||||
|
||||
uint32_t *tdbah = (uint32_t *)E1000REG(E1000_TDBAH);
|
||||
*tdbah = 0;
|
||||
|
||||
tdh = (struct e1000_tdh *)E1000REG(E1000_TDH);
|
||||
tdh->tdh = 0;
|
||||
|
||||
tdt = (struct e1000_tdt *)E1000REG(E1000_TDT);
|
||||
tdt->tdt = 0;
|
||||
|
||||
struct e1000_tctl *tctl = (struct e1000_tctl *)E1000REG(E1000_TCTL);
|
||||
tctl->en = 1;
|
||||
tctl->psp = 1;
|
||||
tctl->ct = 0x10;
|
||||
tctl->cold = 0x40;
|
||||
|
||||
struct e1000_tipg *tipg = (struct e1000_tipg *)E1000REG(E1000_TIPG);
|
||||
tipg->ipgt = 10;
|
||||
tipg->ipgr1 = 4;
|
||||
tipg->ipgr2 = 6;
|
||||
}
|
||||
|
||||
int
|
||||
e1000_transmit(void *data, size_t len)
|
||||
{
|
||||
uint32_t current = tdt->tdt;
|
||||
if(!(tx_desc_array[current].status & E1000_TXD_STAT_DD)) {
|
||||
return -E_TRANSMIT_RETRY;
|
||||
}
|
||||
tx_desc_array[current].length = len;
|
||||
tx_desc_array[current].status &= ~E1000_TXD_STAT_DD;
|
||||
tx_desc_array[current].cmd |= (E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS);
|
||||
memcpy(tx_buffer_array[current], data, len);
|
||||
uint32_t next = (current + 1) % TXDESCS;
|
||||
tdt->tdt = next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
get_ra_address(uint32_t mac[], uint32_t *ral, uint32_t *rah)
|
||||
{
|
||||
uint32_t low = 0, high = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
low |= mac[i] << (8 * i);
|
||||
}
|
||||
|
||||
for (i = 4; i < 6; i++) {
|
||||
high |= mac[i] << (8 * i);
|
||||
}
|
||||
|
||||
*ral = low;
|
||||
*rah = high | E1000_RAH_AV;
|
||||
}
|
||||
|
||||
static void
|
||||
e1000_receive_init()
|
||||
{
|
||||
uint32_t *rdbal = (uint32_t *)E1000REG(E1000_RDBAL);
|
||||
uint32_t *rdbah = (uint32_t *)E1000REG(E1000_RDBAH);
|
||||
*rdbal = PADDR(rx_desc_array);
|
||||
*rdbah = 0;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < RXDESCS; i++) {
|
||||
rx_desc_array[i].addr = PADDR(rx_buffer_array[i]);
|
||||
}
|
||||
|
||||
struct e1000_rdlen *rdlen = (struct e1000_rdlen *)E1000REG(E1000_RDLEN);
|
||||
rdlen->len = RXDESCS;
|
||||
|
||||
rdh = (struct e1000_rdh *)E1000REG(E1000_RDH);
|
||||
rdt = (struct e1000_rdt *)E1000REG(E1000_RDT);
|
||||
rdh->rdh = 0;
|
||||
rdt->rdt = RXDESCS-1;
|
||||
|
||||
uint32_t *rctl = (uint32_t *)E1000REG(E1000_RCTL);
|
||||
*rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SECRC;
|
||||
|
||||
uint32_t *ra = (uint32_t *)E1000REG(E1000_RA);
|
||||
uint32_t ral, rah;
|
||||
get_ra_address(E1000_MAC, &ral, &rah);
|
||||
ra[0] = ral;
|
||||
ra[1] = rah;
|
||||
}
|
||||
|
||||
int
|
||||
e1000_receive(void *addr, size_t *len)
|
||||
{
|
||||
static int32_t next = 0;
|
||||
if(!(rx_desc_array[next].status & E1000_RXD_STAT_DD)) {
|
||||
return -E_RECEIVE_RETRY;
|
||||
}
|
||||
if(rx_desc_array[next].errors) {
|
||||
cprintf("receive errors\n");
|
||||
return -E_RECEIVE_RETRY;
|
||||
}
|
||||
*len = rx_desc_array[next].length;
|
||||
memcpy(addr, rx_buffer_array[next], *len);
|
||||
|
||||
rdt->rdt = (rdt->rdt + 1) % RXDESCS;
|
||||
next = (next + 1) % RXDESCS;
|
||||
return 0;
|
||||
}
|
||||
327
lab/lab6.si4project/Backup/httpd(174).c
Normal file
327
lab/lab6.si4project/Backup/httpd(174).c
Normal file
@@ -0,0 +1,327 @@
|
||||
#include <inc/lib.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/inet.h>
|
||||
|
||||
#define PORT 80
|
||||
#define VERSION "0.1"
|
||||
#define HTTP_VERSION "1.0"
|
||||
|
||||
#define E_BAD_REQ 1000
|
||||
|
||||
#define BUFFSIZE 512
|
||||
#define MAXPENDING 5 // Max connection requests
|
||||
|
||||
struct http_request {
|
||||
int sock;
|
||||
char *url;
|
||||
char *version;
|
||||
};
|
||||
|
||||
struct responce_header {
|
||||
int code;
|
||||
char *header;
|
||||
};
|
||||
|
||||
struct responce_header headers[] = {
|
||||
{ 200, "HTTP/" HTTP_VERSION " 200 OK\r\n"
|
||||
"Server: jhttpd/" VERSION "\r\n"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
struct error_messages {
|
||||
int code;
|
||||
char *msg;
|
||||
};
|
||||
|
||||
struct error_messages errors[] = {
|
||||
{400, "Bad Request"},
|
||||
{404, "Not Found"},
|
||||
};
|
||||
|
||||
static void
|
||||
die(char *m)
|
||||
{
|
||||
cprintf("%s\n", m);
|
||||
exit();
|
||||
}
|
||||
|
||||
static void
|
||||
req_free(struct http_request *req)
|
||||
{
|
||||
free(req->url);
|
||||
free(req->version);
|
||||
}
|
||||
|
||||
static int
|
||||
send_header(struct http_request *req, int code)
|
||||
{
|
||||
struct responce_header *h = headers;
|
||||
while (h->code != 0 && h->header!= 0) {
|
||||
if (h->code == code)
|
||||
break;
|
||||
h++;
|
||||
}
|
||||
|
||||
if (h->code == 0)
|
||||
return -1;
|
||||
|
||||
int len = strlen(h->header);
|
||||
if (write(req->sock, h->header, len) != len) {
|
||||
die("Failed to send bytes to client");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
send_data(struct http_request *req, int fd)
|
||||
{
|
||||
// LAB 6: Your code here.
|
||||
panic("send_data not implemented");
|
||||
}
|
||||
|
||||
static int
|
||||
send_size(struct http_request *req, off_t size)
|
||||
{
|
||||
char buf[64];
|
||||
int r;
|
||||
|
||||
r = snprintf(buf, 64, "Content-Length: %ld\r\n", (long)size);
|
||||
if (r > 63)
|
||||
panic("buffer too small!");
|
||||
|
||||
if (write(req->sock, buf, r) != r)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
mime_type(const char *file)
|
||||
{
|
||||
//TODO: for now only a single mime type
|
||||
return "text/html";
|
||||
}
|
||||
|
||||
static int
|
||||
send_content_type(struct http_request *req)
|
||||
{
|
||||
char buf[128];
|
||||
int r;
|
||||
const char *type;
|
||||
|
||||
type = mime_type(req->url);
|
||||
if (!type)
|
||||
return -1;
|
||||
|
||||
r = snprintf(buf, 128, "Content-Type: %s\r\n", type);
|
||||
if (r > 127)
|
||||
panic("buffer too small!");
|
||||
|
||||
if (write(req->sock, buf, r) != r)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
send_header_fin(struct http_request *req)
|
||||
{
|
||||
const char *fin = "\r\n";
|
||||
int fin_len = strlen(fin);
|
||||
|
||||
if (write(req->sock, fin, fin_len) != fin_len)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// given a request, this function creates a struct http_request
|
||||
static int
|
||||
http_request_parse(struct http_request *req, char *request)
|
||||
{
|
||||
const char *url;
|
||||
const char *version;
|
||||
int url_len, version_len;
|
||||
|
||||
if (!req)
|
||||
return -1;
|
||||
|
||||
if (strncmp(request, "GET ", 4) != 0)
|
||||
return -E_BAD_REQ;
|
||||
|
||||
// skip GET
|
||||
request += 4;
|
||||
|
||||
// get the url
|
||||
url = request;
|
||||
while (*request && *request != ' ')
|
||||
request++;
|
||||
url_len = request - url;
|
||||
|
||||
req->url = malloc(url_len + 1);
|
||||
memmove(req->url, url, url_len);
|
||||
req->url[url_len] = '\0';
|
||||
|
||||
// skip space
|
||||
request++;
|
||||
|
||||
version = request;
|
||||
while (*request && *request != '\n')
|
||||
request++;
|
||||
version_len = request - version;
|
||||
|
||||
req->version = malloc(version_len + 1);
|
||||
memmove(req->version, version, version_len);
|
||||
req->version[version_len] = '\0';
|
||||
|
||||
// no entity parsing
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
send_error(struct http_request *req, int code)
|
||||
{
|
||||
char buf[512];
|
||||
int r;
|
||||
|
||||
struct error_messages *e = errors;
|
||||
while (e->code != 0 && e->msg != 0) {
|
||||
if (e->code == code)
|
||||
break;
|
||||
e++;
|
||||
}
|
||||
|
||||
if (e->code == 0)
|
||||
return -1;
|
||||
|
||||
r = snprintf(buf, 512, "HTTP/" HTTP_VERSION" %d %s\r\n"
|
||||
"Server: jhttpd/" VERSION "\r\n"
|
||||
"Connection: close"
|
||||
"Content-type: text/html\r\n"
|
||||
"\r\n"
|
||||
"<html><body><p>%d - %s</p></body></html>\r\n",
|
||||
e->code, e->msg, e->code, e->msg);
|
||||
|
||||
if (write(req->sock, buf, r) != r)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
send_file(struct http_request *req)
|
||||
{
|
||||
int r;
|
||||
off_t file_size = -1;
|
||||
int fd;
|
||||
|
||||
// open the requested url for reading
|
||||
// if the file does not exist, send a 404 error using send_error
|
||||
// if the file is a directory, send a 404 error using send_error
|
||||
// set file_size to the size of the file
|
||||
|
||||
// LAB 6: Your code here.
|
||||
panic("send_file not implemented");
|
||||
|
||||
if ((r = send_header(req, 200)) < 0)
|
||||
goto end;
|
||||
|
||||
if ((r = send_size(req, file_size)) < 0)
|
||||
goto end;
|
||||
|
||||
if ((r = send_content_type(req)) < 0)
|
||||
goto end;
|
||||
|
||||
if ((r = send_header_fin(req)) < 0)
|
||||
goto end;
|
||||
|
||||
r = send_data(req, fd);
|
||||
|
||||
end:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_client(int sock)
|
||||
{
|
||||
struct http_request con_d;
|
||||
int r;
|
||||
char buffer[BUFFSIZE];
|
||||
int received = -1;
|
||||
struct http_request *req = &con_d;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Receive message
|
||||
if ((received = read(sock, buffer, BUFFSIZE)) < 0)
|
||||
panic("failed to read");
|
||||
|
||||
memset(req, 0, sizeof(*req));
|
||||
|
||||
req->sock = sock;
|
||||
|
||||
r = http_request_parse(req, buffer);
|
||||
if (r == -E_BAD_REQ)
|
||||
send_error(req, 400);
|
||||
else if (r < 0)
|
||||
panic("parse failed");
|
||||
else
|
||||
send_file(req);
|
||||
|
||||
req_free(req);
|
||||
|
||||
// no keep alive
|
||||
break;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void
|
||||
umain(int argc, char **argv)
|
||||
{
|
||||
int serversock, clientsock;
|
||||
struct sockaddr_in server, client;
|
||||
|
||||
binaryname = "jhttpd";
|
||||
|
||||
// Create the TCP socket
|
||||
if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
||||
die("Failed to create socket");
|
||||
|
||||
// Construct the server sockaddr_in structure
|
||||
memset(&server, 0, sizeof(server)); // Clear struct
|
||||
server.sin_family = AF_INET; // Internet/IP
|
||||
server.sin_addr.s_addr = htonl(INADDR_ANY); // IP address
|
||||
server.sin_port = htons(PORT); // server port
|
||||
|
||||
// Bind the server socket
|
||||
if (bind(serversock, (struct sockaddr *) &server,
|
||||
sizeof(server)) < 0)
|
||||
{
|
||||
die("Failed to bind the server socket");
|
||||
}
|
||||
|
||||
// Listen on the server socket
|
||||
if (listen(serversock, MAXPENDING) < 0)
|
||||
die("Failed to listen on server socket");
|
||||
|
||||
cprintf("Waiting for http connections...\n");
|
||||
|
||||
while (1) {
|
||||
unsigned int clientlen = sizeof(client);
|
||||
// Wait for client connection
|
||||
if ((clientsock = accept(serversock,
|
||||
(struct sockaddr *) &client,
|
||||
&clientlen)) < 0)
|
||||
{
|
||||
die("Failed to accept client connection");
|
||||
}
|
||||
handle_client(clientsock);
|
||||
}
|
||||
|
||||
close(serversock);
|
||||
}
|
||||
65
lab/lab6.si4project/Backup/input(2647).c
Normal file
65
lab/lab6.si4project/Backup/input(2647).c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "ns.h"
|
||||
#include <kern/e1000.h>
|
||||
|
||||
|
||||
extern union Nsipc nsipcbuf;
|
||||
|
||||
|
||||
void
|
||||
sleep(int msec)
|
||||
{
|
||||
unsigned now = sys_time_msec();
|
||||
unsigned end = now + msec;
|
||||
|
||||
if ((int)now < 0 && (int)now > -MAXERROR)
|
||||
panic("sys_time_msec: %e", (int)now);
|
||||
if (end < now)
|
||||
panic("sleep: wrap");
|
||||
|
||||
while (sys_time_msec() < end)
|
||||
sys_yield();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
input(envid_t ns_envid)
|
||||
{
|
||||
binaryname = "ns_input";
|
||||
|
||||
// LAB 6: Your code here:
|
||||
// - read a packet from the device driver
|
||||
// - send it to the network server
|
||||
// Hint: When you IPC a page to the network server, it will be
|
||||
// reading from it for a while, so don't immediately receive
|
||||
// another packet in to the same physical page.
|
||||
/*
|
||||
size_t len;
|
||||
char rev_buf[RX_PACKET_SIZE];
|
||||
size_t i = 0;
|
||||
while(1) {
|
||||
// 阻塞式读
|
||||
while ( sys_pkt_try_receive(rev_buf, &len) < 0) {
|
||||
sys_yield();
|
||||
}
|
||||
memcpy(nsipcbuf.pkt.jp_data, rev_buf, len);
|
||||
nsipcbuf.pkt.jp_len = len;
|
||||
|
||||
ipc_send(ns_envid, NSREQ_INPUT, &nsipcbuf, PTE_P|PTE_U);
|
||||
sleep(50);
|
||||
}
|
||||
*/
|
||||
size_t len;
|
||||
char buf[RX_PKT_SIZE];
|
||||
while (1) {
|
||||
if (sys_pkt_recv(buf, &len) < 0) {
|
||||
continue;
|
||||
}
|
||||
memcpy(nsipcbuf.pkt.jp_data, buf, len);
|
||||
nsipcbuf.pkt.jp_len = len;
|
||||
ipc_send(ns_envid, NSREQ_INPUT, &nsipcbuf, PTE_P|PTE_U|PTE_W);
|
||||
sleep(50);
|
||||
}
|
||||
|
||||
}
|
||||
16
lab/lab6.si4project/Backup/input(7104).c
Normal file
16
lab/lab6.si4project/Backup/input(7104).c
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "ns.h"
|
||||
|
||||
extern union Nsipc nsipcbuf;
|
||||
|
||||
void
|
||||
input(envid_t ns_envid)
|
||||
{
|
||||
binaryname = "ns_input";
|
||||
|
||||
// LAB 6: Your code here:
|
||||
// - read a packet from the device driver
|
||||
// - send it to the network server
|
||||
// Hint: When you IPC a page to the network server, it will be
|
||||
// reading from it for a while, so don't immediately receive
|
||||
// another packet in to the same physical page.
|
||||
}
|
||||
152
lab/lab6.si4project/Backup/lib(1933).h
Normal file
152
lab/lab6.si4project/Backup/lib(1933).h
Normal file
@@ -0,0 +1,152 @@
|
||||
// Main public header file for our user-land support library,
|
||||
// whose code lives in the lib directory.
|
||||
// This library is roughly our OS's version of a standard C library,
|
||||
// and is intended to be linked into all user-mode applications
|
||||
// (NOT the kernel or boot loader).
|
||||
|
||||
#ifndef JOS_INC_LIB_H
|
||||
#define JOS_INC_LIB_H 1
|
||||
|
||||
#include <inc/types.h>
|
||||
#include <inc/stdio.h>
|
||||
#include <inc/stdarg.h>
|
||||
#include <inc/string.h>
|
||||
#include <inc/error.h>
|
||||
#include <inc/assert.h>
|
||||
#include <inc/env.h>
|
||||
#include <inc/memlayout.h>
|
||||
#include <inc/syscall.h>
|
||||
#include <inc/trap.h>
|
||||
#include <inc/fs.h>
|
||||
#include <inc/fd.h>
|
||||
#include <inc/args.h>
|
||||
#include <inc/malloc.h>
|
||||
#include <inc/ns.h>
|
||||
|
||||
#define USED(x) (void)(x)
|
||||
|
||||
// main user program
|
||||
void umain(int argc, char **argv);
|
||||
|
||||
// libmain.c or entry.S
|
||||
extern const char *binaryname;
|
||||
extern const volatile struct Env *thisenv;
|
||||
extern const volatile struct Env envs[NENV];
|
||||
extern const volatile struct PageInfo pages[];
|
||||
|
||||
// exit.c
|
||||
void exit(void);
|
||||
|
||||
// pgfault.c
|
||||
void set_pgfault_handler(void (*handler)(struct UTrapframe *utf));
|
||||
|
||||
// readline.c
|
||||
char* readline(const char *buf);
|
||||
|
||||
// syscall.c
|
||||
void sys_cputs(const char *string, size_t len);
|
||||
int sys_cgetc(void);
|
||||
envid_t sys_getenvid(void);
|
||||
int sys_env_destroy(envid_t);
|
||||
void sys_yield(void);
|
||||
static envid_t sys_exofork(void);
|
||||
int sys_env_set_status(envid_t env, int status);
|
||||
int sys_env_set_trapframe(envid_t env, struct Trapframe *tf);
|
||||
int sys_env_set_pgfault_upcall(envid_t env, void *upcall);
|
||||
int sys_page_alloc(envid_t env, void *pg, int perm);
|
||||
int sys_page_map(envid_t src_env, void *src_pg,
|
||||
envid_t dst_env, void *dst_pg, int perm);
|
||||
int sys_page_unmap(envid_t env, void *pg);
|
||||
int sys_ipc_try_send(envid_t to_env, uint32_t value, void *pg, int perm);
|
||||
int sys_ipc_recv(void *rcv_pg);
|
||||
unsigned int sys_time_msec(void);
|
||||
|
||||
// This must be inlined. Exercise for reader: why?
|
||||
static inline envid_t __attribute__((always_inline))
|
||||
sys_exofork(void)
|
||||
{
|
||||
envid_t ret;
|
||||
asm volatile("int %2"
|
||||
: "=a" (ret)
|
||||
: "a" (SYS_exofork), "i" (T_SYSCALL));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ipc.c
|
||||
void ipc_send(envid_t to_env, uint32_t value, void *pg, int perm);
|
||||
int32_t ipc_recv(envid_t *from_env_store, void *pg, int *perm_store);
|
||||
envid_t ipc_find_env(enum EnvType type);
|
||||
|
||||
// fork.c
|
||||
#define PTE_SHARE 0x400
|
||||
envid_t fork(void);
|
||||
envid_t sfork(void); // Challenge!
|
||||
|
||||
// fd.c
|
||||
int close(int fd);
|
||||
ssize_t read(int fd, void *buf, size_t nbytes);
|
||||
ssize_t write(int fd, const void *buf, size_t nbytes);
|
||||
int seek(int fd, off_t offset);
|
||||
void close_all(void);
|
||||
ssize_t readn(int fd, void *buf, size_t nbytes);
|
||||
int dup(int oldfd, int newfd);
|
||||
int fstat(int fd, struct Stat *statbuf);
|
||||
int stat(const char *path, struct Stat *statbuf);
|
||||
|
||||
// file.c
|
||||
int open(const char *path, int mode);
|
||||
int ftruncate(int fd, off_t size);
|
||||
int remove(const char *path);
|
||||
int sync(void);
|
||||
|
||||
// pageref.c
|
||||
int pageref(void *addr);
|
||||
|
||||
// sockets.c
|
||||
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int bind(int s, struct sockaddr *name, socklen_t namelen);
|
||||
int shutdown(int s, int how);
|
||||
int connect(int s, const struct sockaddr *name, socklen_t namelen);
|
||||
int listen(int s, int backlog);
|
||||
int socket(int domain, int type, int protocol);
|
||||
|
||||
// nsipc.c
|
||||
int nsipc_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int nsipc_bind(int s, struct sockaddr *name, socklen_t namelen);
|
||||
int nsipc_shutdown(int s, int how);
|
||||
int nsipc_close(int s);
|
||||
int nsipc_connect(int s, const struct sockaddr *name, socklen_t namelen);
|
||||
int nsipc_listen(int s, int backlog);
|
||||
int nsipc_recv(int s, void *mem, int len, unsigned int flags);
|
||||
int nsipc_send(int s, const void *buf, int size, unsigned int flags);
|
||||
int nsipc_socket(int domain, int type, int protocol);
|
||||
|
||||
// spawn.c
|
||||
envid_t spawn(const char *program, const char **argv);
|
||||
envid_t spawnl(const char *program, const char *arg0, ...);
|
||||
|
||||
// console.c
|
||||
void cputchar(int c);
|
||||
int getchar(void);
|
||||
int iscons(int fd);
|
||||
int opencons(void);
|
||||
|
||||
// pipe.c
|
||||
int pipe(int pipefds[2]);
|
||||
int pipeisclosed(int pipefd);
|
||||
|
||||
// wait.c
|
||||
void wait(envid_t env);
|
||||
|
||||
/* File open modes */
|
||||
#define O_RDONLY 0x0000 /* open for reading only */
|
||||
#define O_WRONLY 0x0001 /* open for writing only */
|
||||
#define O_RDWR 0x0002 /* open for reading and writing */
|
||||
#define O_ACCMODE 0x0003 /* mask for above modes */
|
||||
|
||||
#define O_CREAT 0x0100 /* create if nonexistent */
|
||||
#define O_TRUNC 0x0200 /* truncate to zero length */
|
||||
#define O_EXCL 0x0400 /* error if already exists */
|
||||
#define O_MKDIR 0x0800 /* create directory, not regular file */
|
||||
|
||||
#endif // !JOS_INC_LIB_H
|
||||
27
lab/lab6.si4project/Backup/output(6468).c
Normal file
27
lab/lab6.si4project/Backup/output(6468).c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "ns.h"
|
||||
|
||||
extern union Nsipc nsipcbuf;
|
||||
|
||||
void
|
||||
output(envid_t ns_envid)
|
||||
{
|
||||
binaryname = "ns_output";
|
||||
envid_t envid;
|
||||
int perm;
|
||||
int32_t req;
|
||||
// LAB 6: Your code here:
|
||||
// - read a packet from the network server
|
||||
while(1) {
|
||||
req = ipc_recv(&envid, (void *) &nsipcbuf, &perm);
|
||||
if (req != NSREQ_OUTPUT)
|
||||
continue;
|
||||
|
||||
struct jif_pkt *pkt = &(nsipcbuf.pkt);
|
||||
while (sys_pkt_try_send(pkt->jp_data, pkt->jp_len) < 0) {
|
||||
sys_yield();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
13
lab/lab6.si4project/Backup/output(770).c
Normal file
13
lab/lab6.si4project/Backup/output(770).c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "ns.h"
|
||||
|
||||
extern union Nsipc nsipcbuf;
|
||||
|
||||
void
|
||||
output(envid_t ns_envid)
|
||||
{
|
||||
binaryname = "ns_output";
|
||||
|
||||
// LAB 6: Your code here:
|
||||
// - read a packet from the network server
|
||||
// - send the packet to the device driver
|
||||
}
|
||||
262
lab/lab6.si4project/Backup/pci(874).c
Normal file
262
lab/lab6.si4project/Backup/pci(874).c
Normal file
@@ -0,0 +1,262 @@
|
||||
#include <inc/x86.h>
|
||||
#include <inc/assert.h>
|
||||
#include <inc/string.h>
|
||||
#include <kern/pci.h>
|
||||
#include <kern/pcireg.h>
|
||||
#include <kern/e1000.h>
|
||||
|
||||
// Flag to do "lspci" at bootup
|
||||
static int pci_show_devs = 1;
|
||||
static int pci_show_addrs = 0;
|
||||
|
||||
// PCI "configuration mechanism one"
|
||||
static uint32_t pci_conf1_addr_ioport = 0x0cf8;
|
||||
static uint32_t pci_conf1_data_ioport = 0x0cfc;
|
||||
|
||||
// Forward declarations
|
||||
static int pci_bridge_attach(struct pci_func *pcif);
|
||||
|
||||
int pci_e1000_attach(struct pci_func * pcif);
|
||||
|
||||
|
||||
// PCI driver table
|
||||
struct pci_driver {
|
||||
uint32_t key1, key2;
|
||||
int (*attachfn) (struct pci_func *pcif);
|
||||
};
|
||||
|
||||
// pci_attach_class matches the class and subclass of a PCI device
|
||||
struct pci_driver pci_attach_class[] = {
|
||||
{ PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI, &pci_bridge_attach },
|
||||
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
// pci_attach_vendor matches the vendor ID and device ID of a PCI device. key1
|
||||
// and key2 should be the vendor ID and device ID respectively
|
||||
struct pci_driver pci_attach_vendor[] = {
|
||||
{ PCI_E1000_VENDOR_ID, PCI_E1000_DEVICE_ID, &pci_e1000_attach},
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static void
|
||||
pci_conf1_set_addr(uint32_t bus,
|
||||
uint32_t dev,
|
||||
uint32_t func,
|
||||
uint32_t offset)
|
||||
{
|
||||
assert(bus < 256);
|
||||
assert(dev < 32);
|
||||
assert(func < 8);
|
||||
assert(offset < 256);
|
||||
assert((offset & 0x3) == 0);
|
||||
|
||||
uint32_t v = (1 << 31) | // config-space
|
||||
(bus << 16) | (dev << 11) | (func << 8) | (offset);
|
||||
outl(pci_conf1_addr_ioport, v);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
pci_conf_read(struct pci_func *f, uint32_t off)
|
||||
{
|
||||
pci_conf1_set_addr(f->bus->busno, f->dev, f->func, off);
|
||||
return inl(pci_conf1_data_ioport);
|
||||
}
|
||||
|
||||
static void
|
||||
pci_conf_write(struct pci_func *f, uint32_t off, uint32_t v)
|
||||
{
|
||||
pci_conf1_set_addr(f->bus->busno, f->dev, f->func, off);
|
||||
outl(pci_conf1_data_ioport, v);
|
||||
}
|
||||
|
||||
static int __attribute__((warn_unused_result))
|
||||
pci_attach_match(uint32_t key1, uint32_t key2,
|
||||
struct pci_driver *list, struct pci_func *pcif)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; list[i].attachfn; i++) {
|
||||
if (list[i].key1 == key1 && list[i].key2 == key2) {
|
||||
int r = list[i].attachfn(pcif);
|
||||
if (r > 0)
|
||||
return r;
|
||||
if (r < 0)
|
||||
cprintf("pci_attach_match: attaching "
|
||||
"%x.%x (%p): e\n",
|
||||
key1, key2, list[i].attachfn, r);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pci_attach(struct pci_func *f)
|
||||
{
|
||||
return
|
||||
pci_attach_match(PCI_CLASS(f->dev_class),
|
||||
PCI_SUBCLASS(f->dev_class),
|
||||
&pci_attach_class[0], f) ||
|
||||
pci_attach_match(PCI_VENDOR(f->dev_id),
|
||||
PCI_PRODUCT(f->dev_id),
|
||||
&pci_attach_vendor[0], f);
|
||||
}
|
||||
|
||||
static const char *pci_class[] =
|
||||
{
|
||||
[0x0] = "Unknown",
|
||||
[0x1] = "Storage controller",
|
||||
[0x2] = "Network controller",
|
||||
[0x3] = "Display controller",
|
||||
[0x4] = "Multimedia device",
|
||||
[0x5] = "Memory controller",
|
||||
[0x6] = "Bridge device",
|
||||
};
|
||||
|
||||
static void
|
||||
pci_print_func(struct pci_func *f)
|
||||
{
|
||||
const char *class = pci_class[0];
|
||||
if (PCI_CLASS(f->dev_class) < ARRAY_SIZE(pci_class))
|
||||
class = pci_class[PCI_CLASS(f->dev_class)];
|
||||
|
||||
cprintf("PCI: %02x:%02x.%d: %04x:%04x: class: %x.%x (%s) irq: %d\n",
|
||||
f->bus->busno, f->dev, f->func,
|
||||
PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id),
|
||||
PCI_CLASS(f->dev_class), PCI_SUBCLASS(f->dev_class), class,
|
||||
f->irq_line);
|
||||
}
|
||||
|
||||
static int
|
||||
pci_scan_bus(struct pci_bus *bus)
|
||||
{
|
||||
int totaldev = 0;
|
||||
struct pci_func df;
|
||||
memset(&df, 0, sizeof(df));
|
||||
df.bus = bus;
|
||||
|
||||
for (df.dev = 0; df.dev < 32; df.dev++) {
|
||||
uint32_t bhlc = pci_conf_read(&df, PCI_BHLC_REG);
|
||||
if (PCI_HDRTYPE_TYPE(bhlc) > 1) // Unsupported or no device
|
||||
continue;
|
||||
|
||||
totaldev++;
|
||||
|
||||
struct pci_func f = df;
|
||||
for (f.func = 0; f.func < (PCI_HDRTYPE_MULTIFN(bhlc) ? 8 : 1);
|
||||
f.func++) {
|
||||
struct pci_func af = f;
|
||||
|
||||
af.dev_id = pci_conf_read(&f, PCI_ID_REG);
|
||||
if (PCI_VENDOR(af.dev_id) == 0xffff)
|
||||
continue;
|
||||
|
||||
uint32_t intr = pci_conf_read(&af, PCI_INTERRUPT_REG);
|
||||
af.irq_line = PCI_INTERRUPT_LINE(intr);
|
||||
|
||||
af.dev_class = pci_conf_read(&af, PCI_CLASS_REG);
|
||||
if (pci_show_devs)
|
||||
pci_print_func(&af);
|
||||
pci_attach(&af);
|
||||
}
|
||||
}
|
||||
|
||||
return totaldev;
|
||||
}
|
||||
|
||||
static int
|
||||
pci_bridge_attach(struct pci_func *pcif)
|
||||
{
|
||||
uint32_t ioreg = pci_conf_read(pcif, PCI_BRIDGE_STATIO_REG);
|
||||
uint32_t busreg = pci_conf_read(pcif, PCI_BRIDGE_BUS_REG);
|
||||
|
||||
if (PCI_BRIDGE_IO_32BITS(ioreg)) {
|
||||
cprintf("PCI: %02x:%02x.%d: 32-bit bridge IO not supported.\n",
|
||||
pcif->bus->busno, pcif->dev, pcif->func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pci_bus nbus;
|
||||
memset(&nbus, 0, sizeof(nbus));
|
||||
nbus.parent_bridge = pcif;
|
||||
nbus.busno = (busreg >> PCI_BRIDGE_BUS_SECONDARY_SHIFT) & 0xff;
|
||||
|
||||
if (pci_show_devs)
|
||||
cprintf("PCI: %02x:%02x.%d: bridge to PCI bus %d--%d\n",
|
||||
pcif->bus->busno, pcif->dev, pcif->func,
|
||||
nbus.busno,
|
||||
(busreg >> PCI_BRIDGE_BUS_SUBORDINATE_SHIFT) & 0xff);
|
||||
|
||||
pci_scan_bus(&nbus);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// External PCI subsystem interface
|
||||
|
||||
void
|
||||
pci_func_enable(struct pci_func *f)
|
||||
{
|
||||
pci_conf_write(f, PCI_COMMAND_STATUS_REG,
|
||||
PCI_COMMAND_IO_ENABLE |
|
||||
PCI_COMMAND_MEM_ENABLE |
|
||||
PCI_COMMAND_MASTER_ENABLE);
|
||||
|
||||
uint32_t bar_width;
|
||||
uint32_t bar;
|
||||
for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
|
||||
bar += bar_width)
|
||||
{
|
||||
uint32_t oldv = pci_conf_read(f, bar);
|
||||
|
||||
bar_width = 4;
|
||||
pci_conf_write(f, bar, 0xffffffff);
|
||||
uint32_t rv = pci_conf_read(f, bar);
|
||||
|
||||
if (rv == 0)
|
||||
continue;
|
||||
|
||||
int regnum = PCI_MAPREG_NUM(bar);
|
||||
uint32_t base, size;
|
||||
if (PCI_MAPREG_TYPE(rv) == PCI_MAPREG_TYPE_MEM) {
|
||||
if (PCI_MAPREG_MEM_TYPE(rv) == PCI_MAPREG_MEM_TYPE_64BIT)
|
||||
bar_width = 8;
|
||||
|
||||
size = PCI_MAPREG_MEM_SIZE(rv);
|
||||
base = PCI_MAPREG_MEM_ADDR(oldv);
|
||||
if (pci_show_addrs)
|
||||
cprintf(" mem region %d: %d bytes at 0x%x\n",
|
||||
regnum, size, base);
|
||||
} else {
|
||||
size = PCI_MAPREG_IO_SIZE(rv);
|
||||
base = PCI_MAPREG_IO_ADDR(oldv);
|
||||
if (pci_show_addrs)
|
||||
cprintf(" io region %d: %d bytes at 0x%x\n",
|
||||
regnum, size, base);
|
||||
}
|
||||
|
||||
pci_conf_write(f, bar, oldv);
|
||||
f->reg_base[regnum] = base;
|
||||
f->reg_size[regnum] = size;
|
||||
|
||||
if (size && !base)
|
||||
cprintf("PCI device %02x:%02x.%d (%04x:%04x) "
|
||||
"may be misconfigured: "
|
||||
"region %d: base 0x%x, size %d\n",
|
||||
f->bus->busno, f->dev, f->func,
|
||||
PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id),
|
||||
regnum, base, size);
|
||||
}
|
||||
|
||||
cprintf("PCI function %02x:%02x.%d (%04x:%04x) enabled\n",
|
||||
f->bus->busno, f->dev, f->func,
|
||||
PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id));
|
||||
}
|
||||
|
||||
int
|
||||
pci_init(void)
|
||||
{
|
||||
static struct pci_bus root_bus;
|
||||
memset(&root_bus, 0, sizeof(root_bus));
|
||||
|
||||
return pci_scan_bus(&root_bus);
|
||||
}
|
||||
24
lab/lab6.si4project/Backup/syscall(2053).h
Normal file
24
lab/lab6.si4project/Backup/syscall(2053).h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef JOS_INC_SYSCALL_H
|
||||
#define JOS_INC_SYSCALL_H
|
||||
|
||||
/* system call numbers */
|
||||
enum {
|
||||
SYS_cputs = 0,
|
||||
SYS_cgetc,
|
||||
SYS_getenvid,
|
||||
SYS_env_destroy,
|
||||
SYS_page_alloc,
|
||||
SYS_page_map,
|
||||
SYS_page_unmap,
|
||||
SYS_exofork,
|
||||
SYS_env_set_status,
|
||||
SYS_env_set_trapframe,
|
||||
SYS_env_set_pgfault_upcall,
|
||||
SYS_yield,
|
||||
SYS_ipc_try_send,
|
||||
SYS_ipc_recv,
|
||||
SYS_time_msec,
|
||||
NSYSCALLS
|
||||
};
|
||||
|
||||
#endif /* !JOS_INC_SYSCALL_H */
|
||||
124
lab/lab6.si4project/Backup/syscall(3019).c
Normal file
124
lab/lab6.si4project/Backup/syscall(3019).c
Normal file
@@ -0,0 +1,124 @@
|
||||
// System call stubs.
|
||||
|
||||
#include <inc/syscall.h>
|
||||
#include <inc/lib.h>
|
||||
|
||||
static inline int32_t
|
||||
syscall(int num, int check, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
// Generic system call: pass system call number in AX,
|
||||
// up to five parameters in DX, CX, BX, DI, SI.
|
||||
// Interrupt kernel with T_SYSCALL.
|
||||
//
|
||||
// The "volatile" tells the assembler not to optimize
|
||||
// this instruction away just because we don't use the
|
||||
// return value.
|
||||
//
|
||||
// The last clause tells the assembler that this can
|
||||
// potentially change the condition codes and arbitrary
|
||||
// memory locations.
|
||||
|
||||
asm volatile("int %1\n"
|
||||
: "=a" (ret)
|
||||
: "i" (T_SYSCALL),
|
||||
"a" (num),
|
||||
"d" (a1),
|
||||
"c" (a2),
|
||||
"b" (a3),
|
||||
"D" (a4),
|
||||
"S" (a5)
|
||||
: "cc", "memory");
|
||||
|
||||
if(check && ret > 0)
|
||||
panic("syscall %d returned %d (> 0)", num, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sys_cputs(const char *s, size_t len)
|
||||
{
|
||||
syscall(SYS_cputs, 0, (uint32_t)s, len, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_cgetc(void)
|
||||
{
|
||||
return syscall(SYS_cgetc, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_env_destroy(envid_t envid)
|
||||
{
|
||||
return syscall(SYS_env_destroy, 1, envid, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
envid_t
|
||||
sys_getenvid(void)
|
||||
{
|
||||
return syscall(SYS_getenvid, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
sys_yield(void)
|
||||
{
|
||||
syscall(SYS_yield, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_page_alloc(envid_t envid, void *va, int perm)
|
||||
{
|
||||
return syscall(SYS_page_alloc, 1, envid, (uint32_t) va, perm, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_page_map(envid_t srcenv, void *srcva, envid_t dstenv, void *dstva, int perm)
|
||||
{
|
||||
return syscall(SYS_page_map, 1, srcenv, (uint32_t) srcva, dstenv, (uint32_t) dstva, perm);
|
||||
}
|
||||
|
||||
int
|
||||
sys_page_unmap(envid_t envid, void *va)
|
||||
{
|
||||
return syscall(SYS_page_unmap, 1, envid, (uint32_t) va, 0, 0, 0);
|
||||
}
|
||||
|
||||
// sys_exofork is inlined in lib.h
|
||||
|
||||
int
|
||||
sys_env_set_status(envid_t envid, int status)
|
||||
{
|
||||
return syscall(SYS_env_set_status, 1, envid, status, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_env_set_trapframe(envid_t envid, struct Trapframe *tf)
|
||||
{
|
||||
return syscall(SYS_env_set_trapframe, 1, envid, (uint32_t) tf, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_env_set_pgfault_upcall(envid_t envid, void *upcall)
|
||||
{
|
||||
return syscall(SYS_env_set_pgfault_upcall, 1, envid, (uint32_t) upcall, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, int perm)
|
||||
{
|
||||
return syscall(SYS_ipc_try_send, 0, envid, value, (uint32_t) srcva, perm, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_ipc_recv(void *dstva)
|
||||
{
|
||||
return syscall(SYS_ipc_recv, 1, (uint32_t)dstva, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
sys_time_msec(void)
|
||||
{
|
||||
return (unsigned int) syscall(SYS_time_msec, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
498
lab/lab6.si4project/Backup/syscall(5120).c
Normal file
498
lab/lab6.si4project/Backup/syscall(5120).c
Normal file
@@ -0,0 +1,498 @@
|
||||
/* See COPYRIGHT for copyright information. */
|
||||
|
||||
#include <inc/x86.h>
|
||||
#include <inc/error.h>
|
||||
#include <inc/string.h>
|
||||
#include <inc/assert.h>
|
||||
|
||||
#include <kern/env.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <kern/trap.h>
|
||||
#include <kern/syscall.h>
|
||||
#include <kern/console.h>
|
||||
#include <kern/sched.h>
|
||||
#include <kern/time.h>
|
||||
|
||||
// Print a string to the system console.
|
||||
// The string is exactly 'len' characters long.
|
||||
// Destroys the environment on memory errors.
|
||||
static void
|
||||
sys_cputs(const char *s, size_t len)
|
||||
{
|
||||
// Check that the user has permission to read memory [s, s+len).
|
||||
// Destroy the environment if not.
|
||||
|
||||
// LAB 3: Your code here.
|
||||
user_mem_assert(curenv, (const void *) s, len, 0);
|
||||
// Print the string supplied by the user.
|
||||
cprintf("%.*s", len, s);
|
||||
}
|
||||
|
||||
// Read a character from the system console without blocking.
|
||||
// Returns the character, or 0 if there is no input waiting.
|
||||
static int
|
||||
sys_cgetc(void)
|
||||
{
|
||||
return cons_getc();
|
||||
}
|
||||
|
||||
// Returns the current environment's envid.
|
||||
static envid_t
|
||||
sys_getenvid(void)
|
||||
{
|
||||
return curenv->env_id;
|
||||
}
|
||||
|
||||
// Destroy a given environment (possibly the currently running environment).
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
static int
|
||||
sys_env_destroy(envid_t envid)
|
||||
{
|
||||
int r;
|
||||
struct Env *e;
|
||||
|
||||
if ((r = envid2env(envid, &e, 1)) < 0)
|
||||
return r;
|
||||
|
||||
|
||||
if (e == curenv)
|
||||
cprintf("[%08x] exiting gracefully\n", curenv->env_id);
|
||||
else
|
||||
cprintf("[%08x] destroying %08x\n", curenv->env_id, e->env_id);
|
||||
|
||||
env_destroy(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Deschedule current environment and pick a different one to run.
|
||||
static void
|
||||
sys_yield(void)
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
|
||||
// Allocate a new environment.
|
||||
// Returns envid of new environment, or < 0 on error. Errors are:
|
||||
// -E_NO_FREE_ENV if no free environment is available.
|
||||
// -E_NO_MEM on memory exhaustion.
|
||||
static envid_t
|
||||
sys_exofork(void)
|
||||
{
|
||||
// Create the new environment with env_alloc(), from kern/env.c.
|
||||
// It should be left as env_alloc created it, except that
|
||||
// status is set to ENV_NOT_RUNNABLE, and the register set is copied
|
||||
// from the current environment -- but tweaked so sys_exofork
|
||||
// will appear to return 0.
|
||||
// LAB 4: Your code here.
|
||||
struct Env *newenv;
|
||||
int32_t ret;
|
||||
if ((ret = env_alloc(&newenv, sys_getenvid())) < 0) {
|
||||
// 两个函数的返回值是一样的
|
||||
return ret;
|
||||
}
|
||||
newenv->env_status = ENV_NOT_RUNNABLE;
|
||||
newenv->env_tf = curenv->env_tf;
|
||||
// newenv的返回值为0, 实现子进程返回0值
|
||||
newenv->env_tf.tf_regs.reg_eax = 0;
|
||||
|
||||
// 返回值存放在eax中
|
||||
return newenv->env_id;
|
||||
|
||||
// panic("sys_exofork not implemented");
|
||||
}
|
||||
|
||||
// Set envid's env_status to status, which must be ENV_RUNNABLE
|
||||
// or ENV_NOT_RUNNABLE.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
// -E_INVAL if status is not a valid status for an environment.
|
||||
static int
|
||||
sys_env_set_status(envid_t envid, int status)
|
||||
{
|
||||
// Hint: Use the 'envid2env' function from kern/env.c to translate an
|
||||
// envid to a struct Env.
|
||||
// You should set envid2env's third argument to 1, which will
|
||||
// check whether the current environment has permission to set
|
||||
// envid's status.
|
||||
|
||||
// LAB 4: Your code here.
|
||||
struct Env *e;
|
||||
if (envid2env(envid, &e, 1)) return -E_BAD_ENV;
|
||||
|
||||
if (status != ENV_NOT_RUNNABLE && status != ENV_RUNNABLE)
|
||||
return -E_INVAL;
|
||||
|
||||
e->env_status = status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set envid's trap frame to 'tf'.
|
||||
// tf is modified to make sure that user environments always run at code
|
||||
// protection level 3 (CPL 3), interrupts enabled, and IOPL of 0.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
static int
|
||||
sys_env_set_trapframe(envid_t envid, struct Trapframe *tf)
|
||||
{
|
||||
// LAB 5: Your code here.
|
||||
// Remember to check whether the user has supplied us with a good
|
||||
// address!
|
||||
struct Env *env;
|
||||
int r;
|
||||
if ( (r = envid2env(envid, &env, 1)) < 0)
|
||||
return r;
|
||||
|
||||
// 什么时候会出现没有权限访问的问题?
|
||||
user_mem_assert(env, tf, sizeof(struct Trapframe), PTE_U);
|
||||
// 直接整个结构体也是可以赋值的
|
||||
|
||||
// tf->tf_cs |= (GD_UT | 0x3);
|
||||
tf->tf_eflags |= FL_IF;
|
||||
// 普通进程无I/O权限
|
||||
tf->tf_eflags &= ~FL_IOPL_MASK;
|
||||
|
||||
env->env_tf = *tf;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// Set the page fault upcall for 'envid' by modifying the corresponding struct
|
||||
// Env's 'env_pgfault_upcall' field. When 'envid' causes a page fault, the
|
||||
// kernel will push a fault record onto the exception stack, then branch to
|
||||
// 'func'.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
static int
|
||||
sys_env_set_pgfault_upcall(envid_t envid, void *func)
|
||||
{
|
||||
// LAB 4: Your code here.
|
||||
struct Env *e;
|
||||
if (envid2env(envid, &e, 1))
|
||||
return -E_BAD_ENV;
|
||||
// cprintf("set pgfault upcall\n");
|
||||
e->env_pgfault_upcall = func;
|
||||
return 0;
|
||||
// panic("sys_env_set_pgfault_upcall not implemented");
|
||||
}
|
||||
|
||||
// Allocate a page of memory and map it at 'va' with permission
|
||||
// 'perm' in the address space of 'envid'.
|
||||
// The page's contents are set to 0.
|
||||
// If a page is already mapped at 'va', that page is unmapped as a
|
||||
// side effect.
|
||||
//
|
||||
// perm -- PTE_U | PTE_P must be set, PTE_AVAIL | PTE_W may or may not be set,
|
||||
// but no other bits may be set. See PTE_SYSCALL in inc/mmu.h.
|
||||
//
|
||||
// Return 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
// -E_INVAL if va >= UTOP, or va is not page-aligned.
|
||||
// -E_INVAL if perm is inappropriate (see above).
|
||||
// -E_NO_MEM if there's no memory to allocate the new page,
|
||||
// or to allocate any necessary page tables.
|
||||
static int
|
||||
sys_page_alloc(envid_t envid, void *va, int perm)
|
||||
{
|
||||
// Hint: This function is a wrapper around page_alloc() and
|
||||
// page_insert() from kern/pmap.c.
|
||||
// Most of the new code you write should be to check the
|
||||
// parameters for correctness.
|
||||
// If page_insert() fails, remember to free the page you
|
||||
// allocated!
|
||||
|
||||
// LAB 4: Your code here.
|
||||
int ret = 0;
|
||||
struct Env *env;
|
||||
|
||||
if ((ret = envid2env(envid, &env, 1)) < 0)
|
||||
return -E_BAD_ENV;
|
||||
|
||||
if((uintptr_t)va >= UTOP || PGOFF(va))
|
||||
return -E_INVAL;
|
||||
if ((perm & PTE_U) == 0 || (perm & PTE_P) == 0)
|
||||
return -E_INVAL;
|
||||
if (perm & ~PTE_SYSCALL)
|
||||
return -E_INVAL;
|
||||
|
||||
struct PageInfo *pp = page_alloc(ALLOC_ZERO);
|
||||
if(!pp)
|
||||
return -E_NO_MEM;
|
||||
|
||||
if (page_insert(env->env_pgdir, pp, va, perm) < 0)
|
||||
return -E_NO_MEM;
|
||||
|
||||
return 0;
|
||||
// panic("sys_page_alloc not implemented");
|
||||
}
|
||||
|
||||
// Map the page of memory at 'srcva' in srcenvid's address space
|
||||
// at 'dstva' in dstenvid's address space with permission 'perm'.
|
||||
// Perm has the same restrictions as in sys_page_alloc, except
|
||||
// that it also must not grant write access to a read-only
|
||||
// page.
|
||||
//
|
||||
// Return 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if srcenvid and/or dstenvid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change one of them.
|
||||
// -E_INVAL if srcva >= UTOP or srcva is not page-aligned,
|
||||
// or dstva >= UTOP or dstva is not page-aligned.
|
||||
// -E_INVAL is srcva is not mapped in srcenvid's address space.
|
||||
// -E_INVAL if perm is inappropriate (see sys_page_alloc).
|
||||
// -E_INVAL if (perm & PTE_W), but srcva is read-only in srcenvid's
|
||||
// address space.
|
||||
// -E_NO_MEM if there's no memory to allocate any necessary page tables.
|
||||
static int
|
||||
sys_page_map(envid_t srcenvid, void *srcva,
|
||||
envid_t dstenvid, void *dstva, int perm)
|
||||
{
|
||||
// Hint: This function is a wrapper around page_lookup() and
|
||||
// page_insert() from kern/pmap.c.
|
||||
// Again, most of the new code you write should be to check the
|
||||
// parameters for correctness.
|
||||
// Use the third argument to page_lookup() to
|
||||
// check the current permissions on the page.
|
||||
|
||||
// LAB 4: Your code here.
|
||||
int ret = 0;
|
||||
struct Env *srcenv, *dstenv;
|
||||
struct PageInfo *srcpp, *dstpp;
|
||||
pte_t *pte;
|
||||
if ((envid2env(srcenvid, &srcenv, 1) < 0 )|| ( envid2env(dstenvid, &dstenv, 1) < 0))
|
||||
return -E_BAD_ENV;
|
||||
if ((uintptr_t)srcva >= UTOP || PGOFF(srcva) || (uintptr_t)dstva >= UTOP || PGOFF(dstva))
|
||||
return -E_INVAL;
|
||||
if ( (perm & PTE_U) == 0 || (perm & PTE_P) == 0 || (perm & ~PTE_SYSCALL))
|
||||
return -E_INVAL;
|
||||
if (!(srcpp = page_lookup(srcenv->env_pgdir, srcva, &pte)))
|
||||
return -E_INVAL;
|
||||
if ((perm & PTE_W) && ((*pte & PTE_W) == 0))
|
||||
return -E_INVAL;
|
||||
if (page_insert(dstenv->env_pgdir, srcpp, dstva, perm) < 0)
|
||||
return -E_NO_MEM;
|
||||
|
||||
return 0;
|
||||
// panic("sys_page_map not implemented");
|
||||
}
|
||||
|
||||
// Unmap the page of memory at 'va' in the address space of 'envid'.
|
||||
// If no page is mapped, the function silently succeeds.
|
||||
//
|
||||
// Return 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
// -E_INVAL if va >= UTOP, or va is not page-aligned.
|
||||
static int
|
||||
sys_page_unmap(envid_t envid, void *va)
|
||||
{
|
||||
// Hint: This function is a wrapper around page_remove().
|
||||
|
||||
// LAB 4: Your code here.
|
||||
int ret = 0;
|
||||
struct Env *env;
|
||||
|
||||
if ((ret = envid2env(envid, &env, 1)) < 0)
|
||||
return -E_BAD_ENV;
|
||||
if ((uintptr_t)va >= UTOP || PGOFF(va))
|
||||
return -E_INVAL;
|
||||
page_remove(env->env_pgdir, va);
|
||||
return 0;
|
||||
// panic("sys_page_unmap not implemented");
|
||||
}
|
||||
|
||||
// Try to send 'value' to the target env 'envid'.
|
||||
// If srcva < UTOP, then also send page currently mapped at 'srcva',
|
||||
// so that receiver gets a duplicate mapping of the same page.
|
||||
//
|
||||
// The send fails with a return value of -E_IPC_NOT_RECV if the
|
||||
// target is not blocked, waiting for an IPC.
|
||||
//
|
||||
// The send also can fail for the other reasons listed below.
|
||||
//
|
||||
// Otherwise, the send succeeds, and the target's ipc fields are
|
||||
// updated as follows:
|
||||
// env_ipc_recving is set to 0 to block future sends;
|
||||
// env_ipc_from is set to the sending envid;
|
||||
// env_ipc_value is set to the 'value' parameter;
|
||||
// env_ipc_perm is set to 'perm' if a page was transferred, 0 otherwise.
|
||||
// The target environment is marked runnable again, returning 0
|
||||
// from the paused sys_ipc_recv system call. (Hint: does the
|
||||
// sys_ipc_recv function ever actually return?)
|
||||
//
|
||||
// If the sender wants to send a page but the receiver isn't asking for one,
|
||||
// then no page mapping is transferred, but no error occurs.
|
||||
// The ipc only happens when no errors occur.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error.
|
||||
// Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist.
|
||||
// (No need to check permissions.)
|
||||
// -E_IPC_NOT_RECV if envid is not currently blocked in sys_ipc_recv,
|
||||
// or another environment managed to send first.
|
||||
// -E_INVAL if srcva < UTOP but srcva is not page-aligned.
|
||||
// -E_INVAL if srcva < UTOP and perm is inappropriate
|
||||
// (see sys_page_alloc).
|
||||
// -E_INVAL if srcva < UTOP but srcva is not mapped in the caller's
|
||||
// address space.
|
||||
// -E_INVAL if (perm & PTE_W), but srcva is read-only in the
|
||||
// current environment's address space.
|
||||
// -E_NO_MEM if there's not enough memory to map srcva in envid's
|
||||
// address space.
|
||||
|
||||
static int
|
||||
sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, unsigned perm)
|
||||
{
|
||||
// LAB 4: Your code here.
|
||||
struct Env *dstenv;
|
||||
pte_t *pte;
|
||||
struct PageInfo *pp;
|
||||
int r;
|
||||
if ( (r = envid2env( envid, &dstenv, 0)) < 0)
|
||||
return r;
|
||||
|
||||
// 不处于等待接收状态, 或有进程已经请求发送数据
|
||||
if ( (dstenv->env_ipc_recving != true) || dstenv->env_ipc_from != 0)
|
||||
return -E_IPC_NOT_RECV;
|
||||
|
||||
if ((uint32_t)srcva < UTOP) {
|
||||
if ( PGOFF(srcva))
|
||||
return -E_INVAL;
|
||||
if ( !(perm & PTE_P ) || !(perm & PTE_U) )
|
||||
return -E_INVAL;
|
||||
if (perm & (~ PTE_SYSCALL))
|
||||
return -E_INVAL;
|
||||
|
||||
|
||||
if ((pp = page_lookup(curenv->env_pgdir, srcva, &pte)) == NULL )
|
||||
return -E_INVAL;
|
||||
|
||||
|
||||
if ((perm & PTE_W) && !(*pte & PTE_W) )
|
||||
return -E_INVAL;
|
||||
|
||||
// 接收进程愿意接收一个页
|
||||
if (dstenv->env_ipc_dstva) {
|
||||
// 开始映射
|
||||
if( (r = page_insert(dstenv->env_pgdir, pp, dstenv->env_ipc_dstva, perm)) < 0)
|
||||
return r;
|
||||
dstenv->env_ipc_perm = perm;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
dstenv->env_ipc_from = curenv->env_id;
|
||||
dstenv->env_ipc_recving = false;
|
||||
dstenv->env_ipc_value = value;
|
||||
dstenv->env_status = ENV_RUNNABLE;
|
||||
// 返回值
|
||||
dstenv->env_tf.tf_regs.reg_eax = 0;
|
||||
return 0;
|
||||
|
||||
//panic("sys_ipc_try_send not implemented");
|
||||
}
|
||||
|
||||
|
||||
// Block until a value is ready. Record that you want to receive
|
||||
// using the env_ipc_recving and env_ipc_dstva fields of struct Env,
|
||||
// mark yourself not runnable, and then give up the CPU.
|
||||
//
|
||||
// If 'dstva' is < UTOP, then you are willing to receive a page of data.
|
||||
// 'dstva' is the virtual address at which the sent page should be mapped.
|
||||
//
|
||||
// This function only returns on error, but the system call will eventually
|
||||
// return 0 on success.
|
||||
// Return < 0 on error. Errors are:
|
||||
// -E_INVAL if dstva < UTOP but dstva is not page-aligned.
|
||||
static int
|
||||
sys_ipc_recv(void *dstva)
|
||||
{
|
||||
// LAB 4: Your code here.
|
||||
if ((uint32_t) dstva < UTOP ) {
|
||||
if (PGOFF(dstva))
|
||||
return -E_INVAL;
|
||||
|
||||
}
|
||||
// 大于小于都可以赋值为desva。
|
||||
curenv->env_ipc_dstva = dstva;
|
||||
curenv->env_status = ENV_NOT_RUNNABLE;
|
||||
curenv->env_ipc_recving = true;
|
||||
curenv->env_ipc_from = 0;
|
||||
sched_yield();
|
||||
// panic("sys_ipc_recv not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the current time.
|
||||
static int
|
||||
sys_time_msec(void)
|
||||
{
|
||||
// LAB 6: Your code here.
|
||||
return time_msec();
|
||||
// panic("sys_time_msec not implemented");
|
||||
}
|
||||
|
||||
// Dispatches to the correct kernel function, passing the arguments.
|
||||
int32_t
|
||||
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
|
||||
{
|
||||
// Call the function corresponding to the 'syscallno' parameter.
|
||||
// Return any appropriate return value.
|
||||
// LAB 3: Your code here.
|
||||
switch (syscallno) {
|
||||
case SYS_cputs:
|
||||
sys_cputs((const char*)a1, a2);
|
||||
break;
|
||||
case SYS_cgetc:
|
||||
return sys_cgetc();
|
||||
case SYS_getenvid:
|
||||
return sys_getenvid();
|
||||
case SYS_env_destroy:
|
||||
return sys_env_destroy(a1);
|
||||
case SYS_yield:
|
||||
sys_yield();
|
||||
break;
|
||||
case SYS_page_alloc:
|
||||
return sys_page_alloc((envid_t)a1, (void * )a2, (int )a3);
|
||||
case SYS_env_set_pgfault_upcall:
|
||||
return sys_env_set_pgfault_upcall((envid_t) a1, (void *) a2);
|
||||
case SYS_page_map:
|
||||
return sys_page_map((envid_t) a1, (void *) a2, (envid_t) a3, (void *) a4, (int) a5);
|
||||
|
||||
case SYS_page_unmap:
|
||||
return sys_page_unmap((envid_t) a1, (void *) a2);
|
||||
|
||||
case SYS_exofork:
|
||||
return sys_exofork();
|
||||
|
||||
case SYS_env_set_status:
|
||||
return sys_env_set_status((envid_t) a1, (int) a2);
|
||||
case SYS_ipc_recv:
|
||||
return sys_ipc_recv( (void *) a1);
|
||||
case SYS_ipc_try_send:
|
||||
return sys_ipc_try_send((envid_t) a1, (uint32_t) a2, (void *) a3, (int) a4);
|
||||
|
||||
case SYS_env_set_trapframe:
|
||||
return sys_env_set_trapframe((envid_t) a1, (struct Trapframe *) a2);
|
||||
case SYS_time_msec:
|
||||
return sys_time_msec();
|
||||
|
||||
case NSYSCALLS:
|
||||
return -E_INVAL;
|
||||
|
||||
default:
|
||||
return -E_INVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
139
lab/lab6.si4project/Backup/syscall(6702).c
Normal file
139
lab/lab6.si4project/Backup/syscall(6702).c
Normal file
@@ -0,0 +1,139 @@
|
||||
// System call stubs.
|
||||
|
||||
#include <inc/syscall.h>
|
||||
#include <inc/lib.h>
|
||||
|
||||
static inline int32_t
|
||||
syscall(int num, int check, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
// Generic system call: pass system call number in AX,
|
||||
// up to five parameters in DX, CX, BX, DI, SI.
|
||||
// Interrupt kernel with T_SYSCALL.
|
||||
//
|
||||
// The "volatile" tells the assembler not to optimize
|
||||
// this instruction away just because we don't use the
|
||||
// return value.
|
||||
//
|
||||
// The last clause tells the assembler that this can
|
||||
// potentially change the condition codes and arbitrary
|
||||
// memory locations.
|
||||
|
||||
asm volatile("int %1\n"
|
||||
: "=a" (ret)
|
||||
: "i" (T_SYSCALL),
|
||||
"a" (num),
|
||||
"d" (a1),
|
||||
"c" (a2),
|
||||
"b" (a3),
|
||||
"D" (a4),
|
||||
"S" (a5)
|
||||
: "cc", "memory");
|
||||
|
||||
if(check && ret > 0)
|
||||
panic("syscall %d returned %d (> 0)", num, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sys_cputs(const char *s, size_t len)
|
||||
{
|
||||
syscall(SYS_cputs, 0, (uint32_t)s, len, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_cgetc(void)
|
||||
{
|
||||
return syscall(SYS_cgetc, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_env_destroy(envid_t envid)
|
||||
{
|
||||
return syscall(SYS_env_destroy, 1, envid, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
envid_t
|
||||
sys_getenvid(void)
|
||||
{
|
||||
return syscall(SYS_getenvid, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
sys_yield(void)
|
||||
{
|
||||
syscall(SYS_yield, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_page_alloc(envid_t envid, void *va, int perm)
|
||||
{
|
||||
return syscall(SYS_page_alloc, 1, envid, (uint32_t) va, perm, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_page_map(envid_t srcenv, void *srcva, envid_t dstenv, void *dstva, int perm)
|
||||
{
|
||||
return syscall(SYS_page_map, 1, srcenv, (uint32_t) srcva, dstenv, (uint32_t) dstva, perm);
|
||||
}
|
||||
|
||||
int
|
||||
sys_page_unmap(envid_t envid, void *va)
|
||||
{
|
||||
return syscall(SYS_page_unmap, 1, envid, (uint32_t) va, 0, 0, 0);
|
||||
}
|
||||
|
||||
// sys_exofork is inlined in lib.h
|
||||
|
||||
int
|
||||
sys_env_set_status(envid_t envid, int status)
|
||||
{
|
||||
return syscall(SYS_env_set_status, 1, envid, status, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_env_set_trapframe(envid_t envid, struct Trapframe *tf)
|
||||
{
|
||||
return syscall(SYS_env_set_trapframe, 1, envid, (uint32_t) tf, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_env_set_pgfault_upcall(envid_t envid, void *upcall)
|
||||
{
|
||||
return syscall(SYS_env_set_pgfault_upcall, 1, envid, (uint32_t) upcall, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, int perm)
|
||||
{
|
||||
return syscall(SYS_ipc_try_send, 0, envid, value, (uint32_t) srcva, perm, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_ipc_recv(void *dstva)
|
||||
{
|
||||
return syscall(SYS_ipc_recv, 1, (uint32_t)dstva, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
sys_time_msec(void)
|
||||
{
|
||||
return (unsigned int) syscall(SYS_time_msec, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
sys_pkt_try_send(void *buf, size_t len)
|
||||
{
|
||||
return syscall(SYS_pkt_try_send, 1, (uint32_t)buf, (uint32_t)len, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_pkt_try_receive(void *rev_buf, size_t *len)
|
||||
{
|
||||
// return 0;
|
||||
return syscall(SYS_pkt_try_recv, 1, (uint32_t)rev_buf, (uint32_t)len, 0, 0, 0);
|
||||
}
|
||||
|
||||
517
lab/lab6.si4project/Backup/syscall(6909).c
Normal file
517
lab/lab6.si4project/Backup/syscall(6909).c
Normal file
@@ -0,0 +1,517 @@
|
||||
/* See COPYRIGHT for copyright information. */
|
||||
|
||||
#include <inc/x86.h>
|
||||
#include <inc/error.h>
|
||||
#include <inc/string.h>
|
||||
#include <inc/assert.h>
|
||||
|
||||
#include <kern/env.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <kern/trap.h>
|
||||
#include <kern/syscall.h>
|
||||
#include <kern/console.h>
|
||||
#include <kern/sched.h>
|
||||
#include <kern/time.h>
|
||||
#include <kern/e1000.h>
|
||||
|
||||
// Print a string to the system console.
|
||||
// The string is exactly 'len' characters long.
|
||||
// Destroys the environment on memory errors.
|
||||
static void
|
||||
sys_cputs(const char *s, size_t len)
|
||||
{
|
||||
// Check that the user has permission to read memory [s, s+len).
|
||||
// Destroy the environment if not.
|
||||
|
||||
// LAB 3: Your code here.
|
||||
user_mem_assert(curenv, (const void *) s, len, 0);
|
||||
// Print the string supplied by the user.
|
||||
cprintf("%.*s", len, s);
|
||||
}
|
||||
|
||||
// Read a character from the system console without blocking.
|
||||
// Returns the character, or 0 if there is no input waiting.
|
||||
static int
|
||||
sys_cgetc(void)
|
||||
{
|
||||
return cons_getc();
|
||||
}
|
||||
|
||||
// Returns the current environment's envid.
|
||||
static envid_t
|
||||
sys_getenvid(void)
|
||||
{
|
||||
return curenv->env_id;
|
||||
}
|
||||
|
||||
// Destroy a given environment (possibly the currently running environment).
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
static int
|
||||
sys_env_destroy(envid_t envid)
|
||||
{
|
||||
int r;
|
||||
struct Env *e;
|
||||
|
||||
if ((r = envid2env(envid, &e, 1)) < 0)
|
||||
return r;
|
||||
|
||||
|
||||
if (e == curenv)
|
||||
cprintf("[%08x] exiting gracefully\n", curenv->env_id);
|
||||
else
|
||||
cprintf("[%08x] destroying %08x\n", curenv->env_id, e->env_id);
|
||||
|
||||
env_destroy(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Deschedule current environment and pick a different one to run.
|
||||
static void
|
||||
sys_yield(void)
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
|
||||
// Allocate a new environment.
|
||||
// Returns envid of new environment, or < 0 on error. Errors are:
|
||||
// -E_NO_FREE_ENV if no free environment is available.
|
||||
// -E_NO_MEM on memory exhaustion.
|
||||
static envid_t
|
||||
sys_exofork(void)
|
||||
{
|
||||
// Create the new environment with env_alloc(), from kern/env.c.
|
||||
// It should be left as env_alloc created it, except that
|
||||
// status is set to ENV_NOT_RUNNABLE, and the register set is copied
|
||||
// from the current environment -- but tweaked so sys_exofork
|
||||
// will appear to return 0.
|
||||
// LAB 4: Your code here.
|
||||
struct Env *newenv;
|
||||
int32_t ret;
|
||||
if ((ret = env_alloc(&newenv, sys_getenvid())) < 0) {
|
||||
// 两个函数的返回值是一样的
|
||||
return ret;
|
||||
}
|
||||
newenv->env_status = ENV_NOT_RUNNABLE;
|
||||
newenv->env_tf = curenv->env_tf;
|
||||
// newenv的返回值为0, 实现子进程返回0值
|
||||
newenv->env_tf.tf_regs.reg_eax = 0;
|
||||
|
||||
// 返回值存放在eax中
|
||||
return newenv->env_id;
|
||||
|
||||
// panic("sys_exofork not implemented");
|
||||
}
|
||||
|
||||
// Set envid's env_status to status, which must be ENV_RUNNABLE
|
||||
// or ENV_NOT_RUNNABLE.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
// -E_INVAL if status is not a valid status for an environment.
|
||||
static int
|
||||
sys_env_set_status(envid_t envid, int status)
|
||||
{
|
||||
// Hint: Use the 'envid2env' function from kern/env.c to translate an
|
||||
// envid to a struct Env.
|
||||
// You should set envid2env's third argument to 1, which will
|
||||
// check whether the current environment has permission to set
|
||||
// envid's status.
|
||||
|
||||
// LAB 4: Your code here.
|
||||
struct Env *e;
|
||||
if (envid2env(envid, &e, 1)) return -E_BAD_ENV;
|
||||
|
||||
if (status != ENV_NOT_RUNNABLE && status != ENV_RUNNABLE)
|
||||
return -E_INVAL;
|
||||
|
||||
e->env_status = status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set envid's trap frame to 'tf'.
|
||||
// tf is modified to make sure that user environments always run at code
|
||||
// protection level 3 (CPL 3), interrupts enabled, and IOPL of 0.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
static int
|
||||
sys_env_set_trapframe(envid_t envid, struct Trapframe *tf)
|
||||
{
|
||||
// LAB 5: Your code here.
|
||||
// Remember to check whether the user has supplied us with a good
|
||||
// address!
|
||||
struct Env *env;
|
||||
int r;
|
||||
if ( (r = envid2env(envid, &env, 1)) < 0)
|
||||
return r;
|
||||
|
||||
// 什么时候会出现没有权限访问的问题?
|
||||
user_mem_assert(env, tf, sizeof(struct Trapframe), PTE_U);
|
||||
// 直接整个结构体也是可以赋值的
|
||||
|
||||
// tf->tf_cs |= (GD_UT | 0x3);
|
||||
tf->tf_eflags |= FL_IF;
|
||||
// 普通进程无I/O权限
|
||||
tf->tf_eflags &= ~FL_IOPL_MASK;
|
||||
|
||||
env->env_tf = *tf;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// Set the page fault upcall for 'envid' by modifying the corresponding struct
|
||||
// Env's 'env_pgfault_upcall' field. When 'envid' causes a page fault, the
|
||||
// kernel will push a fault record onto the exception stack, then branch to
|
||||
// 'func'.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
static int
|
||||
sys_env_set_pgfault_upcall(envid_t envid, void *func)
|
||||
{
|
||||
// LAB 4: Your code here.
|
||||
struct Env *e;
|
||||
if (envid2env(envid, &e, 1))
|
||||
return -E_BAD_ENV;
|
||||
// cprintf("set pgfault upcall\n");
|
||||
e->env_pgfault_upcall = func;
|
||||
return 0;
|
||||
// panic("sys_env_set_pgfault_upcall not implemented");
|
||||
}
|
||||
|
||||
// Allocate a page of memory and map it at 'va' with permission
|
||||
// 'perm' in the address space of 'envid'.
|
||||
// The page's contents are set to 0.
|
||||
// If a page is already mapped at 'va', that page is unmapped as a
|
||||
// side effect.
|
||||
//
|
||||
// perm -- PTE_U | PTE_P must be set, PTE_AVAIL | PTE_W may or may not be set,
|
||||
// but no other bits may be set. See PTE_SYSCALL in inc/mmu.h.
|
||||
//
|
||||
// Return 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
// -E_INVAL if va >= UTOP, or va is not page-aligned.
|
||||
// -E_INVAL if perm is inappropriate (see above).
|
||||
// -E_NO_MEM if there's no memory to allocate the new page,
|
||||
// or to allocate any necessary page tables.
|
||||
static int
|
||||
sys_page_alloc(envid_t envid, void *va, int perm)
|
||||
{
|
||||
// Hint: This function is a wrapper around page_alloc() and
|
||||
// page_insert() from kern/pmap.c.
|
||||
// Most of the new code you write should be to check the
|
||||
// parameters for correctness.
|
||||
// If page_insert() fails, remember to free the page you
|
||||
// allocated!
|
||||
|
||||
// LAB 4: Your code here.
|
||||
int ret = 0;
|
||||
struct Env *env;
|
||||
|
||||
if ((ret = envid2env(envid, &env, 1)) < 0)
|
||||
return -E_BAD_ENV;
|
||||
|
||||
if((uintptr_t)va >= UTOP || PGOFF(va))
|
||||
return -E_INVAL;
|
||||
if ((perm & PTE_U) == 0 || (perm & PTE_P) == 0)
|
||||
return -E_INVAL;
|
||||
if (perm & ~PTE_SYSCALL)
|
||||
return -E_INVAL;
|
||||
|
||||
struct PageInfo *pp = page_alloc(ALLOC_ZERO);
|
||||
if(!pp)
|
||||
return -E_NO_MEM;
|
||||
|
||||
if (page_insert(env->env_pgdir, pp, va, perm) < 0)
|
||||
return -E_NO_MEM;
|
||||
|
||||
return 0;
|
||||
// panic("sys_page_alloc not implemented");
|
||||
}
|
||||
|
||||
// Map the page of memory at 'srcva' in srcenvid's address space
|
||||
// at 'dstva' in dstenvid's address space with permission 'perm'.
|
||||
// Perm has the same restrictions as in sys_page_alloc, except
|
||||
// that it also must not grant write access to a read-only
|
||||
// page.
|
||||
//
|
||||
// Return 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if srcenvid and/or dstenvid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change one of them.
|
||||
// -E_INVAL if srcva >= UTOP or srcva is not page-aligned,
|
||||
// or dstva >= UTOP or dstva is not page-aligned.
|
||||
// -E_INVAL is srcva is not mapped in srcenvid's address space.
|
||||
// -E_INVAL if perm is inappropriate (see sys_page_alloc).
|
||||
// -E_INVAL if (perm & PTE_W), but srcva is read-only in srcenvid's
|
||||
// address space.
|
||||
// -E_NO_MEM if there's no memory to allocate any necessary page tables.
|
||||
static int
|
||||
sys_page_map(envid_t srcenvid, void *srcva,
|
||||
envid_t dstenvid, void *dstva, int perm)
|
||||
{
|
||||
// Hint: This function is a wrapper around page_lookup() and
|
||||
// page_insert() from kern/pmap.c.
|
||||
// Again, most of the new code you write should be to check the
|
||||
// parameters for correctness.
|
||||
// Use the third argument to page_lookup() to
|
||||
// check the current permissions on the page.
|
||||
|
||||
// LAB 4: Your code here.
|
||||
int ret = 0;
|
||||
struct Env *srcenv, *dstenv;
|
||||
struct PageInfo *srcpp, *dstpp;
|
||||
pte_t *pte;
|
||||
if ((envid2env(srcenvid, &srcenv, 1) < 0 )|| ( envid2env(dstenvid, &dstenv, 1) < 0))
|
||||
return -E_BAD_ENV;
|
||||
if ((uintptr_t)srcva >= UTOP || PGOFF(srcva) || (uintptr_t)dstva >= UTOP || PGOFF(dstva))
|
||||
return -E_INVAL;
|
||||
if ( (perm & PTE_U) == 0 || (perm & PTE_P) == 0 || (perm & ~PTE_SYSCALL))
|
||||
return -E_INVAL;
|
||||
if (!(srcpp = page_lookup(srcenv->env_pgdir, srcva, &pte)))
|
||||
return -E_INVAL;
|
||||
if ((perm & PTE_W) && ((*pte & PTE_W) == 0))
|
||||
return -E_INVAL;
|
||||
if (page_insert(dstenv->env_pgdir, srcpp, dstva, perm) < 0)
|
||||
return -E_NO_MEM;
|
||||
|
||||
return 0;
|
||||
// panic("sys_page_map not implemented");
|
||||
}
|
||||
|
||||
// Unmap the page of memory at 'va' in the address space of 'envid'.
|
||||
// If no page is mapped, the function silently succeeds.
|
||||
//
|
||||
// Return 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
// -E_INVAL if va >= UTOP, or va is not page-aligned.
|
||||
static int
|
||||
sys_page_unmap(envid_t envid, void *va)
|
||||
{
|
||||
// Hint: This function is a wrapper around page_remove().
|
||||
|
||||
// LAB 4: Your code here.
|
||||
int ret = 0;
|
||||
struct Env *env;
|
||||
|
||||
if ((ret = envid2env(envid, &env, 1)) < 0)
|
||||
return -E_BAD_ENV;
|
||||
if ((uintptr_t)va >= UTOP || PGOFF(va))
|
||||
return -E_INVAL;
|
||||
page_remove(env->env_pgdir, va);
|
||||
return 0;
|
||||
// panic("sys_page_unmap not implemented");
|
||||
}
|
||||
|
||||
// Try to send 'value' to the target env 'envid'.
|
||||
// If srcva < UTOP, then also send page currently mapped at 'srcva',
|
||||
// so that receiver gets a duplicate mapping of the same page.
|
||||
//
|
||||
// The send fails with a return value of -E_IPC_NOT_RECV if the
|
||||
// target is not blocked, waiting for an IPC.
|
||||
//
|
||||
// The send also can fail for the other reasons listed below.
|
||||
//
|
||||
// Otherwise, the send succeeds, and the target's ipc fields are
|
||||
// updated as follows:
|
||||
// env_ipc_recving is set to 0 to block future sends;
|
||||
// env_ipc_from is set to the sending envid;
|
||||
// env_ipc_value is set to the 'value' parameter;
|
||||
// env_ipc_perm is set to 'perm' if a page was transferred, 0 otherwise.
|
||||
// The target environment is marked runnable again, returning 0
|
||||
// from the paused sys_ipc_recv system call. (Hint: does the
|
||||
// sys_ipc_recv function ever actually return?)
|
||||
//
|
||||
// If the sender wants to send a page but the receiver isn't asking for one,
|
||||
// then no page mapping is transferred, but no error occurs.
|
||||
// The ipc only happens when no errors occur.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error.
|
||||
// Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist.
|
||||
// (No need to check permissions.)
|
||||
// -E_IPC_NOT_RECV if envid is not currently blocked in sys_ipc_recv,
|
||||
// or another environment managed to send first.
|
||||
// -E_INVAL if srcva < UTOP but srcva is not page-aligned.
|
||||
// -E_INVAL if srcva < UTOP and perm is inappropriate
|
||||
// (see sys_page_alloc).
|
||||
// -E_INVAL if srcva < UTOP but srcva is not mapped in the caller's
|
||||
// address space.
|
||||
// -E_INVAL if (perm & PTE_W), but srcva is read-only in the
|
||||
// current environment's address space.
|
||||
// -E_NO_MEM if there's not enough memory to map srcva in envid's
|
||||
// address space.
|
||||
|
||||
static int
|
||||
sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, unsigned perm)
|
||||
{
|
||||
// LAB 4: Your code here.
|
||||
struct Env *dstenv;
|
||||
pte_t *pte;
|
||||
struct PageInfo *pp;
|
||||
int r;
|
||||
if ( (r = envid2env( envid, &dstenv, 0)) < 0)
|
||||
return r;
|
||||
|
||||
// 不处于等待接收状态, 或有进程已经请求发送数据
|
||||
if ( (dstenv->env_ipc_recving != true) || dstenv->env_ipc_from != 0)
|
||||
return -E_IPC_NOT_RECV;
|
||||
|
||||
if ((uint32_t)srcva < UTOP) {
|
||||
if ( PGOFF(srcva))
|
||||
return -E_INVAL;
|
||||
if ( !(perm & PTE_P ) || !(perm & PTE_U) )
|
||||
return -E_INVAL;
|
||||
if (perm & (~ PTE_SYSCALL))
|
||||
return -E_INVAL;
|
||||
|
||||
|
||||
if ((pp = page_lookup(curenv->env_pgdir, srcva, &pte)) == NULL )
|
||||
return -E_INVAL;
|
||||
|
||||
|
||||
if ((perm & PTE_W) && !(*pte & PTE_W) )
|
||||
return -E_INVAL;
|
||||
|
||||
// 接收进程愿意接收一个页
|
||||
if (dstenv->env_ipc_dstva) {
|
||||
// 开始映射
|
||||
if( (r = page_insert(dstenv->env_pgdir, pp, dstenv->env_ipc_dstva, perm)) < 0)
|
||||
return r;
|
||||
dstenv->env_ipc_perm = perm;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
dstenv->env_ipc_from = curenv->env_id;
|
||||
dstenv->env_ipc_recving = false;
|
||||
dstenv->env_ipc_value = value;
|
||||
dstenv->env_status = ENV_RUNNABLE;
|
||||
// 返回值
|
||||
dstenv->env_tf.tf_regs.reg_eax = 0;
|
||||
return 0;
|
||||
|
||||
//panic("sys_ipc_try_send not implemented");
|
||||
}
|
||||
|
||||
|
||||
// Block until a value is ready. Record that you want to receive
|
||||
// using the env_ipc_recving and env_ipc_dstva fields of struct Env,
|
||||
// mark yourself not runnable, and then give up the CPU.
|
||||
//
|
||||
// If 'dstva' is < UTOP, then you are willing to receive a page of data.
|
||||
// 'dstva' is the virtual address at which the sent page should be mapped.
|
||||
//
|
||||
// This function only returns on error, but the system call will eventually
|
||||
// return 0 on success.
|
||||
// Return < 0 on error. Errors are:
|
||||
// -E_INVAL if dstva < UTOP but dstva is not page-aligned.
|
||||
static int
|
||||
sys_ipc_recv(void *dstva)
|
||||
{
|
||||
// LAB 4: Your code here.
|
||||
if ((uint32_t) dstva < UTOP ) {
|
||||
if (PGOFF(dstva))
|
||||
return -E_INVAL;
|
||||
|
||||
}
|
||||
// 大于小于都可以赋值为desva。
|
||||
curenv->env_ipc_dstva = dstva;
|
||||
curenv->env_status = ENV_NOT_RUNNABLE;
|
||||
curenv->env_ipc_recving = true;
|
||||
curenv->env_ipc_from = 0;
|
||||
sched_yield();
|
||||
// panic("sys_ipc_recv not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the current time.
|
||||
static int
|
||||
sys_time_msec(void)
|
||||
{
|
||||
// LAB 6: Your code here.
|
||||
return time_msec();
|
||||
// panic("sys_time_msec not implemented");
|
||||
}
|
||||
|
||||
int
|
||||
sys_pkt_try_send(void * buf, size_t len)
|
||||
{
|
||||
user_mem_assert(curenv, buf, len, PTE_U);
|
||||
return e1000_transmit(buf, len);
|
||||
}
|
||||
|
||||
int
|
||||
sys_pkt_try_receive(void *rev_buf, size_t *len)
|
||||
{
|
||||
return e1000_receive(rev_buf, len);
|
||||
}
|
||||
|
||||
|
||||
// Dispatches to the correct kernel function, passing the arguments.
|
||||
int32_t
|
||||
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
|
||||
{
|
||||
// Call the function corresponding to the 'syscallno' parameter.
|
||||
// Return any appropriate return value.
|
||||
// LAB 3: Your code here.
|
||||
switch (syscallno) {
|
||||
case SYS_cputs:
|
||||
sys_cputs((const char*)a1, a2);
|
||||
break;
|
||||
case SYS_cgetc:
|
||||
return sys_cgetc();
|
||||
case SYS_getenvid:
|
||||
return sys_getenvid();
|
||||
case SYS_env_destroy:
|
||||
return sys_env_destroy(a1);
|
||||
case SYS_yield:
|
||||
sys_yield();
|
||||
break;
|
||||
case SYS_page_alloc:
|
||||
return sys_page_alloc((envid_t)a1, (void * )a2, (int )a3);
|
||||
case SYS_env_set_pgfault_upcall:
|
||||
return sys_env_set_pgfault_upcall((envid_t) a1, (void *) a2);
|
||||
case SYS_page_map:
|
||||
return sys_page_map((envid_t) a1, (void *) a2, (envid_t) a3, (void *) a4, (int) a5);
|
||||
|
||||
case SYS_page_unmap:
|
||||
return sys_page_unmap((envid_t) a1, (void *) a2);
|
||||
|
||||
case SYS_exofork:
|
||||
return sys_exofork();
|
||||
|
||||
case SYS_env_set_status:
|
||||
return sys_env_set_status((envid_t) a1, (int) a2);
|
||||
case SYS_ipc_recv:
|
||||
return sys_ipc_recv( (void *) a1);
|
||||
case SYS_ipc_try_send:
|
||||
return sys_ipc_try_send((envid_t) a1, (uint32_t) a2, (void *) a3, (int) a4);
|
||||
|
||||
case SYS_env_set_trapframe:
|
||||
return sys_env_set_trapframe((envid_t) a1, (struct Trapframe *) a2);
|
||||
case SYS_time_msec:
|
||||
return sys_time_msec();
|
||||
case SYS_pkt_try_send:
|
||||
return sys_pkt_try_send((void *) a1, (size_t) a2);
|
||||
case SYS_pkt_try_recv:
|
||||
return sys_pkt_try_receive((void *) a1, (size_t *) a2);
|
||||
|
||||
case NSYSCALLS:
|
||||
return -E_INVAL;
|
||||
|
||||
default:
|
||||
return -E_INVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
lab/lab6.si4project/cache/parse/boot_main.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/boot_main.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/fs_bc.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/fs_bc.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/fs_fs.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/fs_fs.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/fs_fs.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/fs_fs.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/fs_fsformat.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/fs_fsformat.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/fs_ide.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/fs_ide.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/fs_serv.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/fs_serv.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/fs_test.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/fs_test.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/gradelib.py.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/gradelib.py.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_args.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_args.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_assert.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_assert.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_elf.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_elf.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_env.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_env.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_error.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_error.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_fd.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_fd.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_fs.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_fs.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_kbdreg.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_kbdreg.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_lib.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_lib.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_malloc.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_malloc.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_memlayout.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_memlayout.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_mmu.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_mmu.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_ns.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_ns.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_partition.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_partition.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_stab.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_stab.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_stdarg.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_stdarg.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_stdio.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_stdio.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_string.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_string.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_syscall.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_syscall.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_trap.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_trap.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_types.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_types.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/inc_x86.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/inc_x86.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_console.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_console.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_console.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_console.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_cpu.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_cpu.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_e1000.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_e1000.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_e1000.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_e1000.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_entrypgdir.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_entrypgdir.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_env.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_env.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_env.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_env.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_init.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_init.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_kclock.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_kclock.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_kclock.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_kclock.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_kdebug.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_kdebug.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_kdebug.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_kdebug.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_lapic.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_lapic.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_monitor.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_monitor.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_monitor.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_monitor.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_mpconfig.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_mpconfig.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_pci.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_pci.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_pci.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_pci.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_pcireg.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_pcireg.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_picirq.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_picirq.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_picirq.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_picirq.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_pmap.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_pmap.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_pmap.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_pmap.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_printf.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_printf.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_sched.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_sched.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_sched.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_sched.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_spinlock.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_spinlock.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_spinlock.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_spinlock.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_syscall.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_syscall.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_syscall.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_syscall.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_time.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_time.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_time.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_time.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_trap.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_trap.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/kern_trap.h.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/kern_trap.h.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_args.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_args.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_console.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_console.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_exit.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_exit.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_fd.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_fd.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_file.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_file.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_fork.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_fork.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_fprintf.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_fprintf.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_ipc.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_ipc.c.sisc
vendored
Normal file
Binary file not shown.
BIN
lab/lab6.si4project/cache/parse/lib_libmain.c.sisc
vendored
Normal file
BIN
lab/lab6.si4project/cache/parse/lib_libmain.c.sisc
vendored
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user