feat: (twimap) provide an easy way for mapping kernel objects into filesystem
authorMinep <zelong56@gmail.com>
Fri, 26 Aug 2022 16:43:06 +0000 (17:43 +0100)
committerMinep <zelong56@gmail.com>
Fri, 26 Aug 2022 16:43:06 +0000 (17:43 +0100)
feat: map pci, clock, cake allocator and block devices into filesystem.
chore: fixes and clean up

15 files changed:
lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/pci.c
lunaix-os/includes/hal/pci.h
lunaix-os/includes/lunaix/block.h
lunaix-os/includes/lunaix/fs/twifs.h
lunaix-os/includes/lunaix/mm/cake.h
lunaix-os/kernel/block/blk_mapping.c [new file with mode: 0644]
lunaix-os/kernel/block/block.c [moved from lunaix-os/kernel/block.c with 96% similarity]
lunaix-os/kernel/demos/simple_sh.c
lunaix-os/kernel/fs/twifs/twifs.c
lunaix-os/kernel/fs/twifs/twimap.c [new file with mode: 0644]
lunaix-os/kernel/mm/cake.c
lunaix-os/kernel/mm/cake_export.c [new file with mode: 0644]
lunaix-os/kernel/proc0.c
lunaix-os/kernel/time/clock.c

index 206112e1d79d0e99c85ab8bc0144c4422f99c4db..43b8f1ea6e1f0978b3429b7cfb2ccac643574c92 100644 (file)
@@ -78,9 +78,8 @@ ahci_init()
     struct pci_device* ahci_dev = pci_get_device_by_class(AHCI_HBA_CLASS);
     assert_msg(ahci_dev, "AHCI: Not found.");
 
-    uintptr_t bar6, size;
-    size = pci_bar_sizing(ahci_dev, &bar6, 6);
-    assert_msg(bar6 && PCI_BAR_MMIO(bar6), "AHCI: BAR#6 is not MMIO.");
+    struct pci_base_addr* bar6 = &ahci_dev->bar[5];
+    assert_msg(bar6->type & BAR_TYPE_MMIO, "AHCI: BAR#6 is not MMIO.");
 
     pci_reg_t cmd = pci_read_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD);
 
@@ -94,7 +93,7 @@ ahci_init()
 
     memset(&hba, 0, sizeof(hba));
 
-    hba.base = (hba_reg_t*)ioremap(PCI_BAR_ADDR_MM(bar6), size);
+    hba.base = (hba_reg_t*)ioremap(bar6->start, bar6->size);
 
 #ifdef DO_HBA_FULL_RESET
     // 重置HBA
index ca31e21c7656d05eddd6a9931429a588c3fe0cb4..893a0bbd00920a833a997e74b319a752f19635f2 100644 (file)
@@ -56,13 +56,14 @@ pci_probe_device(int bus, int dev, int funct)
     pci_reg_t intr = pci_read_cspace(base, 0x3c);
     pci_reg_t class = pci_read_cspace(base, 0x8);
 
-    struct pci_device* device = valloc(sizeof(struct pci_device));
+    struct pci_device* device = vzalloc(sizeof(struct pci_device));
     *device = (struct pci_device){ .cspace_base = base,
                                    .class_info = class,
                                    .device_info = reg1,
                                    .intr_info = intr };
 
     pci_probe_msi_info(device);
+    pci_probe_bar_info(device);
 
     llist_append(&pci_devices, &device->dev_chain);
 }
@@ -79,6 +80,24 @@ pci_probe()
     }
 }
 
+void
+pci_probe_bar_info(struct pci_device* device)
+{
+    uint32_t bar;
+    struct pci_base_addr* ba;
+    for (size_t i = 0; i < 6; i++) {
+        ba = &device->bar[i];
+        ba->size = pci_bar_sizing(device, &bar, i + 1);
+        if (PCI_BAR_MMIO(bar)) {
+            ba->start = PCI_BAR_ADDR_MM(bar);
+            ba->type |= PCI_BAR_CACHEABLE(bar) ? BAR_TYPE_CACHABLE : 0;
+            ba->type |= BAR_TYPE_MMIO;
+        } else {
+            ba->start = PCI_BAR_ADDR_IO(bar);
+        }
+    }
+}
+
 void
 pci_probe_msi_info(struct pci_device* device)
 {
@@ -107,23 +126,69 @@ pci_probe_msi_info(struct pci_device* device)
     }
 }
 
-#define PCI_PRINT_BAR_LISTING
+void
+__pci_read_cspace(struct twimap* map)
+{
+    struct pci_device* pcidev = (struct pci_device*)(map->data);
 
-int
-__pci_read_cspace(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
+    for (size_t i = 0; i < 256; i += sizeof(pci_reg_t)) {
+        *(pci_reg_t*)(map->buffer + i) =
+          pci_read_cspace(pcidev->cspace_base, i);
+    }
+
+    map->size_acc = 256;
+}
+
+void
+__pci_read_revid(struct twimap* map)
+{
+    int class = twimap_data(map, struct pci_device*)->class_info;
+    twimap_printf(map, "0x%x", PCI_DEV_REV(class));
+}
+
+void
+__pci_read_class(struct twimap* map)
 {
-    if (len < 256) {
-        return ERANGE;
+    int class = twimap_data(map, struct pci_device*)->class_info;
+    twimap_printf(map, "0x%x", PCI_DEV_CLASS(class));
+}
+
+void
+__pci_bar_read(struct twimap* map)
+{
+    struct pci_device* pcidev = twimap_data(map, struct pci_device*);
+    int bar_index = twimap_index(map, int);
+
+    struct pci_base_addr* bar = &pcidev->bar[bar_index];
+
+    if (!bar->start && !bar->size) {
+        twimap_printf(map, "[%d] not present \n", bar_index);
+        return;
     }
 
-    struct twifs_node* node = (struct twifs_node*)(inode->data);
-    struct pci_device* pcidev = (struct pci_device*)(node->data);
+    twimap_printf(
+      map, "[%d] base=%p, size=%p, ", bar_index, bar->start, bar->size);
 
-    for (size_t i = 0; i < 256; i += sizeof(pci_reg_t)) {
-        *(pci_reg_t*)(buffer + i) = pci_read_cspace(pcidev->cspace_base, i);
+    if ((bar->type & BAR_TYPE_MMIO)) {
+        twimap_printf(map, "mmio");
+        if ((bar->type & BAR_TYPE_CACHABLE)) {
+            twimap_printf(map, ", cachable");
+        }
+    } else {
+        twimap_printf(map, "io");
     }
 
-    return 256;
+    twimap_printf(map, "\n");
+}
+
+int
+__pci_bar_gonext(struct twimap* map)
+{
+    if (twimap_index(map, int) >= 5) {
+        return 0;
+    }
+    map->index += 1;
+    return 1;
 }
 
 void
@@ -131,18 +196,29 @@ pci_build_fsmapping()
 {
     struct twifs_node *pci_class = twifs_dir_node(NULL, "pci"), *pci_dev;
     struct pci_device *pos, *n;
+    struct twimap* map;
     llist_for_each(pos, n, &pci_devices, dev_chain)
     {
         pci_dev = twifs_dir_node(pci_class,
-                                 "B%d:D%d:F%d.%x:%x",
+                                 "%.2d:%.2d:%.2d.%.4x:%.4x",
                                  PCI_BUS_NUM(pos->cspace_base),
                                  PCI_SLOT_NUM(pos->cspace_base),
                                  PCI_FUNCT_NUM(pos->cspace_base),
                                  PCI_DEV_VENDOR(pos->device_info),
                                  PCI_DEV_DEVID(pos->device_info));
-        struct twifs_node* fnode = twifs_file_node(pci_dev, "cspace");
-        fnode->data = pos;
-        fnode->ops.read = __pci_read_cspace;
+
+        map = twifs_mapping(pci_dev, pos, "config");
+        map->read = __pci_read_cspace;
+
+        map = twifs_mapping(pci_dev, pos, "revision");
+        map->read = __pci_read_revid;
+
+        map = twifs_mapping(pci_dev, pos, "class");
+        map->read = __pci_read_class;
+
+        map = twifs_mapping(pci_dev, pos, "io_bases");
+        map->read = __pci_bar_read;
+        map->go_next = __pci_bar_gonext;
     }
 }
 
index 24c4e2963b804ab0497ca0a0f95f6498a3ad96fd..95d5fb80f0c17d12b1c1028c1977d1a0dbdd4480 100644 (file)
@@ -56,6 +56,16 @@ typedef unsigned int pci_reg_t;
 // PCI device header format
 // Ref: "PCI Local Bus Specification, Rev.3, Section 6.1"
 
+#define BAR_TYPE_MMIO 0x1
+#define BAR_TYPE_CACHABLE 0x2
+
+struct pci_base_addr
+{
+    uint32_t start;
+    uint32_t size;
+    uint32_t type;
+};
+
 struct pci_device
 {
     struct llist_header dev_chain;
@@ -64,6 +74,7 @@ struct pci_device
     uint32_t cspace_base;
     uint32_t msi_loc;
     uint16_t intr_info;
+    struct pci_base_addr bar[6];
 };
 
 // PCI Configuration Space (C-Space) r/w:
index 40935f9f630bb79da872ea7874606e743630647c..df481d82c32bb245986ee80bba0fe4081b8c5c99 100644 (file)
@@ -44,4 +44,10 @@ block_init();
 int
 block_mount_disk(struct hba_device* hd_dev);
 
+void
+blk_mapping_init();
+
+void
+blk_set_blkmapping(struct block_dev* bdev);
+
 #endif /* __LUNAIX_BLOCK_H */
index 563411223d8d5d258110e73b26e7d70024888500..b194066afe07c791902f1e71e8365376737ad761 100644 (file)
@@ -2,6 +2,7 @@
 #define __LUNAIX_TWIFS_H
 
 #include <lunaix/fs.h>
+#include <lunaix/spike.h>
 
 struct twifs_node
 {
@@ -25,9 +26,30 @@ struct twifs_node
     } ops;
 };
 
+struct twimap
+{
+    void* index;
+    void* buffer;
+    void* data;
+    size_t size_acc;
+    void (*read)(struct twimap* mapping);
+    int (*go_next)(struct twimap* mapping);
+    void (*reset)(struct twimap* mapping);
+};
+
+#define twinode_getdata(inode, type)                                           \
+    ({                                                                         \
+        struct twifs_node* twinode = (struct twifs_node*)(inode)->data;        \
+        assert(twinode);                                                       \
+        (type) twinode->data;                                                  \
+    })
+
 void
 twifs_init();
 
+struct twifs_node*
+twifs_file_node_vargs(struct twifs_node* parent, const char* fmt, va_list args);
+
 struct twifs_node*
 twifs_file_node(struct twifs_node* parent, const char* fmt, ...);
 
@@ -37,4 +59,19 @@ twifs_dir_node(struct twifs_node* parent, const char* fmt, ...);
 int
 twifs_rm_node(struct twifs_node* node);
 
+#define twimap_index(twimap, type) ((type)((twimap)->index))
+#define twimap_data(twimap, type) ((type)((twimap)->data))
+
+struct twimap*
+twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...);
+
+void
+twimap_printf(struct twimap* mapping, const char* fmt, ...);
+
+int
+twimap_memcpy(struct twimap* mapping, const void* src, const size_t len);
+
+int
+twimap_memappend(struct twimap* mapping, const void* src, const size_t len);
+
 #endif /* __LUNAIX_TWIFS_H */
index 0312c45d381ac7854a802cb248eb792ac496cbf6..6a3aa392238e38cfb358f59849dd4adc007161f6 100644 (file)
@@ -70,11 +70,7 @@ cake_release(struct cake_pile* pile, void* area);
 void
 cake_init();
 
-/**
- * @brief 统计蛋糕数量 - 问问Pinkie :D
- *
- */
 void
-cake_stats();
+cake_export();
 
 #endif /* __LUNAIX_VALLOC_H */
diff --git a/lunaix-os/kernel/block/blk_mapping.c b/lunaix-os/kernel/block/blk_mapping.c
new file mode 100644 (file)
index 0000000..f6d1346
--- /dev/null
@@ -0,0 +1,111 @@
+#include <lunaix/block.h>
+#include <lunaix/fs/twifs.h>
+
+static struct twifs_node* blk_root;
+
+void
+blk_mapping_init()
+{
+    blk_root = twifs_dir_node(NULL, "block");
+}
+
+void
+__blk_rd_size(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    size_t secsize = bdev->hd_dev->block_size;
+    twimap_printf(map, "%u", (bdev->end_lba - bdev->base_lba) * secsize);
+}
+
+void
+__blk_rd_secsize(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    size_t secsize = bdev->hd_dev->block_size;
+    twimap_printf(map, "%u", secsize);
+}
+
+void
+__blk_rd_range(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    twimap_printf(
+      map, "%u,%u", (uint32_t)bdev->base_lba, (uint32_t)bdev->end_lba);
+}
+
+void
+__blk_rd_model(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    twimap_printf(map, "%s", bdev->hd_dev->model);
+}
+
+void
+__blk_rd_serial(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    twimap_printf(map, "%s", bdev->hd_dev->serial_num);
+}
+
+void
+__blk_rd_status(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    twimap_printf(map, "%p", bdev->hd_dev->last_result.status);
+}
+
+void
+__blk_rd_error(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    twimap_printf(map, "%p", bdev->hd_dev->last_result.error);
+}
+
+void
+__blk_rd_sense_key(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    twimap_printf(map, "%p", bdev->hd_dev->last_result.sense_key);
+}
+
+void
+__blk_rd_wwid(struct twimap* map)
+{
+    struct block_dev* bdev = twimap_data(map, struct block_dev*);
+    uint32_t h = bdev->hd_dev->wwn >> 32;
+    uint32_t l = (uint32_t)bdev->hd_dev->wwn;
+    twimap_printf(map, "%x%x", h, l);
+}
+
+void
+blk_set_blkmapping(struct block_dev* bdev)
+{
+    struct twifs_node* dev_root = twifs_dir_node(blk_root, bdev->bdev_id);
+
+    struct twimap* map = twifs_mapping(dev_root, bdev, "size");
+    map->read = __blk_rd_size;
+
+    map = twifs_mapping(dev_root, bdev, "secsize");
+    map->read = __blk_rd_secsize;
+
+    map = twifs_mapping(dev_root, bdev, "range");
+    map->read = __blk_rd_range;
+
+    map = twifs_mapping(dev_root, bdev, "model");
+    map->read = __blk_rd_model;
+
+    map = twifs_mapping(dev_root, bdev, "serial");
+    map->read = __blk_rd_serial;
+
+    map = twifs_mapping(dev_root, bdev, "status");
+    map->read = __blk_rd_status;
+
+    map = twifs_mapping(dev_root, bdev, "error");
+    map->read = __blk_rd_error;
+
+    map = twifs_mapping(dev_root, bdev, "sense-key");
+    map->read = __blk_rd_sense_key;
+
+    map = twifs_mapping(dev_root, bdev, "wwid");
+    map->read = __blk_rd_wwid;
+}
\ No newline at end of file
similarity index 96%
rename from lunaix-os/kernel/block.c
rename to lunaix-os/kernel/block/block.c
index 3d3f97c860c4adc90a34ac2efbec609d0bb2962b..936ce2a7644a67dd3ed666d066fd3d0907df390a 100644 (file)
@@ -36,6 +36,8 @@ block_init()
     lbd_pile = cake_new_pile("block_dev", sizeof(struct block_dev), 1, 0);
     dev_registry = vcalloc(sizeof(struct block_dev*), MAX_DEV);
     free_slot = 0;
+
+    blk_mapping_init();
 }
 
 int
@@ -113,6 +115,7 @@ block_mount_disk(struct hba_device* hd_dev)
         goto error;
     }
 
+    blk_set_blkmapping(bdev);
     return errno;
 
 error:
@@ -120,6 +123,7 @@ error:
             hd_dev->model,
             hd_dev->serial_num,
             -errno);
+    return errno;
 }
 
 int
@@ -134,6 +138,7 @@ __block_register(struct block_dev* bdev)
     dev->read = __block_read;
 
     bdev->dev = dev;
+    strcpy(bdev->bdev_id, dev->name_val);
     dev_registry[free_slot++] = bdev;
     return 1;
 }
\ No newline at end of file
index 4ea9711a925438232e4fbc14386f13ee3b6c6554..195117af3c211029439b2f6749858130edb5ca6e 100644 (file)
@@ -75,7 +75,7 @@ sh_main()
 
     while (1) {
         getcwd(pwd, 512);
-        printf("%s$ ", pwd);
+        printf("[\033[2m%s\033[39;49m]$ ", pwd);
         size_t sz = read(stdin, buf, 512);
         if (sz < 0) {
             printf("fail to read user input (%d)\n", geterrno());
@@ -121,6 +121,7 @@ sh_main()
                     write(stdout, cat_buf, sz);
                 }
                 close(fd);
+                printf("\n");
             }
         } else {
             printf("unknow command");
index 9a5dd8e9fd4f3370efed1a684b3153e1aa355ae6..4952e9df62516f447bae49721c4293f5805db4eb 100644 (file)
@@ -188,16 +188,22 @@ twifs_rm_node(struct twifs_node* node)
     return 0;
 }
 
+struct twifs_node*
+twifs_file_node_vargs(struct twifs_node* parent, const char* fmt, va_list args)
+{
+    char buf[VFS_NAME_MAXLEN];
+    size_t len = __ksprintf_internal(buf, fmt, VFS_NAME_MAXLEN, args);
+
+    return __twifs_new_node(parent ? parent : fs_root, buf, len, VFS_IFSEQDEV);
+}
+
 struct twifs_node*
 twifs_file_node(struct twifs_node* parent, const char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
 
-    char buf[VFS_NAME_MAXLEN];
-    size_t len = __ksprintf_internal(buf, fmt, VFS_NAME_MAXLEN, args);
-    struct twifs_node* twi_node =
-      __twifs_new_node(parent ? parent : fs_root, buf, len, VFS_IFSEQDEV);
+    struct twifs_node* twi_node = twifs_file_node_vargs(parent, fmt, args);
 
     va_end(args);
 
diff --git a/lunaix-os/kernel/fs/twifs/twimap.c b/lunaix-os/kernel/fs/twifs/twimap.c
new file mode 100644 (file)
index 0000000..2446014
--- /dev/null
@@ -0,0 +1,110 @@
+#include <lunaix/fs/twifs.h>
+#include <lunaix/mm/valloc.h>
+
+#include <klibc/stdio.h>
+#include <klibc/string.h>
+
+#define TWIMAP_BUFFER_SIZE 1024
+
+void
+__twimap_default_reset(struct twimap* map)
+{
+    map->index = NULL;
+}
+
+int
+__twimap_default_gonext(struct twimap* map)
+{
+    return 0;
+}
+
+int
+__twimap_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
+{
+    struct twimap* map = twinode_getdata(inode, struct twimap*);
+    map->buffer = valloc(TWIMAP_BUFFER_SIZE);
+    map->reset(map);
+
+    // FIXME what if TWIMAP_BUFFER_SIZE is not big enough?
+
+    size_t pos = 0;
+    do {
+        map->size_acc = 0;
+        map->read(map);
+        pos += map->size_acc;
+    } while (pos < fpos && map->go_next(map));
+
+    if (pos < fpos) {
+        vfree(map->buffer);
+        return 0;
+    }
+
+    if (!fpos) {
+        pos = 0;
+    }
+
+    size_t acc_size = MIN(len, map->size_acc - (pos - fpos)), rdlen = acc_size;
+    memcpy(buffer, map->buffer + (pos - fpos), acc_size);
+
+    while (acc_size < len && map->go_next(map)) {
+        map->size_acc = 0;
+        map->read(map);
+        rdlen = MIN(len - acc_size, map->size_acc);
+        memcpy(buffer + acc_size, map->buffer, rdlen);
+        acc_size += rdlen;
+    }
+
+    vfree(map->buffer);
+    return acc_size;
+}
+
+struct twimap*
+twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+
+    struct twimap* map = vzalloc(sizeof(struct twimap));
+    struct twifs_node* node = twifs_file_node_vargs(parent, fmt, args);
+    node->ops.read = __twimap_read;
+    node->data = map;
+
+    map->reset = __twimap_default_reset;
+    map->go_next = __twimap_default_gonext;
+    map->data = data;
+
+    return map;
+}
+
+void
+twimap_printf(struct twimap* mapping, const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+
+    char* buf = mapping->buffer + mapping->size_acc;
+
+    mapping->size_acc +=
+      __ksprintf_internal(buf, fmt, TWIMAP_BUFFER_SIZE, args);
+
+    va_end(args);
+}
+
+int
+twimap_memcpy(struct twimap* mapping, const void* src, const size_t len)
+{
+    mapping->size_acc = MIN(TWIMAP_BUFFER_SIZE, len);
+    memcpy(mapping->buffer, src, mapping->size_acc);
+
+    return mapping->size_acc;
+}
+
+int
+twimap_memappend(struct twimap* mapping, const void* src, const size_t len)
+{
+    size_t cpy_len = MIN(TWIMAP_BUFFER_SIZE - mapping->size_acc, len);
+    memcpy(mapping->buffer + mapping->size_acc, src, cpy_len);
+    mapping->size_acc += cpy_len;
+
+    return cpy_len;
+}
\ No newline at end of file
index c3cee83d7153b23a7df3f96ff9ce213ce489f126..5aa9bef0d97a4e259c9f666431fa71c12a5065fb 100644 (file)
@@ -48,6 +48,7 @@ __new_cake(struct cake_pile* pile)
 
     cake->first_piece = (void*)((uintptr_t)cake + pile->offset);
     cake->next_free = 0;
+    pile->cakes_count++;
 
     piece_index_t* free_list = cake->free_list;
     for (size_t i = 0; i < max_piece - 1; i++) {
@@ -187,21 +188,4 @@ found:
     }
 
     return 1;
-}
-
-void
-cake_stats()
-{
-    kprintf(KDEBUG "<name> <cake> <pg/c> <p/c> <alloced>\n");
-
-    struct cake_pile *pos, *n;
-    llist_for_each(pos, n, &piles, piles)
-    {
-        kprintf("%s %d %d %d %d\n",
-                pos->pile_name,
-                pos->cakes_count,
-                pos->pg_per_cake,
-                pos->pieces_per_cake,
-                pos->alloced_pieces);
-    }
 }
\ No newline at end of file
diff --git a/lunaix-os/kernel/mm/cake_export.c b/lunaix-os/kernel/mm/cake_export.c
new file mode 100644 (file)
index 0000000..276e823
--- /dev/null
@@ -0,0 +1,108 @@
+#include <lunaix/fs/twifs.h>
+#include <lunaix/mm/cake.h>
+
+extern struct llist_header piles;
+
+int
+__cake_stat_gonext(struct twimap* map)
+{
+    struct cake_pile* pile = twimap_index(map, struct cake_pile*);
+    if (pile->piles.next == &piles) {
+        return 0;
+    }
+    map->index = list_entry(pile->piles.next, struct cake_pile, piles);
+    return 1;
+}
+
+void
+__cake_stat_reset(struct twimap* map)
+{
+    map->index = container_of(piles.next, struct cake_pile, piles);
+}
+
+void
+__cake_rd_stat(struct twimap* map)
+{
+    struct cake_pile* pos = twimap_index(map, struct cake_pile*);
+    twimap_printf(map,
+                  "%s %d %d %d %d\n",
+                  pos->pile_name,
+                  pos->cakes_count,
+                  pos->pg_per_cake,
+                  pos->pieces_per_cake,
+                  pos->alloced_pieces);
+}
+
+void
+__cake_rd_psize(struct twimap* map)
+{
+    struct cake_pile* pile = twimap_data(map, struct cake_pile*);
+    twimap_printf(map, "%u", pile->piece_size);
+}
+
+void
+__cake_rd_ccount(struct twimap* map)
+{
+    struct cake_pile* pile = twimap_data(map, struct cake_pile*);
+    twimap_printf(map, "%u", pile->cakes_count);
+}
+
+void
+__cake_rd_alloced(struct twimap* map)
+{
+    struct cake_pile* pile = twimap_data(map, struct cake_pile*);
+    twimap_printf(map, "%u", pile->alloced_pieces);
+}
+
+void
+__cake_rd_ppc(struct twimap* map)
+{
+    struct cake_pile* pile = twimap_data(map, struct cake_pile*);
+    twimap_printf(map, "%u", pile->pieces_per_cake);
+}
+
+void
+__cake_rd_ppg(struct twimap* map)
+{
+    struct cake_pile* pile = twimap_data(map, struct cake_pile*);
+    twimap_printf(map, "%u", pile->pg_per_cake);
+}
+
+void
+cake_export_pile(struct twifs_node* root, struct cake_pile* pile)
+{
+    struct twifs_node* pile_rt = twifs_dir_node(root, pile->pile_name);
+
+    struct twimap* map = twifs_mapping(pile_rt, pile, "piece_size");
+    map->read = __cake_rd_psize;
+
+    map = twifs_mapping(pile_rt, pile, "cake_count");
+    map->read = __cake_rd_ccount;
+
+    map = twifs_mapping(pile_rt, pile, "grabbed");
+    map->read = __cake_rd_alloced;
+
+    map = twifs_mapping(pile_rt, pile, "pieces_per_cake");
+    map->read = __cake_rd_ppc;
+
+    map = twifs_mapping(pile_rt, pile, "page_per_cake");
+    map->read = __cake_rd_ppg;
+}
+
+void
+cake_export()
+{
+    struct twifs_node* cake_root = twifs_dir_node(NULL, "cake");
+
+    struct twimap* map = twifs_mapping(cake_root, NULL, "pinkiepie");
+    map->reset = __cake_stat_reset;
+    map->go_next = __cake_stat_gonext;
+    map->read = __cake_rd_stat;
+    __cake_stat_reset(map);
+
+    struct cake_pile *pos, *n;
+    llist_for_each(pos, n, &piles, piles)
+    {
+        cake_export_pile(cake_root, pos);
+    }
+}
\ No newline at end of file
index bdc23ced68618e2d89f95096b81c9471f752ae84..e242196f0b969255bbf848b3b723baf2d3ceb599 100644 (file)
@@ -173,6 +173,7 @@ init_platform()
     console_start_flushing();
     console_flush();
 
+    cake_export();
     unlock_reserved_memory();
 
     for (size_t i = 0; i < (uintptr_t)(&__init_hhk_end); i += PG_SIZE) {
index 15a6a32aaf5fbf67527457578d30ebf52f46f18c..0f0457530df0f70240de7a6dae5caa8adec0ec5d 100644 (file)
@@ -1,5 +1,6 @@
 #include <hal/rtc.h>
 #include <lunaix/clock.h>
+#include <lunaix/fs/twifs.h>
 #include <lunaix/spike.h>
 #include <lunaix/timer.h>
 
@@ -8,6 +9,52 @@ static volatile time_t sys_time;
 void
 clock_systime_counter(void* arg);
 
+void
+__clock_read_systime(struct twimap* map)
+{
+    time_t save = sys_time;
+    twimap_printf(map, "%u", save);
+}
+
+void
+__clock_read_datetime(struct twimap* map)
+{
+    datetime_t dt;
+    clock_walltime(&dt);
+    twimap_printf(map,
+                  "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
+                  dt.year,
+                  dt.month,
+                  dt.day,
+                  dt.hour,
+                  dt.minute,
+                  dt.second);
+}
+
+void
+__clock_read_unix(struct twimap* map)
+{
+    datetime_t dt;
+    clock_walltime(&dt);
+    twimap_printf(map, "%u", clock_tounixtime(&dt));
+}
+
+void
+clock_build_mapping()
+{
+    struct twifs_node* root = twifs_dir_node(NULL, "clock");
+    struct twimap* map;
+
+    map = twifs_mapping(root, NULL, "systime");
+    map->read = __clock_read_systime;
+
+    map = twifs_mapping(root, NULL, "unix");
+    map->read = __clock_read_unix;
+
+    map = twifs_mapping(root, NULL, "datetime");
+    map->read = __clock_read_datetime;
+}
+
 void
 clock_init()
 {
@@ -17,6 +64,8 @@ clock_init()
 
     // 系统计时器每毫秒累加。
     timer_run_ms(1, clock_systime_counter, NULL, TIMER_MODE_PERIODIC);
+
+    clock_build_mapping();
 }
 
 void